批注和表单
注释和表单
Aspose.PDF FOSS for .NET 为您提供对 PDF 注释
和交互式 AcroForm 字段的完整读写访问。注释的主要入口点是Page.Annotations(一个 AnnotationCollection),而表单字段通过Document.Form 访问。两个子系统完全在内存中工作,无需
许可证密钥。
添加注释
AnnotationCollection 为每种标准注释类型公开了强类型的帮助方法。每个方法接受一个 Rectangle,用于定义页面上的注释位置,并附加特定类型的参数。
using var doc = Document.Open(pdfBytes);
var page = doc.Pages[1];
// Text (sticky-note) annotation
page.Annotations.AddTextAnnotation(
new Rectangle(72, 720, 200, 740),
contents: "Review this paragraph",
title: "Editor",
open: true);
// Highlight annotation
page.Annotations.AddHighlightAnnotation(
new Rectangle(72, 680, 300, 700),
quadPoints: null,
color: new double[] { 1, 1, 0 });
// Free-text annotation (rendered directly on the page)
page.Annotations.AddFreeTextAnnotation(
new Rectangle(72, 640, 350, 660),
contents: "Inline note",
fontName: "Helvetica",
fontSize: 10,
color: new double[] { 0, 0, 0 });
using var ms = new MemoryStream();
doc.Save(ms);链接注释和操作
链接将可点击的矩形与PdfAction结合。
该库支持 URI、GoTo、JavaScript、Named 和 Launch 操作。
using var doc = Document.Open(pdfBytes);
var page = doc.Pages[1];
// URI link
var uriAction = PdfAction.CreateUri("https://aspose.com");
page.Annotations.AddLinkAnnotation(
new Rectangle(50, 700, 200, 720), uriAction);
// GoTo link (jump to page 3)
page.Annotations.AddLinkAnnotation(
new Rectangle(50, 660, 200, 680),
destinationPage: 3,
destRect: new Rectangle(0, 0, 612, 792));
// JavaScript link
var jsAction = PdfAction.CreateJavaScript("app.alert('Hello');");
page.Annotations.AddLinkAnnotation(
new Rectangle(50, 620, 200, 640), jsAction);
doc.Save("links.pdf");要在打开已保存的 PDF 后读取链接,请将注释强制转换为 LinkAnnotation 并检查其 Uri 属性,或通过 PdfAction.Create 解析操作字典。
标记和形状注释
标记注释(高亮、下划线、删除线)标记现有文本。形状注释(方形、圆形、线条、墨迹)在页面上绘制几何图形。
var page = doc.Pages[1];
// Underline
page.Annotations.AddUnderlineAnnotation(
new Rectangle(72, 600, 300, 620),
quadPoints: null,
color: new double[] { 1, 0, 0 });
// Square
page.Annotations.AddSquareAnnotation(
new Rectangle(72, 540, 200, 580),
borderColor: new double[] { 0, 0, 1 },
fillColor: null,
lineWidth: 1.5);
// Line
page.Annotations.AddLineAnnotation(
new Rectangle(72, 500, 300, 520),
x1: 72, y1: 510, x2: 300, y2: 510,
color: new double[] { 0, 0.5, 0 },
lineWidth: 2);
// Ink (freehand)
page.Annotations.AddInkAnnotation(
new Rectangle(72, 440, 200, 480),
inkPaths: new[] { new double[] { 80, 450, 120, 470, 160, 450 } },
color: new double[] { 0.5, 0, 0.5 },
lineWidth: 1);印章批注
Stamp 注释在页面上覆盖图像或预定义图标。
var stamp = new StampAnnotation(doc);
// Configure stamp properties, then add to page
page.Annotations.Add(stamp);扁平化注释
对任意批注调用 Flatten() 将其视觉外观烧录到页面内容流中,并将其从交互式批注列表中移除。
foreach (var annot in doc.Pages[1].Annotations)
{
annot.Flatten();
}使用 AnnotationSelector 的访问者模式
AnnotationSelector 实现了访问者模式,使您能够按类型过滤注释,而无需手动强制转换。
var selector = new AnnotationSelector();
doc.Pages[1].Accept(selector);
// selector.Selected now contains all annotations on page 1
foreach (var annot in selector.Selected)
{
// Process each annotation by type
}将已键入的注释实例传递给构造函数,以仅过滤该类型:
var linkFilter = new AnnotationSelector(new LinkAnnotation(page, Rectangle.Empty));
page.Accept(linkFilter);
// linkFilter.Selected contains only LinkAnnotation instances交互式表单字段
通过 Document.Form 访问 AcroForm 字段。Form 类公开字段级的读/写操作,并支持 JSON 导出。
using var doc = Document.Open(pdfBytes);
// Enumerate all fields
foreach (var field in doc.Form.Fields)
{
Console.WriteLine($"{field.FullName}: {field.Value}");
}Field 子类包括 TextBoxField、CheckboxField、RadioButtonField,
ComboBoxField、ListBoxField、ChoiceField和 SignatureField。
将表单数据导出为 JSON
WidgetAnnotation 提供 ExportToJson 重载,用于将字段数据序列化到流或文件路径。可选的 ExportFieldsToJsonOptions 参数控制输出格式。
using var doc = Document.Open(pdfBytes);
var widget = (WidgetAnnotation)doc.Pages[1].Annotations[1];
using var jsonStream = new MemoryStream();
widget.ExportToJson(jsonStream);技巧和最佳实践
- 始终在 PDF 用户空间单位(1/72 英寸)中指定明确的
Rectangle坐标。 - 使用
AddLinkAnnotation与PdfAction以获得最大灵活性——支持 URI、GoTo、JavaScript 和命名操作。 - 在分发 PDF 之前调用
Flatten(),如果希望注释在非交互式查看器中显示。 - 通过
Document.Form.Fields访问表单字段,而不是遍历页面注释——表单集合会处理跨页字段分组。 - 保存并重新打开文档以验证注释的往返完整性,尤其是自定义操作。
常见问题
| Issue | Cause | Fix |
|---|---|---|
| 保存后注释不可见 | 矩形面积为零或超出页面边界 | 验证坐标位于页面范围内 MediaBox |
LinkAnnotation.Uri 返回 null | 链接使用 GoTo 或 JavaScript 动作,而不是 URI 动作 | 通过 PdfAction.Create 解析动作字典,并检查 ActionType |
| 表单字段值为空字符串 | 字段存在但没有 /V 条目 | 在处理前检查 field.Value 不为 null |
Flatten() 抛出异常 | 注释没有 /P(页面)引用 | 确保注释是通过 Page.Annotations 添加的 |
常见问题
如何向 PDF 页面添加超链接?
使用 page.Annotations.AddLinkAnnotation(rect, PdfAction.CreateUri(url)) 在指定的矩形区域创建可点击的 URI 链接。
我可以读取现有 PDF 中的表单字段值吗?
是的。使用 Document.Open 打开文档,然后遍历 Document.Form.Fields 并读取每个 Field 上的 Value 属性。
该库支持哪些注释类型?
该库支持文本、自由文本、链接、突出显示、下划线、删除线,
方框、圆形、线条、墨迹、印章、插入符、文件附件、声音、多边形,
折线、小部件、水印以及 3D 注释。所有类型均可通过AnnotationCollection 辅助方法或直接构造获得。
我如何按类型过滤注释?
使用 AnnotationSelector 与类型化模板注释。调用 page.Accept(selector)
并检查 selector.Selected 以匹配注释。
我可以只展平特定的注释吗?
是的。对各个 Annotation 实例调用 Flatten(),而不是遍历整个集合。
API 参考摘要
| Class / Method | Description |
|---|---|
AnnotationCollection | 在每个 Page 上的强类型集合;为所有注释类型提供 Add* 辅助方法 |
AnnotationCollection.AddTextAnnotation | 添加便签注释 |
AnnotationCollection.AddLinkAnnotation | 添加带有 URI、页面目标或自定义操作的链接 |
AnnotationCollection.AddHighlightAnnotation | 添加文本高亮注释 |
AnnotationCollection.AddInkAnnotation | 添加自由手绘注释 |
AnnotationCollection.AddSquareAnnotation | 添加矩形形状注释 |
AnnotationCollection.AddCircleAnnotation | 添加椭圆形状注释 |
AnnotationCollection.AddLineAnnotation | 添加线条注释 |
Annotation.Flatten | 将注释外观烘焙到页面内容中 |
Annotation.Accept | 分派到强类型的 AnnotationSelector.Visit 重载 |
AnnotationSelector | 按类型收集注释的访问者 |
LinkAnnotation | 携带 URI 或操作的注释子类 |
TextAnnotation | 便签注释 |
InkAnnotation | 带有笔画路径的自由手绘注释 |
StampAnnotation | 图像或图标覆盖注释 |
WidgetAnnotation.ExportToJson | 将表单字段数据序列化为 JSON |
Form | AcroForm 外观;枚举并操作字段 |
Field | 表单字段的基类(TextBoxField、CheckboxField 等) |
CheckboxField | 复选框表单字段 |
TextBoxField | 单行/多行文本输入字段 |
ComboBoxField | 下拉选择字段 |
RadioButtonField | 单选按钮组字段 |
AnnotationType | 注释种类的枚举 |
PdfAction.CreateUri | URI 链接操作的工厂 |
PdfAction.CreateJavaScript | JavaScript 操作的工厂 |