Z tego przewodnika dowiesz się, jak używać interfejsu Google Docs API do scalania informacji z co najmniej 1 zewnętrznego źródła danych z istniejącym dokumentem szablonu.
Szablon to typ dokumentu zawierający stały tekst i symbole zastępcze treści dynamicznej. Na przykład szablon umowy może zawierać stały tekst z symbolami zastępczymi imienia i nazwiska oraz adresu odbiorcy. Aplikacja scala następnie dane konkretnego użytkownika z szablonem, aby utworzyć gotowy dokument.
Istnieje kilka powodów, dla których to podejście jest przydatne:
Projektanci mogą dostosować wygląd dokumentu za pomocą Dokumentów Google. Jest to prostsze niż dostrajanie parametrów w aplikacji w celu ustawienia renderowanego układu.
Oddzielenie treści od prezentacji to znana zasada projektowania, która ma wiele zalet.
Jak działa scalanie dokumentów
Oto przykład, jak możesz użyć interfejsu Docs API do scalania danych z dokumentem:
Utwórz dokument, używając treści zastępczej, która pomoże Ci w projektowaniu i formatowaniu. Zachowane zostanie dowolne formatowanie tekstu, które chcesz zastąpić.
W przypadku każdego elementu, który będziesz wstawiać, zastąp treść zastępczą tagiem. Używaj ciągów znaków, które raczej nie występują normalnie. Dobrym tagiem może być na przykład
{{account-holder-name}}.W kodzie użyj interfejsu Google Drive API, aby utworzyć kopię dokumentu.
W kodzie użyj metody interfejsu Docs API
batchUpdatez nazwą dokumentu i dodajReplaceAllTextRequest.
Identyfikatory dokumentów odwołują się do dokumentu i można je uzyskać z adresu URL:
https://docs.google.com/document/d/DOCUMENT_ID/edit
Zarządzanie szablonami
W przypadku dokumentów szablonów, które są definiowane i należą do aplikacji, utwórz szablon za pomocą konta dedykowanego reprezentującego aplikację. Dobrym rozwiązaniem są konta usługi, które pozwalają uniknąć komplikacji związanych z zasadami Google Workspace ograniczającymi udostępnianie.
Gdy tworzysz instancje dokumentów na podstawie szablonów, zawsze używaj danych logowania użytkownika. Dzięki temu użytkownicy mają pełną kontrolę nad utworzonym dokumentem i unikają problemów ze skalowaniem związanych z limitami na użytkownika na Dysku Google.
Aby utworzyć szablon za pomocą konta usługi, wykonaj te czynności, używając danych logowania aplikacji:
- Utwórz dokument za pomocą
documents.createw interfejsie Docs API. - Zaktualizuj uprawnienia, aby umożliwić odbiorcom dokumentu jego odczytanie, za pomocą
permissions.createw interfejsie Drive API. - Zaktualizuj uprawnienia, aby umożliwić autorom szablonu zapisywanie w nim, za pomocą metody
permissions.createw interfejsie Drive API. - W razie potrzeby edytuj szablon.
Aby utworzyć instancję dokumentu, wykonaj te czynności, używając danych logowania użytkownika:
- Utwórz kopię szablonu za pomocą
files.copyw interfejsie Drive API. - Zastąp wartości za pomocą
documents.batchUpdatew interfejsie Docs API.
Przykład: scalanie danych z szablonem
Poniższy przykładowy kod pokazuje, jak zastąpić 2 pola we wszystkich kartach szablonu rzeczywistymi wartościami, aby wygenerować gotowy dokument:
Aby przeprowadzić to scalanie, użyj tego kodu:
Java
String customerName = "Alice"; DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd"); String date = formatter.format(LocalDate.now()); // Make a copy of the template document using the Drive API. String copyTitle = "Merged Document"; File copyMetadata = new File().setName(copyTitle); File documentCopyFile = driveService.files().copy(DOCUMENT_ID, copyMetadata).execute(); String documentCopyId = documentCopyFile.getId(); Listrequests = new ArrayList<>(); // One option for replacing all text is to specify all tab IDs. requests.add(new Request() .setReplaceAllText(new ReplaceAllTextRequest() .setContainsText(new SubstringMatchCriteria() .setText("{{customer-name}}") .setMatchCase(true)) .setReplaceText(customerName) .setTabsCriteria(new TabsCriteria() .addTabIds(TAB_ID_1) .addTabIds(TAB_ID_2) .addTabIds(TAB_ID_3)))); // Another option is to omit TabsCriteria if you are replacing across all tabs. requests.add(new Request() .setReplaceAllText(new ReplaceAllTextRequest() .setContainsText(new SubstringMatchCriteria() .setText("{{date}}") .setMatchCase(true)) .setReplaceText(date))); BatchUpdateDocumentRequest body = new BatchUpdateDocumentRequest(); service.documents().batchUpdate(documentCopyId, body.setRequests(requests)).execute();
Node.js
let customerName = 'Alice'; let date = yyyymmdd() let requests = [ // One option for replacing all text is to specify all tab IDs. { replaceAllText: { containsText: { text: '{{customer-name}}', matchCase: true, }, replaceText: customerName, tabsCriteria: { tabIds: [TAB_ID_1, TAB_ID_2, TAB_ID_3], }, }, }, // Another option is to omit TabsCriteria if you are replacing across all tabs. { replaceAllText: { containsText: { text: '{{date}}', matchCase: true, }, replaceText: date, }, }, ]; // Make a copy of the template document using the Drive API. let copyTitle = 'Merged Document'; driveService.files.copy({ fileId: '1yBx6HSnu_gbV2sk1nChJOFo_g3AizBhr-PpkyKAwcTg', resource: { name: copyTitle, }, }, (err, driveResponse) => { if (err) return console.log('The Drive API returned an error: ' + err); let documentCopyId = driveResponse.data.id; google.options({auth: auth}); google .discoverAPI( 'https://docs.googleapis.com/$discovery/rest?version=v1&key={YOUR_API_KEY}') .then(function(docs) { docs.documents.batchUpdate( { documentId: documentCopyId, resource: { requests, }, }, (err, {data}) => { if (err) return console.log('The API returned an error: ' + err); console.log(data); }); }); });
Python
customer_name = 'Alice' date = datetime.datetime.now().strftime("%y/%m/%d") # Make a copy of the template document using the Drive API. copy_title = 'Merged Document' body = { 'name': copy_title } drive_response = drive_service.files().copy( fileId=DOCUMENT_ID, body=body).execute() document_copy_id = drive_response.get('id') requests = [ # One option for replacing all text is to specify all tab IDs. { 'replaceAllText': { 'containsText': { 'text': '{{customer-name}}', 'matchCase': 'true' }, 'replaceText': customer_name, 'tabsCriteria': { 'tabIds': [TAB_ID_1, TAB_ID_2, TAB_ID_3], }, }}, # Another option is to omit TabsCriteria if you are replacing across all tabs. { 'replaceAllText': { 'containsText': { 'text': '{{date}}', 'matchCase': 'true' }, 'replaceText': str(date), } } ] result = service.documents().batchUpdate( documentId=document_copy_id, body={'requests': requests}).execute()
Obsługa list i tabel dynamicznych
Standardowe scalanie dokumentów używa ReplaceAllTextRequest do zastępowania pojedynczych
symboli zastępczych (np. {{customer-name}} lub
{{date}}). Jeśli jednak dane zawierają
dynamiczną listę elementów (np. wiersze na fakturze, listę zamówionych
produktów lub tabelę dynamiczną), nie możesz użyć standardowego zastępowania tekstu, ponieważ
liczba elementów jest nieznana podczas projektowania szablonu.
Aby obsługiwać dynamiczną listę treści, użyj jednej z tych strategii.
Opcja 1. Dołączanie wierszy do tabeli szablonu
Jeśli dokument szablonu zawiera już sformatowaną tabelę (np. z wierszem nagłówka i pojedynczym wierszem zastępczym), możesz dynamicznie klonować i wypełniać wiersze dla każdego elementu na liście:
- Odczytaj strukturę szablonu: użyj metody
documents.get, aby znaleźć tabelę i zidentyfikować indeks wiersza szablonu. - Wstaw nowe wiersze: w przypadku każdego elementu na Twojej liście danych (z wyjątkiem pierwszego
elementu, który może ponownie użyć istniejącego wiersza szablonu) wywołaj
InsertTableRowRequest, aby wstawić nowy wiersz poniżej wiersza szablonu. - Wypełnij dane komórek: wypełnij komórki w wierszu szablonu, zastępując jego symbole zastępcze. W przypadku nowo utworzonych wierszy użyj
InsertTextRequestaby wstawić odpowiedni tekst w lokalizacji współrzędnych każdej komórki.
Przykłady wstawiania wierszy tabeli znajdziesz w artykule Praca z tabelami.
Opcja 2. Zastępowanie tagu wygenerowaną tabelą
Jeśli chcesz programowo utworzyć tabelę od podstaw:
- Umieść tag zastępczy: użyj pojedynczego tagu (np.
{{invoice-table}}) w dokumencie szablonu, aby oznaczyć miejsce, w którym ma się znajdować lista. - Znajdź symbol zastępczy: użyj operacji wyszukiwania, aby znaleźć indeks początkowy tagu.
- Usuń symbol zastępczy: użyj
DeleteContentRangeRequestaby usunąć tekst{{invoice-table}}. - Wstaw tabelę: wyślij
InsertTableRequestna tym indeksie początkowym, określając liczbę wierszy i kolumn na podstawie źródła danych. - Zapisz wartości: wypełnij kolejno każdą komórkę tabeli.
Przykłady programowego wstawiania tabel znajdziesz w artykule Praca z tabelami.