使用Microsoft Excel和Microsoft Word,可以轻松地将电子表格中的行合并到Word文件中的页面中。传统上,这是用来制作纸质邮件的。如何使用Google云端硬盘/ Google文档执行相同的操作?
有许多模板可提供电子表格到电子邮件的合并: 如何与Gmail合并邮件?但这不是我所追求的。
使用Microsoft Excel和Microsoft Word,可以轻松地将电子表格中的行合并到Word文件中的页面中。传统上,这是用来制作纸质邮件的。如何使用Google云端硬盘/ Google文档执行相同的操作?
有许多模板可提供电子表格到电子邮件的合并: 如何与Gmail合并邮件?但这不是我所追求的。
Answers:
您将需要为此编写一个Google Apps脚本。您可以将电子表格的第一行作为字段名称,并创建一个模板文档,在其中引用字段[FIELD]
。
因此,如果您的电子表格看起来像:
NAME | STREET | ZIP | TOWN
---------------------------------------------
Vidar | Karl Johans gate 15 | 0200 | Oslo
John | 3021 Arlington Road | 123456 | Memphis, TN
...您可能有一个模板文档,例如
亲爱的[NAME],住在[STREET],[TOWN] [ZIP] ...
您的脚本将需要创建一个新的空文档,并为电子表格中的每一行添加一个新页面,并用行值搜索/替换字段占位符。
我有一个工作版本,可能需要一些改进。可以在这里调用。它将创建一个名为Result of mail merge的新文档。
您可以将其用作自己的脚本的起点。让我知道您是否感兴趣,否则我可以花更多时间完成脚本。
脚本内容:
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();
}
通过新的Google云端硬盘插件,可以使用多种邮件合并功能,例如“还可以进行其他邮件合并”。
要使用它,您必须具有“新” Google Spreadsheet,然后通过“加载项”菜单安装加载项:
搜索Mail merge
,您将找到几个选项。
Google自己的帖子解释了如何在一个工作表中设置提要数据,而在另一工作表中而不是Google Spreadsheet + Google Doc中设置模板:https : //developers.google.com/apps-script/articles/mail_merge
但是,最终结果是MailApp
发送电子邮件而不是所需的“克隆”文档。我建议结合使用本教程和@Vidar的答案,以替代方式:
MailApp.sendEmail(rowData.emailAddress, emailSubject, emailText);
与
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?
随机的AppScript参考:
我遇到了同样的问题,并尝试用Vidar的答案解决它,但由于弃用,它无法正常工作。
实际的解决方案是@hadi在Vidar的答案评论中的链接。
维达尔:
这是一个很好的答案。我清理了它,并更新了一些不推荐使用的方法,并摆脱了不必要的功能,并按照 @ JacobJanTuinstra的 建议将其修改为可以在电子表格中运行。然后,我意识到存在一个会破坏图像的错误,并且我也对该错误做出了解决方法。我觉得现在可以放到Github上了。我已经将其张贴在此处,并在其中提供了指向您回复的链接,作为该作品的起始版本。
– 哈迪2015年3月 4日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.
只需按照上的步骤操作Readme
,我便可以通过模板Google-Doc和Google-Sheet创建合并的文档。