【问题标题】:Generate PDF through Google App Script通过 Google App Script 生成 PDF
【发布时间】:2018-07-07 17:34:18
【问题描述】:

我找到了一个script,它从活动 Google 电子表格中的活动行中获取字段,并使用 Google Doc 模板创建了一个 PDF,其中这些字段替换了模板中的键。密钥通过在任一侧具有% 来标识,例如%Name%.

链接代码向 UI 添加了一个菜单项,因此用户只需单击一个单元格,然后选择“创建 PDF”菜单选项。我想做一些改变,以满足我的需要。我的上下文是:

  1. 用户在每个单元格下拉列表中选择一个选项,分别在 C3、C5、C7 和 C9 中找到。这些选择会触发我工作表中的过滤器;

  2. 用户单击按钮,根据工作表状态生成 PDF 报告;

  3. 如果设置了无效选项或成功生成报告,脚本会显示一条消息;

我当前的代码:

var TEMPLATE_ID = ''
var PDF_FILE_NAME = ''

function checkEntries(){
  var ss = SpreadsheetApp.getActiveSheet(),
      sheet = ss.getSheets()[0],
      project = ss.getRange('C3').getValue(),
      month = ss.getRange('C5').getValue(),
      year = ss.getRange('C7').getValue();

  if(project === 'all' && month === 'all' && year === 'all'){
    SpreadsheetApp.getUi().alert('The report is always specific to a project in a specific year and month')
    return;
  }
}

function createPdf() {
  var copyFile = DriveApp.getFileById(TEMPLATE_ID).makeCopy(),
      copyId = copyFile.getId(),
      copyDoc = DocumentApp.openById(copyId),
      copyBody = copyDoc.getActiveSection();

  var ss = SpreadsheetApp.getActiveSheet(),
      sheet = ss.getSheets()[0],
      project = ss.getRange('C3').getValue(),
      total_cost = ss.getRange('C14').getValue(),
      month = ss.getRange('C7').getValue(),
      year = ss.getRange('C9').getValue();

  var replace_values = [];
  replace_values.push(total_cost, year, month)

  for (var i = 0; i < replace_values.length; i++) {
    copyBody.replaceText('%' + replace_values[i] + '%', 
                         replace_values[i])          
  }
  copyDoc.saveAndClose()

  var newFile = DriveApp.createFile(copyFile.getAs('application/pdf'))  
  if (PDF_FILE_NAME !== '') {
    newFile.setName(PDF_FILE_NAME)
  } 

  copyFile.setTrashed(true)

  SpreadsheetApp.getUi().alert('report generated successfully')
} 

我将该脚本链接到一个按钮,但它没有获取单元格值,也没有生成 PDF。预期行为是基于 Doc 模板生成 PDF 文档,将占位符替换为 yearmonthtotal_cost 变量。我做错了什么,我该如何实现预期的行为?

【问题讨论】:

  • “它不起作用”不是有效的问题描述。编辑您的问题以包含遇到的任何特定错误,以及所需的行为和当前行为。
  • 完成。我想我可以更多地了解当前写入日志的行为。我会这样做并发布结果
  • 您提到您将脚本链接到按钮...好吧,您的脚本有两个功能。哪个与按钮相关联?请注意,第一个函数 checkEntries 不会调用第二个函数 createPDF
  • 我的回答是否向您展示了您想要的结果?你能告诉我吗?这对我学习也很有用。如果这可行,与您有相同问题的其他人也可以将您的问题作为可以解决的问题。如果您对我的回答有疑问,请随时告诉我。我想学习解决你的问题。
  • 非常感谢,你的帮助很大!

标签: google-apps-script google-sheets google-docs export-to-pdf


【解决方案1】:

这个修改怎么样?我认为您的情况有几个答案。因此,请将此视为其中之一。

修改点:

  • 你可以像copyDoc.replaceText('%' + replace_values[i] + '%', replace_values[i])一样使用copyDoc
  • var ss = SpreadsheetApp.getActiveSheet(), 运行后,sheet = ss.getSheets()[0], 出现错误。
    • 如果要使用索引为“0”的工作表,可以使用var ss = SpreadsheetApp.getActiveSpreadsheet(),ss作为它。
    • 在此修改中,我认为您可能还想使用其他索引。所以我使用了sheet = ss.getSheets()[0];
  • project = ss.getRange('C3').getValue(), 中的project 未在createPdf() 中使用。
  • var replace_values = []; replace_values.push(total_cost, year, month)var replace_values = [total_cost, year, month]; 相同。
    • 你也可以使用像[total_cost, month, year] = [sheet.getRange('C14').getValue(), sheet.getRange('C7').getValue(), sheet.getRange('C9').getValue()];这样的解构赋值来代替total_cost = sheet.getRange('C14').getValue(),month = sheet.getRange('C7').getValue(),year = sheet.getRange('C9').getValue();

当这些反映到修改后的脚本中时,请进行如下修改。

从 :
var copyFile = DriveApp.getFileById(TEMPLATE_ID).makeCopy(),
    copyId = copyFile.getId(),
    copyDoc = DocumentApp.openById(copyId),
    copyBody = copyDoc.getActiveSection();
var ss = SpreadsheetApp.getActiveSheet(),
    sheet = ss.getSheets()[0],
    project = ss.getRange('C3').getValue(),
    total_cost = ss.getRange('C14').getValue(),
    month = ss.getRange('C7').getValue(),
    year = ss.getRange('C9').getValue();
var replace_values = [];
replace_values.push(total_cost, year, month)
for (var i = 0; i < replace_values.length; i++) {
  copyBody.replaceText('%' + replace_values[i] + '%', replace_values[i])
}
到 :
var copyFile = DriveApp.getFileById(TEMPLATE_ID).makeCopy(),
    copyId = copyFile.getId(),
    copyDoc = DocumentApp.openById(copyId);
var ss = SpreadsheetApp.getActiveSpreadsheet(), // Modified
    sheet = ss.getSheets()[0],
    total_cost = sheet.getRange('C14').getValue(), // Modified
    month = sheet.getRange('C7').getValue(), // Modified
    year = sheet.getRange('C9').getValue(); // Modified
var replace_values = [total_cost, year, month]; // Modified
for (var i = 0; i < replace_values.length; i++) {
  copyDoc.replaceText('%' + replace_values[i] + '%', replace_values[i]); // Modified
}

注意:

参考资料:

如果这不是你想要的,请告诉我。我想修改它。

【讨论】:

  • 而不是replaceValues 的两部分“初始化然后添加”,为什么不var replaceValues = [total_cost, year, month];
  • @tehhowch 感谢您的评论。我将其添加为修改之一。
  • 我也认为replaceValues在原始脚本中的使用是不正确的——应该有一个键(由%符号包围)和一个将替换它的值。例如。 for (var key in values) copyDoc.replaceText("%" + key + "%", values[key]); 其中值为 {year: "...", ... }
  • @tehhowch 感谢您提供更多信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多