Wie verschicke ich einen Seriendruck aus einer Google-Tabelle in ein Google-Dokument?


20

Mit Microsoft Excel und Microsoft Word ist es einfach, Zeilen aus einer Kalkulationstabelle in Seiten in einer Word-Datei zusammenzuführen. Dies wurde traditionell verwendet, um Papier-Mailings zu machen. Wie kann ich dasselbe mit Google Drive / Google Docs tun?

Es gibt viele Vorlagen, die das Zusammenführen von Tabellenkalkulationen und E-Mails ermöglichen: Wie führe ich einen Seriendruck mit Google Mail durch? aber danach bin ich nicht.


Haben Sie versucht, zu kopieren / einfügen?
Jacob Jan Tuinstra

4
Kopieren / Einfügen für 10.000 Zeilen? Nein Danke. Word / Excel reicht völlig aus.
Bryce

Antworten:


8

Dazu müssen Sie ein Google Apps-Skript schreiben . Sie können die erste Zeile des Arbeitsblatts als Feldnamen definieren und ein Vorlagendokument erstellen, in dem die Felder wie folgt referenziert werden [FIELD].

Also, wenn Ihre Tabelle so aussieht:

NAME  |  STREET             | ZIP    | TOWN
---------------------------------------------
Vidar | Karl Johans gate 15 | 0200   | Oslo
John  | 3021 Arlington Road | 123456 | Memphis, TN

... Sie könnten ein Vorlagendokument wie haben

Lieber [NAME], wohnhaft in [STREET], [TOWN] [ZIP] ...

Ihr Skript muss ein neues, leeres Dokument erstellen und für jede Zeile in Ihrer Tabelle eine neue Seite hinzufügen und die Feldplatzhalter durch Zeilenwerte suchen / ersetzen.

Ich habe eine etwas funktionierende Version, die möglicherweise etwas poliert werden muss. Es kann hier aufgerufen werden . Es wird ein neues Dokument mit dem Namen Ergebnis des Seriendrucks erstellt .

Sie können es als Ausgangspunkt für Ihr eigenes Skript verwenden. Lassen Sie mich wissen, ob Sie sich dafür interessieren, oder ich kann etwas mehr Zeit damit verbringen, das Drehbuch fertigzustellen.

Skriptinhalt:

var selectedTemplateId = null;
var selectedSpreadsheetId = null;
var spreadsheetDocPicker = null;
var templateDocPicker = null;

function mailMerge(app) {
  var app = UiApp.createApplication().setTitle("Mail Merge");
  templateDocPicker = createFilePicker(app, "Choose template", 
         UiApp.FileType.DOCUMENTS, "templateSelectionHandler"); 
  templateDocPicker.showDocsPicker();
  return app;
};

function createFilePicker(app, title, fileType, selectionHandlerName) {
  Logger.log("Creating file picker for " + fileType);
  var docPicker = app.createDocsListDialog();
  docPicker.setDialogTitle(title);
  docPicker.setInitialView(fileType);
  var selectionHandler = app.createServerHandler(selectionHandlerName);
  docPicker.addSelectionHandler(selectionHandler);
  return docPicker;
}

function templateSelectionHandler(e) {
  var app = UiApp.getActiveApplication();
  selectedTemplateId = e.parameter.items[0].id;
  UserProperties.setProperty("templateId", e.parameter.items[0].id);
  Logger.log("Selected template: " + selectedTemplateId);
  var spreadsheetDocPicker = createFilePicker(app, "Choose spreadsheet", 
        UiApp.FileType.SPREADSHEETS, "spreadsheetSelectionHandler");
  spreadsheetDocPicker.showDocsPicker();
  return app;
}

function spreadsheetSelectionHandler(e) {
  var app = UiApp.getActiveApplication();
  UserProperties.setProperty("spreadsheetId", e.parameter.items[0].id);
  selectedSpreadsheetId = e.parameter.items[0].id;
  Logger.log("Selected spreadsheet: " + selectedSpreadsheetId);
  doMerge();
  return app;
}

