如何用pdf-lib或脚本库修改PDF中drawText添加的文本?
在Google Apps Script中用PDF-Lib实现PDF文本替换(而非叠加)
方案1:基于原始PDF副本修改(最简单高效)
每次修改都从未添加过文本的原始PDF文件读取内容,再覆盖目标文件,从根源避免叠加问题。
修改后的代码:
async function modifyPdf() { // 替换为你的「干净原始PDF」文件ID(从未添加过文本的版本) const ORIGINAL_PDF_ID = "你的原始PDF文件ID"; // 目标PDF的ID(可以是原文件,也可以是新文件) const TARGET_PDF_ID = "1Zy4Fbq__ubjX0NLs7J5WPGj7JlV_8-KJ"; const pdfData = new Uint8Array(DriveApp.getFileById(ORIGINAL_PDF_ID).getBlob().getBytes()); const { PDFDocument, StandardFonts, rgb } = PDFLib; const pdfDoc = await PDFDocument.load(pdfData); const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica); const firstPage = pdfDoc.getPages()[0]; const { height } = firstPage.getSize(); // 写入新文本(每次都在干净的原始PDF上添加,自然替换旧内容) firstPage.drawText(`替换后的新文本`, { x: 10, y: height - 10, size: 20, font: helveticaFont, color: rgb(0.95, 0.1, 0.1) }); const pdfBytes = await pdfDoc.save(); Drive.Files.update( { title: "newpdf from apps script v22", mimeType: "application/pdf" }, TARGET_PDF_ID, Utilities.newBlob(pdfBytes) ) }
方案2:解析页面内容流删除旧文本(适合必须基于当前文件修改的场景)
PDF页面内容由一系列指令组成,我们可以解析内容流,过滤掉之前添加的文本绘制指令,再添加新文本。
代码示例:
async function modifyPdf() { const TARGET_PDF_ID = "1Zy4Fbq__ubjX0NLs7J5WPGj7JlV_8-KJ"; const pdfData = new Uint8Array(DriveApp.getFileById(TARGET_PDF_ID).getBlob().getBytes()); const { PDFDocument, StandardFonts, rgb, decodePDFRawStream, arrayAsString } = PDFLib; const pdfDoc = await PDFDocument.load(pdfData); const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica); const firstPage = pdfDoc.getPages()[0]; const { height } = firstPage.getSize(); // 解析并过滤页面内容流 const contentStreams = firstPage.node.getContents(); let updatedContent = []; for (const stream of contentStreams) { const decodedContent = arrayAsString(decodePDFRawStream(stream, pdfDoc.context)); // 过滤掉包含旧文本的指令行,替换成你实际的旧文本内容 const filteredContent = decodedContent.split('\n').filter(line => { return !line.includes('(This text was added with JavaScript)'); }).join('\n'); updatedContent.push(filteredContent); } // 清空原页面内容,写入过滤后的内容 firstPage.node.clearContents(); updatedContent.forEach(content => firstPage.node.addContent(content)); // 添加新文本 firstPage.drawText(`新的替换文本`, { x: 10, y: height - 10, size: 20, font: helveticaFont, color: rgb(0.95, 0.1, 0.1) }); const pdfBytes = await pdfDoc.save(); Drive.Files.update( { title: "newpdf from apps script v22", mimeType: "application/pdf" }, TARGET_PDF_ID, Utilities.newBlob(pdfBytes) ) }
注意:PDF的文本指令格式类似 BT /F1 20 Tf 10 770 Td (旧文本内容) Tj ET,如果旧文本有换行、旋转等格式,需要调整过滤条件。
内容的提问来源于stack exchange,提问作者Diego-31
相关产品推荐
相关产品推荐

