如何为PDF嵌入未嵌入字体?寻求Node.js及工具解决方案
解决方案:PDF字体嵌入修复与替代方案
一、修复PDFlib的字体名称异常问题
你当前的代码仅为页面设置了新字体,但未处理原有文本的字体引用,且PDFlib默认会生成带后缀的字体名称。需通过以下步骤修复:
- 指定嵌入字体的自定义名称:在
embedFont时传入name参数,强制设置字体名称为目标名称(如'Arial')。 - 替换页面中所有未嵌入字体的引用:遍历页面的字体字典,将原有未嵌入字体的引用替换为新嵌入的字体。
修正后的代码示例:
const { PDFDocument } = require('pdf-lib'); const fs = require('fs'); const fontkit = require('@pdf-lib/fontkit'); async function embedFontsInPDF(inputPath, outputPath) { // 读取原始PDF const pdfBytes = fs.readFileSync(inputPath); const pdfDoc = await PDFDocument.load(pdfBytes); // 注册fontkit pdfDoc.registerFontkit(fontkit); // 嵌入Arial字体并指定名称 const arialFontBytes = fs.readFileSync('Arial.ttf'); const arialFont = await pdfDoc.embedFont(arialFontBytes, { name: 'Arial' }); // 遍历所有页面替换字体引用 const pages = pdfDoc.getPages(); pages.forEach(page => { const pageFonts = page.node.getFonts(); pageFonts.forEach(([fontRef]) => { // 替换未嵌入字体为新嵌入的Arial page.node.setFonts([[fontRef, arialFont.ref]]); }); // 设置页面默认字体 page.setFont(arialFont); }); // 保存处理后的PDF const modifiedPdfBytes = await pdfDoc.save(); fs.writeFileSync(outputPath, modifiedPdfBytes); } // 执行处理 embedFontsInPDF('input.pdf', 'output.pdf');
二、Ghostscript替代方案(推荐)
Ghostscript是处理PDF字体嵌入的成熟工具,支持批量处理、字体替换与强制嵌入,无需编写复杂代码:
1. 强制嵌入所有字体
执行以下命令即可将PDF中所有未嵌入字体嵌入:
gs -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dEmbedAllFonts=true -dSubsetFonts=false -sOutputFile=output.pdf input.pdf
-dEmbedAllFonts=true:强制嵌入所有使用的字体-dSubsetFonts=false:嵌入完整字体(若不需要子集化可保留)
2. 替换字体并嵌入(如用Arimo替代Arial)
- 创建字体映射文件
fontmap.txt,内容如下:
Arial /path/to/Arimo.ttf Arial-Bold /path/to/Arimo-Bold.ttf
- 执行命令时指定字体映射:
gs -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dEmbedAllFonts=true -sFONTMAP=fontmap.txt -sOutputFile=output.pdf input.pdf
3. 在Node.js中调用Ghostscript
通过child_process模块执行Ghostscript命令:
const { exec } = require('child_process'); function embedFontsWithGhostscript(inputPath, outputPath) { const command = `gs -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dEmbedAllFonts=true -dSubsetFonts=false -sOutputFile=${outputPath} ${inputPath}`; exec(command, (error, stdout, stderr) => { if (error) { console.error(`执行错误: ${error.message}`); return; } if (stderr) { console.error(`输出错误: ${stderr}`); return; } console.log('字体嵌入完成'); }); } // 执行处理 embedFontsWithGhostscript('input.pdf', 'output.pdf');
内容的提问来源于stack exchange,提问作者derikS4M1
相关产品推荐
相关产品推荐

