Introducción

El post introductorio cubre brevemente las anotaciones: resaltados, subrayados, notas adhesivas y sellos, añadidos mediante Page.AddHighlight(), Page.AddUnderline() y métodos similares. Eso es solo una pequeña parte de lo que realmente admite un Page — la galería de anotaciones en esta biblioteca cubre marcado, formas a mano alzada, enlaces con navegación real y acciones de envío de formularios, y búsqueda, todo accesible directamente desde Page.

Esta publicación recorre el resto de esa superficie: los métodos de anotación de forma y a mano alzada, lo que realmente puede hacer la acción de una anotación Link, y las dos formas diferentes de buscar contenido de anotaciones dependiendo de si el texto que buscas está en la apariencia de la anotación o en su /Contents comentario.

Cada método de anotación devuelve un manejador tipado limitado a la anotación que acaba de crear, y cada anotación en una página es legible posteriormente a través de page.Annotations.


Qué incluye

Anotaciones de marcado

Page.AddHighlight(), Page.AddUnderline(), Page.AddSquiggly() y Page.AddStrikeOut() aceptan la misma forma de opciones — un conjunto de puntos cuádruples que marcan la región de texto y un color opcional — y los cuatro devuelven un MarkupAnnotation. Los puntos cuádruples suelen derivarse de una búsqueda de texto o de un rectángulo de texto conocido.

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] }));

Notas y Texto Independiente

Page.AddTextNote() agrega un ícono clásico de sticky-note que abre una ventana emergente de comentario al hacer clic, devolviendo un TextAnnotation. Page.AddFreeText() en su lugar dibuja su texto directamente en la página dentro de un cuadro con borde, con su propio tamaño de fuente, alineación y color de relleno — útil para llamadas de atención que deben ser visibles sin abrir nada.

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,
});

Formas y Tinta a Mano Alzada

Page.AddSquare() y Page.AddCircle() dibujan un rectángulo o elipse con borde, cada uno con un relleno interior opcional. Page.AddLine() dibuja una línea recta entre dos puntos, con estilos de punta de flecha seleccionables de forma independiente (startEnding/endEnding, p.ej. 'OpenArrow'/'ClosedArrow') en cada extremo. Page.AddPolygon() y Page.AddPolyline() dibujan formas multi-punto cerradas y abiertas a partir de una lista plana de coordenadas, y Page.AddInk() registra una o más trazos de lápiz a mano alzada como paths de listas de puntos.

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 });

Enlaces y Sus Acciones

Page.AddLink() devuelve un LinkAnnotation cuyo action decide qué ocurre al hacer clic: { type: 'uri', uri: '...' } abre una URL externa, { type: 'goto', page: N } salta a una página dentro del mismo documento, y { type: 'submit', url: '...', format: 'html' } envía los valores actuales de los campos del formulario a un endpoint. Un número de página goto fuera de rango o un objeto de acción malformado es rechazado en el momento de la creación en lugar de ser aceptado silenciosamente.

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.

Buscar Contenido de Anotaciones

Dos métodos diferentes buscan el texto de la anotación, y son deliberadamente disjuntos: Page.SearchAnnotations() busca el texto de la propia aparición de una anotación dibuja — la etiqueta visible en un FreeText o sello, por ejemplo — mientras Page.SearchAnnotationText() busca el texto que lleva la anotación /Contents entrada, como el cuerpo del comentario de una nota adhesiva. Una coincidencia en una no implica una coincidencia en la otra.

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

Las anotaciones que ya no se necesiten pueden eliminarse directamente con Page.RemoveAnnotation(), pasando ya sea el identificador de la anotación o su diccionario subyacente.


Inicio rápido

Instala el paquete y luego agrega un resaltado, un enlace y una nota adhesiva a una página existente:

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');

Formatos compatibles

FormatoExtensiónLeerEscribir
PDFpdf✓✓
Markdownmd✓✓
SVGsvg✓✓
TIFFtiff✓✓
DOCXdocx—✓
HTMLhtml—✓
PNGpng—✓
EPUBepub—✓

Código abierto y licencias

Aspose.PDF FOSS para TypeScript se publica bajo la licencia MIT, con el código fuente disponible en GitHub. No hay marca de agua de evaluación, límite de uso ni archivo de licencia separado que gestionar, y la biblioteca puede usarse en productos comerciales sin regalías.

El paquete está actualmente en la versión 0.1.0, lo que refleja un desarrollo activo en una etapa temprana. Node.js (>=22) es el único requisito de tiempo de ejecución, y el paquete no tiene otras dependencias de terceros.


Comenzando

Recursos relacionados