web-dev-qa-db-fra.com

Comment puis-je fusionner des publipostages de Google Spreadsheet vers un document Google?

Avec Microsoft Excel et Microsoft Word, il est facile de fusionner des lignes d’une feuille de calcul en pages d’un fichier Word. Ceci était traditionnellement utilisé pour faire des mailings en papier. Comment puis-je faire de même avec Google Drive/Google Docs?

Il existe de nombreux modèles proposant le publipostage feuille à feuille: Comment puis-je fusionner avec Gmail? mais ce n’est pas ce que je recherche.

19
Bryce

Vous devrez écrire un script Google Apps pour cela. Vous pouvez laisser la première ligne de la feuille de calcul être le nom des champs et créer un modèle de document dans lequel les champs sont référencés comme [FIELD].

Donc, si votre feuille de calcul ressemble à:

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

... vous pourriez avoir un modèle de document comme

Cher [NOM], habitant à [RUE], [VILLE] [Zip] ...

Votre script devra créer un nouveau document vide et, pour chaque ligne de votre feuille de calcul, ajouter une nouvelle page et rechercher/remplacer les espaces réservés aux champs par des valeurs de ligne.

J'ai une version quelque peu fonctionnelle, qui pourrait nécessiter un peu de polissage. Il peut être invoqué ici . Il créera un nouveau document nommé Résultat du publipostage .

Vous pouvez l'utiliser comme point de départ pour votre propre script. Faites-moi savoir si cela vous intéresse ou je peux passer un peu plus de temps à finir le script.

Contenu du script:

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();
}
7
Vidar S. Ramdal

Grâce au nouveau Google Drive Add-ons , il existe plusieurs possibilités de fusion et publipostage, telles que "Encore un publipostage".

Pour l'utiliser, vous devez disposer d'un "nouveau" tableur Google et installer le module complémentaire via le menu Compléments:

Screenshot from Google Spreadsheets

Recherchez Mail merge et vous trouverez plusieurs options.

6
Vidar S. Ramdal

Un article de Google explique comment configurer les données de fil dans une feuille et le modèle dans une autre, plutôt que dans une feuille de calcul Google + Google Doc: https://developers.google.com/apps-script/articles/mail_merge

Cependant, le résultat final est que la MailApp envoie un courrier électronique, plutôt que le document "cloné" souhaité. Je suggérerais de combiner le tutoriel et la réponse de @ Vidar pour remplacer:

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

avec

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?

Références aléatoires AppScripts:

5
drzaus

Je recommande autoCrat . Il s'agit d'un module complémentaire de Google doté d'une excellente interface, similaire à un assistant, pour vous aider à configurer la fusion.

3
morphatic