我想实现一个工作流程,用户通过 Google 表单提交数据,他们的回复会自动发布到预先存在的 PDF 表单中。
我有几个我经常使用的 PDF 表单。我创建了一个 Google 表单来收集完成 PDF 所需的所有信息。现在我正在尝试找到一种将答案映射到原始 PDF 的方法。
我怎样才能做到这一点?
我想实现一个工作流程,用户通过 Google 表单提交数据,他们的回复会自动发布到预先存在的 PDF 表单中。
我有几个我经常使用的 PDF 表单。我创建了一个 Google 表单来收集完成 PDF 所需的所有信息。现在我正在尝试找到一种将答案映射到原始 PDF 的方法。
我怎样才能做到这一点?
Patentbytes.com 上有一篇文章Automatically Completing Your PDF Forms,其中详细介绍了这个主题,也是这个答案的灵感来源。
使用 Google Apps 脚本,您无法修改现有的 PDF 表单。但是,您可以利用 Adobe Acrobat 和 Acrobat Reader 等应用程序中的现有导入功能,通过脚本以易于导入的方式生成表单数据。
这是想法:
在继续之前,您的 PDF 表单需要具有特定的特征:
我们将使用前面提到的文章中的示例表单作为示例。它工作,虽然它需要清理。
使用 Acrobat Reader(或类似软件),完整填写示例表单,然后将表单数据导出为 XML。(如果您使用将用于 HTML 模板的 camelCase 术语填写表格,它将简化未来的步骤 - 例如inventionTitle
。)
在 Apps 脚本编辑器中,使用 File-New 在项目中创建一个新的 html 文件,并将其命名为“formXml”。将导出的 xml 文件的文本内容粘贴到 formXml.html 中。
XML 声明需要在我们的最终输出中,但如果留在模板中会导致 HtmlService 崩溃。从模板中删除它;我们将把它添加回我们的代码中。
<?xml version="1.0" encoding="UTF-8"?>
(可选)美化 XML,使其更容易避免引入错误。(freeformatter.com 有一个有用的 xml 格式化程序。我发现第一次使用“紧凑模式”,然后第二次通过每个缩进 2 个空格产生了很好的结果。
(可选)对字段进行逻辑重新排序。
对于每个输入字段,将示例文本替换为有效的打印脚本。
inventionTitle becomes <?= inventionTitle ?>
这是您的表单 XML 模板最终应该是什么样子的。在这个例子中,我们只有 5 个表单域。
<fields xmlns:xfdf="http://ns.adobe.com/xfdf-transition/">
<TitleofInvention xfdf:original="Title of Invention"><?= inventionTitle ?></TitleofInvention>
<Inventorone xfdf:original="Inventor one"><?= inventor1name ?></Inventorone>
<Citizenof xfdf:original="Citizen of"><?= inventor1citizenship ?></Citizenof>
<Inventortwo xfdf:original="Inventor two"><?= inventor2name ?></Inventortwo>
<Citizenof_2 xfdf:original="Citizen of_2"><?= inventor2citizenship ?></Citizenof_2>
</fields>
这是表单提交触发功能。每次用户填写您的在线 google 表单时,此电子表格表单提交触发器将处理他们的回复,并在您的 google 驱动器上保存一个带时间戳的 xml 文件,准备导入 PDF 表单。
function formSubmission(eventData) {
// Get a handle on the xml template
var formXml = HtmlService.createTemplateFromFile('formXml');
// Replace templated values with user's input
formXml.inventionTitle = eventData.namedValues['Invention Title'];
formXml.inventor1name = eventData.namedValues['Inventor 1 Name'];
formXml.inventor1citizenship = eventData.namedValues['Inventor 1 Citizenship'];
formXml.inventor2name = eventData.namedValues['Inventor 2 Name'];
formXml.inventor2citizenship = eventData.namedValues['Inventor 2 Citizenship'];
// Evaluate the template with substitutions
var xml = formXml.evaluate();
// Get the evaluated template as text, prepend the XML Declaration
var formXmlText = '<?xml version="1.0" encoding="UTF-8"?>'
+ xml.getContent();
// Save user's input as an xml file on our Google Drive
var fileName = 'Form ' + eventData.namedValues['Timestamp'];
var xmlFile = DriveApp.createFile(fileName, formXmlText, MimeType.XML);
}
触发函数处理的namedValues
eventData 对象来自 Form Responses 工作表,这些工作表直接来自 Form questions。(这是保持问题简短的一个很好的理由,并依靠帮助文本来详细说明!)