介绍

这篇介绍性文章简要概述了批注:高亮、下划线、便利贴和印章,这些批注可通过Page.AddHighlight()、Page.AddUnderline()以及类似方法添加。这只是 Page 实际支持功能的一小部分——本库中的批注画廊涵盖了标记、手绘形状、具有真实导航和表单提交操作的链接以及搜索,所有这些都可直接从 Page 访问。

本文将继续探讨其余内容:形状和手绘批注方法、Link 批注的操作实际上可以做什么,以及根据要查找的文本是位于批注的外观还是其 /Contents 注释中而采用的两种不同的批注内容搜索方式。

每种批注方法都会返回一个限定在刚创建的批注范围内的类型化句柄,页面上的每个批注随后都可以通过 page.Annotations 读取。


包含内容

标记批注

Page.AddHighlight()、Page.AddUnderline()、Page.AddSquiggly() 和 Page.AddStrikeOut() 都采用相同形式的选项——一组标记文本区域的四点坐标以及可选的颜色——并且这四者都返回一个 MarkupAnnotation。四点坐标通常来源于文本搜索或已知的文本矩形。

const markup = (body: [number, number, number, number], sample: string,
  add: (quads: number[]) => void): void => {
  const yMid = (body[1] + body[3]) / 2 - 6;
  const textRect: [number, number, number, number] = [body[0] + 4, yMid, body[2] - 4, yMid + 16];
  page.AddText(sample, textRect[0], textRect[1], { fontSize: 12 });
  add(rectToQuads(textRect));
};

markup(cardBody, 'Highlight this phrase', (quads) =>
  page.AddHighlight({ quads, color: [1, 1, 0], contents: 'Yellow highlight' }));
markup(cardBody, 'Underline this phrase', (quads) =>
  page.AddUnderline({ quads, color: [0, 0, 1] }));
markup(cardBody, 'Squiggle this phrase', (quads) =>
  page.AddSquiggly({ quads, color: [1, 0.5, 0] }));
markup(cardBody, 'Strike this phrase out', (quads) =>
  page.AddStrikeOut({ quads, color: [1, 0, 0] }));

注释和独立文本

Page.AddTextNote() 添加一个经典的便利贴图标,点击后会打开评论弹出框,并返回一个 TextAnnotation。Page.AddFreeText() 则直接在页面上绘制文本,置于带边框的框内,拥有自己的字体大小、对齐方式和填充颜色——适用于无需打开任何东西即可看到的标注。

page.AddTextNote({
  rect: [x, y, x + 20, y + 20], icon: 'Note', author: 'Reviewer',
  contents: 'This is a sticky-note annotation.',
});

page.AddFreeText({
  rect: [220, 60, 520, 96],
  contents: 'FreeText sample', fontSize: 10, align: 'center',
  fill: [1, 1, 0.8], width: 1,
});

形状和手绘墨迹

Page.AddSquare() 和 Page.AddCircle() 绘制带边框的矩形或椭圆,可选内部填充。Page.AddLine() 在两点之间绘制直线,且两端的箭头样式可独立选择(startEnding/endEnding,例如 'OpenArrow'/'ClosedArrow')。Page.AddPolygon() 和 Page.AddPolyline() 从平面坐标列表绘制闭合或开放的多点形状,而 Page.AddInk() 将一个或多个手绘笔画记录为 paths 的点列表。

page.AddSquare({ rect: [50, 400, 130, 435], color: [0.8, 0, 0], fill: [1, 1, 0.5], width: 2 });
page.AddCircle({ rect: [150, 400, 230, 435], color: [0, 0.5, 0], width: 2 });

page.AddLine({
  line: [260, 417, 420, 417],
  color: [0, 0, 0.7], width: 2,
  startEnding: 'OpenArrow', endEnding: 'ClosedArrow',
});

const stroke: number[] = [];
[-8, 6, -4, 10, -2, 8, -6].forEach((dy, i) => stroke.push(440 + i * 12, 417 + dy));
page.AddInk({ paths: [stroke], color: [0.6, 0, 0.6], width: 2 });

链接及其行为

Page.AddLink() 返回一个 LinkAnnotation,其 action 决定点击时的行为:{ type: 'uri', uri: '...' } 打开外部 URL,{ type: 'goto', page: N } 跳转到同一文档中的页面,{ type: 'submit', url: '...', format: 'html' } 将当前表单字段值提交到端点。超出范围的 goto 页码或格式错误的动作对象将在创建时被拒绝,而不是悄悄接受。

const uriLink = page.AddLink({
  rect: [10, 10, 100, 30], action: { type: 'uri', uri: 'https://example.com' },
});

const gotoLink = page.AddLink({
  rect: [10, 40, 100, 60], action: { type: 'goto', page: 2 },
});

const submitLink = page.AddLink({
  rect: [10, 70, 100, 90],
  action: { type: 'submit', url: 'https://example.com/post', format: 'html' },
});

// page.AddLink({ rect: [...], action: { type: 'goto', page: 99 } }) throws RangeError
// when 99 is out of range for the document.

搜索批注内容

两种不同的方法搜索注释文本,它们是刻意互不重叠的: Page.SearchAnnotations() 搜索注释自身出现的文本 绘制 — 在…上可见的标签 FreeText 或印章,例如 — 而 Page.SearchAnnotationText() 搜索注释中携带的文本 /Contents 条目,例如便利贴的评论正文。一个匹配并不意味着另一个也匹配。

page.SearchAnnotations('bravo');          // finds it if the annotation's drawn appearance contains it
page.SearchAnnotationText('bravo');       // finds it if the annotation's /Contents comment contains it

不再需要的注释可以直接使用 Page.RemoveAnnotation() 删除,传入注释句柄或其底层字典即可。


快速开始

安装该包后,向现有页面添加高亮、链接和便签:

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
import { Document } from '@asposefoss/pdf';

const doc = Document.OpenFile('input.pdf');
const page = doc.Pages[0];

page.AddHighlight({ quads: [72, 700, 300, 700, 72, 715, 300, 715], color: [1, 1, 0] });

page.AddLink({
  rect: [72, 670, 200, 690], action: { type: 'uri', uri: 'https://example.com' },
});

page.AddTextNote({
  rect: [320, 670, 340, 690], icon: 'Note', author: 'Reviewer',
  contents: 'Please double-check this figure.',
});

doc.WriteTo('annotated.pdf');

支持的格式

格式扩展读取写入
PDFpdf✓✓
Markdownmd✓✓
SVGsvg✓✓
TIFFtiff✓✓
DOCXdocx—✓
HTMLhtml—✓
PNGpng—✓
EPUBepub—✓

开源与许可

Aspose.PDF FOSS for TypeScript 在 MIT 许可证下发布,源码已发布在 GitHub。没有评估水印、使用限制或需要管理的单独许可证文件,且该库可在商业产品中免费使用,无需版税。

该包当前版本为 0.1.0,体现了积极的早期开发阶段。Node.js (>=22) 是唯一的运行时要求,且该包没有其他第三方依赖。


入门

相关资源