使用pdf-lib处理PDF文本框字体族与字号问题求助
解决pdf-lib设置PDF文本框字体族和字号异常的问题
问题原因分析
你的代码存在两个核心问题,导致字体和字号显示异常:
- 硬编码字体名称
/F3,但PDF文档中字体的内部标识是动态分配的,这个值不一定对应你嵌入的Arial Bold字体,最终会引用到默认的Courier字体。 - 默认外观字符串未指定有效字号,仅写了
0,PDF阅读器会自动使用大字号渲染内容。
修正后的代码
const { PDFDocument, StandardFonts } = require("pdf-lib"); const { join } = require("path"); const fs = require("fs"); const fontkit = require('@pdf-lib/fontkit'); // 确保已安装该依赖 // 遍历表单数组 for (const iterator of forms) { let formName = iterator.url; const source = join(__dirname, `../public/forms/${formName}.pdf`); const pdfData = fs.readFileSync(source); const pdfDoc = await PDFDocument.load(pdfData); pdfDoc.registerFontkit(fontkit); const fontFile = join(__dirname, '../ARIALBD.TTF'); const fontBytes = fs.readFileSync(fontFile); const font = await pdfDoc.embedFont(fontBytes); const fontName = font.getName(); // 获取嵌入字体的动态内部名称 const formSchema = pdfDoc.getForm(); const fields = formSchema.getFields(); fields.forEach((field) => { if (field.constructor.name === "PDFTextField") { const textField = formSchema.getTextField(field.getName()); textField.setText("sample text"); // 提取原字段的字号,保持和原表单样式一致;无匹配则用默认12号 const originalDA = textField.acroField.getDefaultAppearance(); const fontSizeMatch = originalDA.match(/(\d+) Tf/); const fontSize = fontSizeMatch ? fontSizeMatch[1] : "12"; // 设置正确的默认外观:动态字体名+字号+黑色文字 textField.acroField.setDefaultAppearance(`/${fontName} ${fontSize} Tf 0 g`); } }); const pdfBytes = await pdfDoc.save(); const des = join(destination, `${docName.join("_")}.pdf`); // 用join处理路径更安全 fs.writeFileSync(des, pdfBytes); }
关键修改说明
- 动态获取字体名称:通过
font.getName()拿到当前PDF中嵌入字体的真实标识,避免硬编码导致的字体引用错误。 - 继承或指定字号:从原字段的默认外观中提取字号,保证和原表单样式统一;也可直接指定固定字号,解决字号过大问题。
- 变量作用域优化:给
textField添加const声明,避免全局变量污染。 - 路径处理优化:用
join拼接目标路径,避免不同系统的路径分隔符问题。
额外注意事项
- 确保已安装
@pdf-lib/fontkit:执行npm install @pdf-lib/fontkit完成依赖安装。 - 若原表单文本框有特殊格式(如颜色、对齐),可在
setDefaultAppearance中保留对应参数,比如原样式是红色文字,就改成/${fontName} ${fontSize} Tf 1 0 0 rg。
内容的提问来源于stack exchange,提问作者omkar p
相关产品推荐
相关产品推荐