function doMerge() {
  var selectedSpreadsheetId = UserProperties.getProperty("spreadsheetId");
  var selectedTemplateId = UserProperties.getProperty("templateId");
  Logger.log("Selected spreadsheet: " + selectedSpreadsheetId);
  var sheet = SpreadsheetApp.openById(selectedSpreadsheetId);
  Logger.log("Spreadsheet opened");
  Logger.log("Opening template: " + selectedTemplateId);
  var template = DocumentApp.openById(selectedTemplateId);
  Logger.log("Template opened");
  var templateFile = DocsList.getFileById(selectedTemplateId);
  var templateDoc = DocumentApp.openById(templateFile.getId());
  //var mergedFile = templateFile.makeCopy();
  var mergedDoc = DocumentApp.create("Result of mail merge");
  var bodyCopy = templateDoc.getActiveSection().copy();
  Logger.log("Copy made");
  var rows = sheet.getDataRange();
  var numRows = rows.getNumRows();
  var values = rows.getValues();
  var fieldNames = values[0];

  for (var i = 1; i < numRows; i++) {
    var row = values[i];
    Logger.log("Processing row " + i + " " + row);
    var body = bodyCopy.copy();
    for (var f = 0; f < fieldNames.length; f++) {
      Logger.log("Processing field " + f + " " + fieldNames[f]);
      Logger.log("Replacing [" + fieldNames[f] + "] with " + row[f]);
      body.replaceText("\\[" + fieldNames[f] + "\\]", row[f]);
    }
    var numChildren = body.getNumChildren();
    for (var c = 0; c < numChildren; c++) {
      var child = body.getChild(c);
      child = child.copy();
      if (child.getType() == DocumentApp.ElementType.HORIZONTALRULE) {
        mergedDoc.appendHorizontalRule(child);
      } else if (child.getType() == DocumentApp.ElementType.INLINEIMAGE) {
        mergedDoc.appendImage(child);
      } else if (child.getType() == DocumentApp.ElementType.PARAGRAPH) {
        mergedDoc.appendParagraph(child);
      } else if (child.getType() == DocumentApp.ElementType.LISTITEM) {
        mergedDoc.appendListItem(child);
      } else if (child.getType() == DocumentApp.ElementType.TABLE) {
        mergedDoc.appendTable(child);
      } else {
        Logger.log("Unknown element type: " + child);
      }
   }
   Logger.log("Appending page break");
   mergedDoc.appendPageBreak();
   Logger.log("Result is now " + mergedDoc.getActiveSection().getText());
  }
}

function testMerge() {
  UserProperties.setProperty("templateId", 
    "1pAXWE0uklZ8z-O_Tejuv3pWSTiSv583ptUTGPt2Knm8");
  UserProperties.setProperty("spreadsheetId", 
    "0Avea1NXBTibYdFo5QkZzWWlMYUhkclNSaFpRWUZOTUE");
  doMerge();
}


function doGet() {
  return mailMerge();
}

1
Warum haben Sie sich für eine eigenständige App entschieden und nicht für einen Build aus der Tabelle heraus? Das wird es dem OP viel leichter machen. Zweitens, warum enthält das Skript so viele Logger-Aufrufe? Dadurch wird das Skript zu dicht.
Jacob Jan Tuinstra

Das Google-Skriptarchiv enthielt einige vorgefertigte Skripte. Gibt es einen bestimmten Grund, warum Ihre oder eine andere nicht hochgeladen werden würde?
Bryce

Ich habe Jacobs Kommentar bis jetzt nicht bemerkt und wie er sagt, sollte es wahrscheinlich ein Spreadsheet-Skript sein, anstatt ein eigenständiges. Ich werde sehen, ob ich Zeit finde, um daran zu arbeiten, und es an die Skriptgalerie weiterleiten.
Vidar S. Ramdal

5
Vidar Das ist eine großartige Antwort. Ich habe es aufgeräumt, einige der veralteten Methoden aktualisiert, unnötige Funktionen beseitigt und es so geändert, dass es in der Tabelle ausgeführt wird, wie von @JacobJanTuinstra vorgeschlagen. Dann wurde mir klar, dass es einen Fehler gibt, der Bilder zerstört , und ich habe auch eine Problemumgehung für den Fehler gemacht. Ich fühle, dass es jetzt schön genug ist, um auf Github gesetzt zu werden. Ich habe es dort gepostet und darin einen Link zu Ihrer Antwort als Startversion der Arbeit bereitgestellt.
Hadi

