使用Google Apps Script合并多PDF时出现setTimeout未定义错误
解决Google Apps Script合并PDF脚本的setTimeout未定义错误
问题场景
我编写了一段用于通过Google Apps Script合并多个PDF文件的脚本:
async function newMain() { // Retrieve PDF data. const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); // Please set your sheet name. const ids = sheet.getRange("D1:D2").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")); }
运行时出现错误:
ReferenceError: setTimeout is not defined
eval
X
eval
eval
eval
a
错误原因
pdf-lib库内部依赖setTimeout API,若脚本运行在Rhino旧版运行时(而非V8),该环境不支持浏览器/Node.js标准的setTimeout;即使在V8环境中,直接通过eval加载库也可能导致上下文缺失问题。
解决步骤
步骤1:切换到V8运行时
- 打开Google Apps Script编辑器,点击右上角的⚙️设置图标。
- 勾选「启用新的Apps Script V8运行时」选项,保存设置后刷新编辑器。
步骤2:添加setTimeout polyfill(可选,针对V8环境仍报错的情况)
在加载pdf-lib前添加polyfill,确保库能正常获取到setTimeout:
async function newMain() { // 新增:polyfill setTimeout,避免上下文缺失 if (typeof setTimeout === 'undefined') { globalThis.setTimeout = (callback) => callback(); } // Retrieve PDF data. const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); // Please set your sheet name. const ids = sheet.getRange("D1:D2").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")); }
替代方案:直接嵌入pdf-lib代码
如果CDN加载不稳定,可手动下载pdf-lib.min.js的内容,粘贴到一个新的脚本文件(比如命名为PdfLib),主脚本中可直接使用PDFLib对象,无需通过eval加载。
验证
修改后重新运行newMain函数,即可正常合并PDF文件。
内容的提问来源于stack exchange,提问作者EagleEye
相关产品推荐
相关产品推荐

