生成多个PDF文件,然后在一个文档中合并它们(应用脚本)。

huangapple go评论65阅读模式
英文:

Generate multiple pdfs at once and merge them after in one document (app script)

问题

在Google电子表格中,我有一个名为“ID_list_Google_doc”的列表,该列表从D3到D(D3:D)创建,其中包含许多Google文档的ID。每个Google文档ID都是唯一的,代表了用于创建PDF的不同模板。

如何解决问题:遍历列表,识别单元格是否包含文本,如果是,生成PDF,如果不是,则不执行任何操作?

然后将这些PDF合并成单一文档。

英文:

In the google spreadsheet, I have a list called "ID_list_Google_doc", the list created from D3 to D (D3:D), which consists of a multitude of google doc ids. Each google doc id is unique and represents a different template for creating pdfs.
What is the solution to go through the list, and identify if the cell contains text if yes, generate pdf, if not do nothing?
Then combine the pdfs into a single document.

答案1

得分: 1

以下是已翻译的内容:

我相信您的目标如下。

  • 您想要从Google电子表格的单元格 "D3:D" 中检索Google文档ID。
  • 您想要将Google文档转换为PDF格式,并且您还想要将所有PDF数据合并为一个PDF文件。

在这种情况下,以下示例脚本如何?在这种情况下,为了将多个PDF数据合并为PDF数据,我使用了pdf-lib

模式1:

在此模式中,电子表格上使用了对话框。请设置您的工作表名称并保存脚本。当您运行 main() 时,在电子表格上打开对话框,并从单元格 "D3:D" 中检索文档ID,将文档转换为PDF格式。然后,将PDF数据合并为单个PDF文件,并将其创建为根文件夹中的文件。

function saveFile(data) {
  const blob = Utilities.newBlob(data, MimeType.PDF, "sample1.pdf");
  DriveApp.createFile(blob);
  return "Done.";
}

function getPDFdata() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1"); // 请设置您的工作表名称。
  const ids = sheet.getRange("D3:D" + sheet.getLastRow()).getDisplayValues().filter(([d]) => d);
  return ids.map(([id]) => DriveApp.getFileById(id).getBlob().getBytes());
}

// 请运行此脚本。
function main() {
  const html = `Now processing... <script src='https://cdn.jsdelivr.net/npm/pdf-lib/dist/pdf-lib.min.js'></script><script>google.script.run.withSuccessHandler(async (data)=>{const pdfDoc=await PDFLib.PDFDocument.create();for (let i=0;i < data.length;i++){const pdfData=await PDFLib.PDFDocument.load(new Uint8Array(data[i]));for (let j=0;j < pdfData.getPageCount();j++){const [page]=await pdfDoc.copyPages(pdfData,[j]);pdfDoc.addPage(page)}}const bytes=await pdfDoc.save();google.script.run.withSuccessHandler(google.script.host.close).saveFile([...new Int8Array(bytes)])}).getPDFdata();</script>`;
  SpreadsheetApp.getUi().showModalDialog(HtmlService.createHtmlOutput(html), "sample");
}
  • 在上述脚本中,Google Apps Script 中包含了以下HTML和JavaScript。
Now processing...
<script src='https://cdn.jsdelivr.net/npm/pdf-lib/dist/pdf-lib.min.js'></script>
<script>
google.script.run.withSuccessHandler(async (data) => {
  const pdfDoc = await PDFLib.PDFDocument.create();
  for (let i = 0; i < data.length; i++) {
    const pdfData = await PDFLib.PDFDocument.load(new Uint8Array(data[i]));
    for (let j = 0; j < pdfData.getPageCount(); j++) {
      const [page] = await pdfDoc.copyPages(pdfData, [j]);
      pdfDoc.addPage(page);
    }
  }
  const bytes = await pdfDoc.save();
  google.script.run.withSuccessHandler(google.script.host.close).saveFile([...new Int8Array(bytes)]);
}).getPDFdata();
</script>

模式2:

我注意到在当前阶段,pdf-lib.min.js 可以直接与Google Apps Script 一起使用。因此,作为模式2,我还想提供一个无需使用对话框的示例脚本。在这个示例脚本中,当您运行 main() 时,脚本将运行。并且,可以获得与上述脚本相同的结果,而无需打开对话框。

async function main() {
  // 检索PDF数据。
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1"); // 请设置您的工作表名称。
  const ids = sheet.getRange("D3:D" + sheet.getLastRow()).getDisplayValues().filter(([d]) => d);
  const data = ids.map(([id]) => new Uint8Array(DriveApp.getFileById(id).getBlob().getBytes()));

  // 合并PDFs。
  const cdnjs = "https://cdn.jsdelivr.net/npm/pdf-lib/dist/pdf-lib.min.js";
  eval(UrlFetchApp.fetch(cdnjs).getContentText()); // 加载pdf-lib
  const pdfDoc = await PDFLib.PDFDocument.create();
  for (let i = 0; i < data.length; i++) {
    const pdfData = await PDFLib.PDFDocument.load(data[i]);
    for (let j = 0; j < pdfData.getPageCount(); j++) {
      const [page] = await pdfDoc.copyPages(pdfData, [j]);
      pdfDoc.addPage(page);
    }
  }
  const bytes = await pdfDoc.save();

  // 创建PDF文件。
  DriveApp.createFile(Utilities.newBlob([...new Int8Array(bytes)], MimeType.PDF, "sample2.pdf"));
}

