如何使用pdf-lib实现PDF链接在新浏览器标签页打开?
解决pdf-lib添加PDF链接在新标签页打开的问题
你遇到的问题是直接设置NewWindow: true不生效,原因是PDF规范要求这个属性必须是PDF布尔类型,而非普通JavaScript布尔值。pdf-lib需要你用PDFBool类包装该值,才能生成符合规范的PDF动作对象。
修改步骤:
- 先从pdf-lib库导入
PDFBool:
import { PDFBool } from 'pdf-lib';
- 在链接动作配置中,将
NewWindow: true替换为NewWindow: PDFBool.of(true):
修改后的核心代码片段(重点看A对象部分):
const linkAnnotation: PDFDict = pdfDoc.context.obj({ Type: "Annot", Subtype: "Link", Rect: [x, y - 10, x + 150, y + 10], Border: [0, 0, 0], C: [0, 0, 1], A: { Type: "Action", S: "URI", URI: PDFString.of(getTexts.link(item).trim()), NewWindow: PDFBool.of(true), // 用PDFBool包装布尔值 }, });
完整修改后的函数代码:
import { PDFBool } from 'pdf-lib'; // 新增导入 export const drawLink = ( x: number, y: number, item: TransformedEvent, haufefontSans: PDFFont, currentPage: PDFPage, pdfDoc: PDFDocument, linkImg: PDFImage ) => { if (getTexts.link(item).trim() === "nothing_to_link") { return y; } else { const linkAnnotation: PDFDict = pdfDoc.context.obj({ Type: "Annot", Subtype: "Link", Rect: [x, y - 10, x + 150, y + 10], Border: [0, 0, 0], C: [0, 0, 1], A: { Type: "Action", S: "URI", URI: PDFString.of(getTexts.link(item).trim()), NewWindow: PDFBool.of(true), // 修正此处 }, }); const linkAnnotationRef = pdfDoc.context.register(linkAnnotation); currentPage.drawText("mehr erfahren", { x: x + 18, y: y, size: 13, color: red, font: haufefontSans, }); currentPage.drawImage(linkImg, { x: x + 2, y: y - 2, width: 11, height: 11, }); y -= 13; let existingAnnots: PDFObject[] = []; const existingAnnotsObj = currentPage.node.get(PDFName.of("Annots")); if (existingAnnotsObj instanceof PDFArray) { existingAnnots = existingAnnotsObj.asArray().slice(); } else if (existingAnnotsObj) { existingAnnots.push(existingAnnotsObj); } existingAnnots.push(linkAnnotationRef); currentPage.node.set( PDFName.of("Annots"), pdfDoc.context.obj(existingAnnots) ); return y; } };
原理说明:
pdf-lib的context.obj()方法会将JavaScript值转换为对应PDF对象类型,但普通true会被错误解析为PDF名称或其他类型,而PDF规范中URI动作的NewWindow属性要求必须是PDF布尔对象。使用PDFBool.of(true)可生成符合规范的布尔值,让PDF阅读器(如浏览器内置阅读器)正确识别该参数,从而在新标签页打开链接。
内容的提问来源于stack exchange,提问作者Gurami Tchumburidze
相关产品推荐
相关产品推荐

