Як працювати з анотаціями у TypeScript
У цьому посібнику показано, як додавати, сплющувати та шукати PDF-аннотації за допомогою Aspose.PDF FOSS для TypeScript. Клас Page надає один Add* метод для кожного підтипу анотації — розмітка (highlight, underline, strikeout, squiggly), форми (square, circle, line, polygon, ink), текст (sticky note, free text) і посилання — кожен з яких повертає типізований 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Перевірте встановлення, імпортуючи клас Document у новий файл TypeScript — цей рядок має успішно підвантажитися без помилок після встановлення пакету:
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), а не a rect — передача прямокутника з 4-м числами створює вироджений або відсутній квадр. Створюйте один квадр на кожному рядку виділеного тексту.
Сплющена анотація все ще клікабельна. Flatten() повинно бути викликано на об’єкті, який повертає Add* виклик, і документ повинен бути збережений (doc.WriteTo() / doc.Save()) після сплющення — зміна існує лише в пам’яті, доки файл не буде записаний назад.
SearchAnnotationText() повертає 0 результатів, хоча текст видимий на сторінці. Він шукає лише поля метаданих анотації (/Contents, /T, /Subj) — видимий розмічений текст, згенерований з власного вигляду анотації (наприклад, a FreeText body) знаходиться за SearchAnnotations() натомість, і не шукає звичайний вміст сторінки (використовуйте Page.GetText() or Page.Search() для цього).
Позначки редагування не відображаються під час пошуку анотацій. Page.AddRedact() створює RedactAnnotation, окремий підтип маркувань/форм/текстових анотацій, розглянутих тут — дивіться the Redaction довідник.
Часто задавані питання
Скільки підтипів анотацій підтримує Page?
Бібліотека генерує вигляди для розмітки (highlight, underline, strikeout, squiggly), форм (square, circle, line, polygon, ink), тексту (sticky note, free text), посилань і печаток — а також анотацій прикріплення файлів та redaction, які описані у їх власних how-to guides.
Чи можу я читати анотації, які вже існують на сторінці?
Так — Page.Annotations повертає існуючі анотації у вигляді масиву типізованих дескрипторів, які ви можете переглядати, редагувати або flatten, а Page.RemoveAnnotation(a) видаляє одну.
У чому різниця між flattening анотації та застосуванням redaction?
Flatten() вбудовує анотацію appearance на сторінку і видаляє об’єкт annotation, але будь-який текст або зображення під ним залишаються недоторканими. ApplyRedactions() деструктивно перезаписує потік вмісту, так що покритий контент зникає — дивіться Redaction guide для деталей.
Чи зберігаються анотації під час циклу збереження/відкриття?
Так — анотації, додані перед doc.WriteTo() / doc.Save(), записуються у PDF і правильно зчитуються під час наступного Document.Open() / Document.OpenFile().