簡體   English   中英

一次生成多個 pdf,然后將它們合並到一個文檔中(應用程序腳本)

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

在谷歌電子表格中,我有一個名為“ID_list_Google_doc”的列表,該列表從 D3 到 D (D3:D) 創建,其中包含大量谷歌文檔 ID。 每個 google doc id 都是唯一的,代表用於創建 pdf 的不同模板。 通過列表解決go,判斷單元格是否包含文本如果是則生成pdf,如果不是什么都不做? 然后將 pdf 組合成一個文檔。

我相信你的目標如下。

  • 您想要從 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"); // Please set your sheet name.
  const ids = sheet.getRange("D3:D" + sheet.getLastRow()).getDisplayValues().filter(([d]) => d);
  return ids.map(([id]) => DriveApp.getFileById(id).getBlob().getBytes());
}

// Please run this script.
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");
}
  • 在上面的腳本中,以下 HTML & Javascript 包含在 Google Apps 腳本中。

     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() {
  // Retrieve PDF data.
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1"); // Please set your sheet name.
  const ids = sheet.getRange("D3:D" + sheet.getLastRow()).getDisplayValues().filter(([d]) => d);
  const data = ids.map(([id]) => new Uint8Array(DriveApp.getFileById(id).getBlob().getBytes()));

  // Merge PDFs.
  const cdnjs = "https://cdn.jsdelivr.net/npm/pdf-lib/dist/pdf-lib.min.js";
  eval(UrlFetchApp.fetch(cdnjs).getContentText()); // Load 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();

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

筆記:

參考:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM