Unisci testo in un documento

Questa guida spiega come utilizzare l'API Documenti Google per unire le informazioni di una o più origini dati esterne in un documento modello esistente.

Un modello è un tipo di documento che contiene testo fisso e segnaposto per contenuti dinamici. Ad esempio, un modello di contratto potrebbe contenere testo fisso con segnaposto per il nome e l'indirizzo del destinatario. L'app unisce quindi i dati specifici dell'utente nel modello per creare il documento finito.

Esistono diversi motivi per cui questo approccio è utile:

  • I progettisti possono perfezionare il design di un documento utilizzando Documenti Google. Questa operazione è più semplice rispetto alla regolazione dei parametri nell'app per impostare il layout di rendering.

  • La separazione dei contenuti dalla presentazione è un principio di progettazione ben noto con molti vantaggi.

Diagramma che mostra come i dati di un'origine vengono uniti in un modello per
creare un documento.
Figura 1. Unione dei dati in un modello per creare un documento.

Come funziona l'unione di documenti

Ecco un esempio di come puoi utilizzare l'API Documenti per unire i dati in un documento:

  1. Crea il documento utilizzando contenuti segnaposto per aiutarti con il design e il formato. La formattazione del testo che vuoi sostituire viene mantenuta.

  2. Per ogni elemento che inserirai, sostituisci il contenuto segnaposto con un tag. Assicurati di utilizzare stringhe che è improbabile che si verifichino normalmente. Ad esempio, {{account-holder-name}} potrebbe essere un buon tag.

  3. Nel codice, utilizza l'API Google Drive per creare una copia del documento.

  4. Nel codice, utilizza il metodo batchUpdate dell'API Documenti con il nome del documento e includi un ReplaceAllTextRequest.

Gli ID documento fanno riferimento a un documento e possono essere derivati dall'URL:

https://docs.google.com/document/d/DOCUMENT_ID/edit

Gestisci modelli

Per i documenti modello definiti e di proprietà dell'app, crea il modello utilizzando un account dedicato che rappresenta l'app. Gli account di servizio sono una buona scelta ed evitano complicazioni con le norme di Google Workspace che limitano la condivisione.

Quando crei istanze di documenti da modelli, utilizza sempre le credenziali dell'utente finale. In questo modo gli utenti hanno il pieno controllo sul documento risultante e si evitano problemi di scalabilità correlati ai limiti per utente in Google Drive.

Per creare un modello utilizzando un account di servizio, segui questi passaggi con le credenziali dell'app:

  1. Crea un documento utilizzando documents.create nell'API Documenti.
  2. Aggiorna le autorizzazioni per consentire ai destinatari del documento di leggerlo utilizzando permissions.create nell'API Drive.
  3. Aggiorna le autorizzazioni per consentire agli autori del modello di scriverlo utilizzando permissions.create nell'API Drive.
  4. Modifica il modello in base alle esigenze.

Per creare un'istanza del documento, segui questi passaggi con le credenziali dell'utente:

  1. Crea una copia del modello utilizzando files.copy nell' API Drive.
  2. Sostituisci i valori utilizzando documents.batchUpdate nell'API Documenti.

Esempio: unire i dati in un modello

Il seguente esempio di codice mostra come sostituire due campi in tutte le schede di un modello con valori reali per generare un documento finito:

Immagine che mostra un modello di documento con segnaposto tag e il documento unito risultante.
Figura 2. Sostituzione dei segnaposto dei tag con i valori.

Per eseguire questa unione, utilizza il seguente codice:

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();

List requests = 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()

Gestire elenchi e tabelle dinamici

Un'unione di documenti standard utilizza ReplaceAllTextRequest per sostituire i singoli segnaposto una tantum (come {{customer-name}} o {{date}}). Tuttavia, se i dati includono un elenco dinamico di elementi (ad esempio righe in una fattura, un elenco di prodotti ordinati o una tabella dinamica), non puoi utilizzare la sostituzione del testo standard perché il numero di elementi è sconosciuto durante la progettazione del modello.

Per gestire i contenuti degli elenchi dinamici, utilizza una delle seguenti strategie.

Opzione 1: aggiungere righe a una tabella modello

Se il documento modello contiene già una tabella formattata (ad esempio, con una riga di intestazione e una singola riga segnaposto), puoi clonare e compilare dinamicamente le righe per ogni elemento dell'elenco:

  1. Leggi la struttura del modello: utilizza il metodo documents.get per individuare la tabella e identificare l' indice della riga del modello.
  2. Inserisci nuove righe: per ogni elemento nell'elenco dei dati (escluso il primo elemento, che può riutilizzare la riga del modello esistente), chiama InsertTableRowRequest per inserire una nuova riga sotto la riga del modello.
  3. Compila i dati delle celle: compila le celle nella riga del modello sostituendo i segnaposto. Per le righe appena create, utilizza InsertTextRequest per inserire il testo corrispondente nella posizione delle coordinate di ogni cella.

Per esempi di come inserire righe di tabella, vedi Utilizzare le tabelle.

Opzione 2: sostituire un tag con una tabella generata

Se vuoi creare la tabella da zero a livello programmatico:

  1. Inserisci un tag segnaposto: utilizza un singolo tag (ad esempio {{invoice-table}}) nel documento modello per contrassegnare la posizione in cui deve essere inserito l'elenco.
  2. Individua il segnaposto: utilizza un'operazione di ricerca per trovare l'indice iniziale del tag.
  3. Elimina il segnaposto: utilizza DeleteContentRangeRequest per rimuovere il testo {{invoice-table}}.
  4. Inserisci la tabella: invia un InsertTableRequest all'indice iniziale, specificando il numero di righe e colonne in base all' origine dati.
  5. Scrivi i valori: compila ogni cella della tabella in sequenza.

Per esempi di inserimento di tabelle a livello programmatico, vedi Utilizzare le tabelle.