合并两个PDF时触发setTimeout未定义错误,求助解决
合并PDF时抛出ReferenceError: setTimeout is not defined错误
我编写了一个合并两个PDF的函数(运行在forEach循环中,此处省略循环代码)。控制台日志显示PDF已成功加载,但无法生成目标文件"combined.pdf",报错信息:ReferenceError: setTimeout is not defined。
相关代码如下:
// ****** FUNCTION 1 ****** async function loadPDF(pdfBytes) { try { const loadedPdf = await PDFLib.PDFDocument.load(pdfBytes); console.log(`PDF loaded successfully`); return loadedPdf; } catch (error) { console.log(`Error loading PDF:`, error); return null; } } // ****** MAIN FUNCTION ****** async function combinePDFsIntoOne () { const cdnjs = 'https://cdn.jsdelivr.net/npm/pdf-lib@1.16.0/dist/pdf-lib.min.js'; eval(UrlFetchApp.fetch(cdnjs).getContentText()); const pdfFile1 = pdf; const pdfFile2 = pdfP2FileName; console.log(typeof pdfFile1) //object console.log(pdfFile1) /* { toString: [Function], getName: [Function], getBytes: [Function], setName: [Function], getContentType: [Function], setContentType: [Function], setBytes: [Function], getDataAsString: [Function], setDataFromString: [Function], isGoogleType: [Function], getAllBlobs: [Function], setContentTypeFromExtension: [Function], copyBlob: [Function], getAs: [Function] } */ console.log(typeof pdfFile2) //object console.log(pdfFile2) /* { toString: [Function], getName: [Function], getBytes: [Function], setName: [Function], getContentType: [Function], setContentType: [Function], setBytes: [Function], getDataAsString: [Function], setDataFromString: [Function], isGoogleType: [Function], getAllBlobs: [Function], setContentTypeFromExtension: [Function], copyBlob: [Function], getAs: [Function] } */ // Read files as "Binary Strings" const pdfBytes1 = new Uint8Array(pdfFile1.getBytes()); const pdfBytes2 = new Uint8Array(pdfFile2.getBytes()); // Create new pdf const pdfDoc = await PDFLib.PDFDocument.create(); // Try loading the first PDF const firstPDF = await loadPDF(pdfBytes1); // PDF loaded successfully console.log(typeof firstPDF); if (!firstPDF) { console.log(`Error loading first PDF ${typeof firstPDF}`); } // Try loading the second PDF const secondPDF = await loadPDF(pdfBytes2); // PDF loaded successfully if (!secondPDF) { console.log(`Error loading second PDF ${typeof secondPDF}`); } // Get pages to import const firstPDFPages = await pdfDoc.copyPages(firstPDF, firstPDF.getPageIndices()); const secondPDFPages = await pdfDoc.copyPages(secondPDF, secondPDF.getPageIndices()); // Add pages to the PDF firstPDFPages.forEach((page) => pdfDoc.addPage(page)); secondPDFPages.forEach((page) => pdfDoc.addPage(page)); const pdfBytes = await pdfDoc.save(); const newBlob = Utilities.newBlob(Array.from(pdfBytes), 'application/pdf'); newBlob.setName('combined.pdf'); holdingFolder.createFile(newBlob); }; try { await combinePDFsIntoOne (); } catch(err) { console.log(`Error is: ${err}`) // Error is: ReferenceError: setTimeout is not defined }
问题原因与解决方案
原因
代码运行在Google Apps Script(GAS)环境中,该环境使用Rhino JavaScript引擎,没有原生的setTimeout全局函数。而pdf-lib库的内部异步逻辑依赖了这个函数,因此触发了报错。
解决方法:模拟setTimeout函数
在加载pdf-lib之前,手动模拟setTimeout和clearTimeout函数,让pdf-lib可以正常运行:
// ****** MAIN FUNCTION ****** async function combinePDFsIntoOne () { // 为GAS环境模拟setTimeout和clearTimeout global.setTimeout = (callback) => { // 直接同步执行回调,pdf-lib不需要实际延迟 callback(); return 0; }; global.clearTimeout = () => {}; const cdnjs = 'https://cdn.jsdelivr.net/npm/pdf-lib@1.16.0/dist/pdf-lib.min.js'; eval(UrlFetchApp.fetch(cdnjs).getContentText()); // ... 剩余代码保持不变 }
替代方案:使用GAS原生PDF合并能力
如果不想依赖第三方库,可以启用Drive API服务后,使用原生能力合并PDF:
function combinePDFsNative() { const fileIds = [pdfFile1.getId(), pdfFile2.getId()]; const resource = { title: 'combined.pdf', mimeType: 'application/pdf', parents: [{id: holdingFolder.getId()}] }; // 复制第一个PDF作为基础文件 const combinedFile = Drive.Files.copy(resource, fileIds[0], { convert: false, ocr: false, uploadType: 'multipart' }); // 将第二个PDF的页面追加到合并文件中 Drive.Files.update({}, combinedFile.id, pdfFile2.getBlob(), { uploadType: 'media', append: true }); }
内容的提问来源于stack exchange,提问作者Borgher
相关产品推荐
相关产品推荐

