Google E-Tablodan bir Google Dokümanına nasıl adres mektup birleştirme yapabilirim?


20

Microsoft Excel ve Microsoft Word ile, bir e-tablodaki satırları bir Word dosyasındaki sayfalara birleştirmek kolaydır. Bu geleneksel olarak kağıt postalar yapmak için kullanılıyordu. Aynı şeyi Google Drive / Google Dokümanlar ile nasıl yapabilirim?

E-tablodan e-postaya adres-mektup birleştirme sunan birçok şablon vardır: Gmail ile adres-mektup birleştirmeyi nasıl yaparım? ama peşinde olduğum şey bu değil.


Kopyalamaya / yapıştırmaya çalıştınız mı?
Jacob Jan Tuinstra

4
10.000 satır kopyala / yapıştır? Hayır teşekkürler. Word / Excel gayet iyi olacak.
Bryce

Yanıtlar:


8

Bunun için bir Google Apps Komut Dosyası yazmanız gerekecek . E-tablonun ilk satırının alan adları olmasına izin verebilir ve alanlara atıfta bulunulan bir şablon belgesi oluşturabilirsiniz [FIELD].

E-tablonuz şöyle görünüyorsa:

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

... bir şablon belgeniz olabilir.

Sevgili [NAME], [STREET], [TOWN] [ZIP] 'da yaşıyor ...

Komut dosyanızın yeni, boş bir belge oluşturması ve e-tablonuzdaki her satır için yeni bir sayfa eklemeniz ve alan yer tutucularını satır değerleriyle araması / değiştirmesi gerekir.

Biraz parlatma gerektirebilecek biraz çalışan bir versiyonum var. Bu çağrılabilir burada . Adres mektup birleştirme sonucu adlı yeni bir belge oluşturur .

Kendi betiğiniz için bir başlangıç ​​noktası olarak kullanabilirsiniz. Bu konuya girip girmediğinizi bize bildirin, yoksa senaryoyu bitirmek için biraz daha zaman harcayabilirim.

Komut dosyası içeriği:

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
Neden e-tablo içinden tek başına bir uygulama değil, tek başına bir uygulama kullanmayı seçtiniz? Bu OP için çok daha kolay olacaktır. İkincisi, senaryoda neden bu kadar çok Logger çağrısı var? Senaryoyu aşırı yoğun hale getirecektir.
Jacob Jan Tuinstra

Önceden oluşturulmuş bazı komut dosyalarına sahip olan Google komut dosyası arşivinin ... sizin veya başka bir dosyanın yüklenmemesinin belirli bir nedeni var mı?
Bryce

Şimdiye kadar Yakup'un yorumunu fark etmedi ve söylediği gibi, büyük olasılıkla bağımsız yerine bir e-tablo komut dosyası olmalıdır. Üzerinde çalışmak için zaman bulabilecek miyim ve Script galerisine göndereceğim.
Vidar S. Ramdal

5
Vidar Bu harika bir cevap. Temizledim ve kullanımdan kaldırılan yöntemlerin bazılarını güncelledim ve gereksiz işlevlerden kurtuldum ve ayrıca @JacobJanTuinstra'nın önerdiği gibi e-tablodan çalıştırılmak üzere değiştirdim. Sonra görüntüleri kıran bir hata olduğunu fark ettim ve bu hata için de bir çözüm buldum. Şimdi Github'a konacak kadar güzel olduğunu hissediyorum. Orada yayınladım ve içinde çalışmanın başlangıç ​​sürümü olarak yanıtınıza bir bağlantı sağladım.
hadi

@hadi İyi iş çıkardın!
Vidar S. Ramdal

6

Yeni Google Drive Eklentileri sayesinde, "Yine Başka Bir Adres Mektup Birleştirme" gibi çeşitli adres mektup birleştirme olanakları vardır.

Bunu kullanmak için "yeni" bir Google E-Tablonuz olması ve Eklentiyi Ons Ekle menüsünden yüklemeniz gerekir:

Google E-Tablolar'dan ekran görüntüsü

Arayın Mail mergeve birkaç seçenek bulacaksınız.


Günde 100 e-posta ile sınırlı olduğunu unutmayın (ücretsiz).
pixeline

5

Google'ın kendi yayını, feed verilerinin Google E-Tablo + Google Dokümanı yerine bir sayfada ve başka bir şablonda nasıl ayarlanacağını açıklıyor: https://developers.google.com/apps-script/articles/mail_merge

Ancak, sonuç, MailAppistenen "klonlanmış" belge yerine e-posta göndermektir. Ben öğretici ve @ Vidar cevabını, değiştirme satırları boyunca bir şey birleştirmenizi öneririz:

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

ile

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?

Random AppScripts Referansları:


başka bir örnek olarak bu GIST ile karşılaştık gist.github.com/mhawksey/1170597
drzaus

3
Bu soru özellikle e-posta adres-mektup birleştirme işlemini içermez.
Bryce

3

AutoCrat'ı öneririm . Birleştirmeyi ayarlamanıza yardımcı olacak mükemmel bir sihirbaz benzeri arayüze sahip bir Google Eklentisidir.


1

Aynı sorunu yaşadım ve Vidar'ın cevabı ile çözmeye çalıştım ama itiraz nedeniyle işe yaramadı.

Asıl çözüm, Vidar'ın cevabı hakkındaki yorumda @hadi'nin bağlantısıdır.

Vidar :
Bu harika bir cevap. Temizledim ve kullanımdan kaldırılan yöntemlerin bazılarını güncelledim ve gereksiz işlevlerden kurtuldum ve ayrıca @ JacobJanTuinstra'nın önerdiği gibi e-tablodan çalıştırılmak üzere değiştirdim . Sonra görüntüleri kıran bir hata olduğunu fark ettim ve bu hata için de bir çözüm buldum. Şimdi Github'a konacak kadar güzel olduğunu hissediyorum. Oraya gönderdim ve içinde çalışmanın başlangıç ​​sürümü olarak yanıtınıza bir bağlantı sağladım.
- hadi 4 '15 Mart 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.

Sadece üzerindeki adımları Readmeizledim ve bir şablon Google-Doc ve Google-Sheet'den birleştirilmiş bir belge oluşturabildim.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.