如何在 TypeScript 中使用注解
本指南展示了如何使用 Aspose.PDF FOSS 为 TypeScript 添加、扁平化和搜索 PDF 批注。Page 类为每种批注子类型公开一个 Add* 方法——标记(高亮、下划线、删除线、波浪线)、形状(方形、圆形、直线、多边形、墨迹)、文本(粘性便签、自由文本)和链接——每个方法返回一个已类型化的 Annotation 句柄,可在以后读取或进行扁平化。它需要 Node.js 22 或更高版本。
分步指南
步骤 1:安装软件包
git clone https://github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-TypeScript.git
cd Aspose.PDF-FOSS-for-TypeScript
npm install
npm run build通过在新的 TypeScript 文件中导入 Document 类来验证安装——一旦软件包安装完成,此行代码应能够解析且不报错:
import { Document } from '@asposefoss/pdf';步骤 2:导入所需类
导入 Document 以打开文件,并 Page 用于下面步骤中使用的注释类型签名:
import { Document, Page } from '@asposefoss/pdf';步骤 3:添加标记注释
Page.AddHighlight()、Page.AddUnderline()、Page.AddSquiggly() 和 Page.AddStrikeOut() 都接受一个 quads 数组——每个高亮文本区域对应一个 8 位数字四元组(x1,y1,x2,y2,x3,y3,x4,y4)——以及一个 color 和可选的 contents。库会自动为所有四种子类型生成外观流(/AP):
import { Document } from '@asposefoss/pdf';
const doc = Document.OpenFile('input.pdf');
const page = doc.Pages[0];
page.AddHighlight({
quads: [72, 700, 300, 700, 72, 685, 300, 685],
color: [1, 1, 0],
contents: 'Yellow highlight',
});
page.AddUnderline({
quads: [72, 660, 300, 660, 72, 645, 300, 645],
color: [0, 0, 1],
});
page.AddStrikeOut({
quads: [72, 620, 300, 620, 72, 605, 300, 605],
color: [1, 0, 0],
});
doc.WriteTo('annotated.pdf');步骤 4:添加形状和墨迹注释
Page.AddSquare() 和 Page.AddCircle() 接受一个边界 rect 加上 color(描边)和可选的 fill。Page.AddLine() 接受一个 4 位数字的 line(x1,y1,x2,y2)以及可选的箭头结束。Page.AddInk() 接受 paths——一个平面点对数组的数组,每个笔画对应一个:
page.AddSquare({ rect: [100, 500, 220, 560], color: [0.8, 0, 0], fill: [1, 1, 0.5], width: 2 });
page.AddCircle({ rect: [250, 500, 370, 560], color: [0, 0.5, 0], width: 2 });
page.AddLine({
line: [100, 470, 370, 470],
color: [0, 0, 0.7],
width: 2,
startEnding: 'OpenArrow',
endEnding: 'ClosedArrow',
});
page.AddInk({
paths: [[100, 400, 130, 430, 160, 390, 190, 420]],
color: [0.6, 0, 0.6],
width: 2,
});步骤 5:添加便签和自由文本
Page.AddTextNote() 放置一个可点击的图标,打开评论弹窗。Page.AddFreeText() 在页面上直接绘制文本,位于其 rect 中:
page.AddTextNote({
rect: [400, 700, 420, 720],
icon: 'Note',
author: 'Reviewer',
contents: 'This is a sticky-note annotation.',
});
page.AddFreeText({
rect: [400, 600, 550, 660],
contents: 'FreeText sample',
fontSize: 10,
align: 'center',
fill: [1, 1, 0.8],
width: 1,
});步骤 6:将注释展平为静态内容
每个由 Add* 调用返回的注释句柄都有一个 Flatten() 方法,该方法将注释的外观烘焙到页面的内容流中并从 /Annots 中移除。扁平化后,查看器中将不再剩余任何可点击或可编辑的内容:
const note = page.AddFreeText({
rect: [210, 535, 470, 590],
contents: 'Sticky note — flattened into the page.',
fontSize: 11,
align: 'left',
});
note.Flatten(); // -> boolean; bakes the annotation, unwires itself from /Annots
步骤 7:搜索注释文本
Page.SearchAnnotationText() and Page.SearchAnnotations() 在两个方向上互不相交: SearchAnnotationText() 匹配文字注释元数据 (/Contents, /T, /Subj) SearchAnnotations() 匹配 rendered 标记注释的文本,例如 FreeText:
const metadataHits = page.SearchAnnotationText('confidential');
for (const hit of metadataHits) {
console.log(hit.key, hit.value); // e.g. 'Contents', 'confidential'
}
const renderedHits = page.SearchAnnotations('confidential');
console.log(renderedHits.length);常见问题及解决方案
Page.AddHighlight() (或其他标记方法) 在错误的位置绘制。 quads 是一个 8 元平面数组 (x1,y1,x2,y2,x3,y3,x4,y4),而不是 rect — 传入一个四数字矩形会产生退化或缺失的四边形。为每行高亮文本构建一个四边形。
扁平化的注释仍然可以点击。 Flatten() 必须在由以下返回的对象上调用 Add* 调用,并且文档必须保存(doc.WriteTo() / doc.Save())在扁平化之后——更改仅存在于内存中,直到文件被写回。
SearchAnnotationText() 即使页面上可见文本,也返回无匹配。 它仅搜索注释元数据字段(/Contents, /T, /Subj)——可见的标记文本由注释自身的外观渲染(例如 a FreeText body) 被发现于 SearchAnnotations() 而不是,而且也不搜索普通页面内容(使用 Page.GetText() or Page.Search() 用于此).
遮蔽标记在搜索批注时不会出现。 Page.AddRedact() 创建一个 RedactAnnotation,一种与此处覆盖的标记/形状/文本批注不同的子类型 — 请参见 Redaction 指南。
常见问题
Page 支持多少种批注子类型?
该库为 markup(highlight、underline、strikeout、squiggly)、shapes(square、circle、line、polygon、ink)、text(sticky note、free text)、links 和 stamps 生成外观 — 另外还有文件附件和遮蔽批注,这些在各自的使用指南中有介绍。
我可以读取页面上已存在的批注吗?
是的 — Page.Annotations 将现有批注作为一个已键入句柄数组返回,您可以检查、编辑或扁平化,而 Page.RemoveAnnotation(a) 则删除其中一个。
将批注扁平化与应用遮蔽之间有什么区别?
Flatten() 为批注的 appearance 嵌入页面并移除注释对象,但其下方的任何文本或图像内容保持不变。 ApplyRedactions() 以破坏性方式重写内容流,导致被覆盖的内容本身消失——请参阅编辑指南了解详情。
在保存/打开的往返过程中,注释会被保留吗?
是的——在 doc.WriteTo() / doc.Save() 之前添加的注释会写入 PDF,并在下一个 Document.Open() / Document.OpenFile() 时正确读取。