You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为PDF嵌入未嵌入字体?寻求Node.js及工具解决方案

解决方案:PDF字体嵌入修复与替代方案

一、修复PDFlib的字体名称异常问题

你当前的代码仅为页面设置了新字体,但未处理原有文本的字体引用,且PDFlib默认会生成带后缀的字体名称。需通过以下步骤修复:

  1. 指定嵌入字体的自定义名称:在embedFont时传入name参数,强制设置字体名称为目标名称(如'Arial')。
  2. 替换页面中所有未嵌入字体的引用:遍历页面的字体字典,将原有未嵌入字体的引用替换为新嵌入的字体。

修正后的代码示例:

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)

  1. 创建字体映射文件fontmap.txt,内容如下:
Arial /path/to/Arimo.ttf
Arial-Bold /path/to/Arimo-Bold.ttf
  1. 执行命令时指定字体映射:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 05:27:34