Введение
Вводный пост охватывает аннотации вкратце: выделения, подчеркивания, стикеры и штампы, добавляемые через 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 buildimport { 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');
Поддерживаемые форматы
| Формат | Расширение | Чтение | Запись |
|---|---|---|---|
| ✓ | ✓ | ||
| Markdown | md | ✓ | ✓ |
| SVG | svg | ✓ | ✓ |
| TIFF | tiff | ✓ | ✓ |
| DOCX | docx | — | ✓ |
| HTML | html | — | ✓ |
| PNG | png | — | ✓ |
| EPUB | epub | — | ✓ |
Открытый исходный код и лицензирование
Aspose.PDF FOSS для TypeScript выпущен под лицензией MIT, исходный код опубликован на GitHub. Нет водяного знака оценки, ограничения использования или отдельного файла лицензии для управления, и библиотеку можно использовать в коммерческих продуктах без роялти.
В настоящее время пакет имеет версию 0.1.0, что отражает активную раннюю стадию разработки. Node.js (>=22) является единственным требованием к среде выполнения, и у пакета нет других сторонних зависимостей.