@hadi Gute Arbeit!
Vidar S. Ramdal

6

Über die neuen Google Drive-Add-Ons stehen verschiedene Möglichkeiten für den Seriendruck zur Verfügung, z. B. "Noch ein Seriendruck".

Um es zu verwenden, müssen Sie über eine "neue" Google-Tabelle verfügen und das Add-On über das Menü "Add-Ons" installieren:

Screenshot von Google Spreadsheets

Suchen Sie nach Mail merge, und Sie werden mehrere Optionen finden.


Beachten Sie, dass es auf 100 E-Mails pro Tag begrenzt ist (kostenlos).
Pixeline

5

In Googles eigenem Beitrag wird erklärt, wie Sie die Feed-Daten in einem Blatt und die Vorlage in einem anderen Blatt anstatt in einer Google-Tabelle und in Google Doc einrichten: https://developers.google.com/apps-script/articles/mail_merge

Das Endergebnis ist jedoch das MailAppSenden einer E-Mail anstelle des gewünschten "geklonten" Dokuments. Ich würde vorschlagen, das Tutorial mit der Antwort von @ Vidar zu kombinieren.

MailApp.sendEmail(rowData.emailAddress, emailSubject, emailText);

mit

var mergedDoc, bodyContent,
    // you'd have to make the DocumentTitle column for the following
    newTitle = rowData.DocumentTitle /* or set to a static title, etc */;

// make a copy of the template document -- see http://stackoverflow.com/a/13243070/1037948
// or start a new one if you aren't using the template, but rather text from a template field
if( usingTemplateFile ) {
    mergedDoc = templateDoc.makeCopy(newTitle)
    bodyContent = mergedDoc.getBody();
} else {
    mergedDoc = DocumentApp.create(newTitle);
    bodyContent = mergedDoc.getBody();
    bodyContent.setText(templateFieldContents);
}

// tweak the fillInTemplateFromObject to accept a document Body and use .replaceText() instead of .match as in mailmerge example
// .replaceText see https://developers.google.com/apps-script/reference/document/body#replaceText(String,String)
fillInTemplateFromObject(bodyContent, rowData);

// no append needed?

Zufällige AppScripts-Referenzen:



3
Die Frage schließt E-Mail-Seriendruck ausdrücklich aus.
Bryce

3

Ich empfehle autoCrat . Es handelt sich um ein Google Add-On mit einer hervorragenden, assistentenähnlichen Oberfläche, die Sie beim Einrichten der Zusammenführung unterstützt.


1

Ich hatte das gleiche Problem und versuchte es mit Vidars Antwort zu lösen, aber wegen der Verachtung funktionierte es nicht.

Die eigentliche Lösung ist der Link von @hadi im Kommentar zu Vidars Antwort.

Vidar :
Das ist eine großartige Antwort. Ich habe es aufgeräumt, einige der veralteten Methoden aktualisiert, überflüssige Funktionen entfernt und es so modifiziert, dass es in der Tabelle ausgeführt wird, wie von @ JacobJanTuinstra vorgeschlagen. Dann wurde mir klar, dass es einen Fehler gibt, der Bilder zerstört, und ich habe auch eine Problemumgehung für den Fehler gemacht. Ich fühle, dass es jetzt schön genug ist, um auf Github gesetzt zu werden. Ich habe es dort gepostet und darin einen Link zu Ihrer Antwort als Startversion der Arbeit bereitgestellt.
- Hadi 4. März 15 um 19:24 "

https://github.com/hadaf/SheetsToDocsMerge :

  A Google Apps Script that merges information from a Google Sheet into a 
  Template created by Google Docs. The result is a new Google Docs file 
  that is populated by the Sheet data.

Befolgen Sie einfach die Schritte auf Readmeund ich konnte ein zusammengeführtes Dokument aus einer Vorlage Google-Doc und einem Google-Sheet erstellen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.