注意:

参考:

英文:

I believe your goal is as follows.

  • You want to retrieve the Google Document IDs from cells "D3:D" on Google Spreadsheet.
  • You want to convert Google Documents to PDF format, and also you want to merge all PDF data as a PDF file.

In this case, how about the following sample script? In this case, in order to merge multiple PDF data as PDF data, I used pdf-lib.

Pattern 1:

In this pattern, a dialog is used on the Spreadsheet. Please set your sheet name and save the script. When you run main(), a dialog is opened on Spreadsheet, and the document IDs are retrieved from cells "D3:D" and the documents are converted to PDF format. And, the PDF data is merged as a single PDF file and created it as a file in the root folder.

function saveFile(data) {
  const blob = Utilities.newBlob(data, MimeType.PDF, &quot;sample1.pdf&quot;);
  DriveApp.createFile(blob);
  return &quot;Done.&quot;;
}

function getPDFdata() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(&quot;Sheet1&quot;); // Please set your sheet name.
  const ids = sheet.getRange(&quot;D3:D&quot; + sheet.getLastRow()).getDisplayValues().filter(([d]) =&gt; d);
  return ids.map(([id]) =&gt; DriveApp.getFileById(id).getBlob().getBytes());
}

// Please run this script.
function main() {
  const html = `Now processing... &lt;script src=&#39;https://cdn.jsdelivr.net/npm/pdf-lib/dist/pdf-lib.min.js&#39;&gt;&lt;/script&gt;&lt;script&gt;google.script.run.withSuccessHandler(async (data)=&gt;{const pdfDoc=await PDFLib.PDFDocument.create();for (let i=0;i &lt; data.length;i++){const pdfData=await PDFLib.PDFDocument.load(new Uint8Array(data[i]));for (let j=0;j &lt; pdfData.getPageCount();j++){const [page]=await pdfDoc.copyPages(pdfData,[j]);pdfDoc.addPage(page)}}const bytes=await pdfDoc.save();google.script.run.withSuccessHandler(google.script.host.close).saveFile([...new Int8Array(bytes)])}).getPDFdata();&lt;/script&gt;`;
  SpreadsheetApp.getUi().showModalDialog(HtmlService.createHtmlOutput(html), &quot;sample&quot;);
}
  • In the above script, the following HTML & Javascript is included in the Google Apps Script.

    Now processing...
    &lt;script src=&#39;https://cdn.jsdelivr.net/npm/pdf-lib/dist/pdf-lib.min.js&#39;&gt;&lt;/script&gt;
    &lt;script&gt;
    google.script.run.withSuccessHandler(async (data) =&gt; {
      const pdfDoc = await PDFLib.PDFDocument.create();
      for (let i = 0; i &lt; data.length; i++) {
        const pdfData = await PDFLib.PDFDocument.load(new Uint8Array(data[i]));
        for (let j = 0; j &lt; pdfData.getPageCount(); j++) {
          const [page] = await pdfDoc.copyPages(pdfData, [j]);
          pdfDoc.addPage(page);
        }
      }
      const bytes = await pdfDoc.save();
      google.script.run.withSuccessHandler(google.script.host.close).saveFile([...new Int8Array(bytes)]);
    }).getPDFdata();
    &lt;/script&gt;
    

Pattern 2:

I noticed that in the current stage, pdf-lib.min.js can be directly used with Google Apps Script. So, as a pattern 2, I would like to also propose a sample script without using a dialog. In this sample script, when you run main(), the script is run. And, the same result with the above script is obtained without opening a dialog.

async function main() {
  // Retrieve PDF data.
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(&quot;Sheet1&quot;); // Please set your sheet name.
  const ids = sheet.getRange(&quot;D3:D&quot; + sheet.getLastRow()).getDisplayValues().filter(([d]) =&gt; d);
  const data = ids.map(([id]) =&gt; new Uint8Array(DriveApp.getFileById(id).getBlob().getBytes()));

  // Merge PDFs.
  const cdnjs = &quot;https://cdn.jsdelivr.net/npm/pdf-lib/dist/pdf-lib.min.js&quot;;
  eval(UrlFetchApp.fetch(cdnjs).getContentText()); // Load pdf-lib
  const pdfDoc = await PDFLib.PDFDocument.create();
  for (let i = 0; i &lt; data.length; i++) {
    const pdfData = await PDFLib.PDFDocument.load(data[i]);
    for (let j = 0; j &lt; pdfData.getPageCount(); j++) {
      const [page] = await pdfDoc.copyPages(pdfData, [j]);
      pdfDoc.addPage(page);
    }
  }
  const bytes = await pdfDoc.save();

  // Create a PDF file.
  DriveApp.createFile(Utilities.newBlob([...new Int8Array(bytes)], MimeType.PDF, &quot;sample2.pdf&quot;));
}

Note:

References:

huangapple
  • 本文由 发表于 2023年1月9日 15:14:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/75054125.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定