Wie man mit PDF-Struktur in TypeScript arbeitet
Dieser Leitfaden zeigt, wie man die Dokumentennavigation und logische Struktur in PDF-Dateien mit Aspose.PDF FOSS für TypeScript erstellt: ein anklickbares Inhaltsverzeichnis auf einer Seite, ein Lesezeichen-Umriss auf Dokumentebene, benannte Ziele und einen getaggten Strukturbaum für Barrierefreiheit. Er erfordert Node.js 22 oder neuer.
Schritt-für-Schritt-Anleitung
Schritt 1: Paket installieren
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Überprüfen Sie die Installation, indem Sie die Document-Klasse in einer neuen TypeScript-Datei importieren — diese Zeile sollte ohne Fehler aufgelöst werden, sobald das Paket installiert ist:
import { Document } from '@asposefoss/pdf';Schritt 2: Erforderliche Klassen importieren
Importieren Sie Document, um die Datei zu öffnen, und OutlineItem für die Lesezeicheneinträge, die in Schritt 4 erstellt wurden:
import { Document, OutlineItem } from '@asposefoss/pdf';Schritt 3: Inhaltsverzeichnis hinzufügen
Page.AddTOC() nimmt ein Array von { title, page }-Einträgen, ein begrenzendes rect und Stiloptionen; es zeichnet gepunktete Führungsstriche und anklickbare Links zu den Zielseiten:
const page = doc.Pages[0];
page.AddTOC(
[
{ title: '1. Introduction', page: 2 },
{ title: '2. Methodology', page: 5 },
{ title: '3. Results', page: 9 },
],
[72, 160, 400, 600],
{ font: 'Helvetica', fontSize: 13, color: [0.1, 0.1, 0.15], rowGap: 18 },
);Schritt 4: Lesezeichen hinzufügen
Document.SetOutlines() ersetzt das Lesezeichen-Panel des Dokuments durch ein Array von OutlineItem-Objekten. Jeder Eintrag kann ein Dest (Seitenziel), Stilinformationen (Color, Bold) und ein verschachteltes Children für einen zusammenklappbaren Baum enthalten:
const items: OutlineItem[] = [
{ Title: 'Sales', Dest: { name: 'section.sales' }, Open: true, Color: [0.1, 0.4, 0.1] },
{ Title: 'Appendix', Dest: { name: 'section.appendix' } },
];
doc.SetOutlines(items);Schritt 5: Gliederungen und benannte Ziele auslesen
Document.GetOutlines() gibt den aktuellen Lesezeichenbaum zurück. Document.GetNamedDestinations() gibt jedes im Dokument registrierte benannte Ziel zurück – nützlich, um zu überprüfen, dass jedes Gliederungsziel und jeder Inhaltsverzeichnis-Link tatsächlich zu einer realen Seite aufgelöst wird:
const destNames = new Set(doc.GetNamedDestinations().map((d) => d.name));
const walk = (nodes: OutlineItem[]): void => {
for (const item of nodes) {
if (item.Dest && 'name' in item.Dest) {
console.log(destNames.has(item.Dest.name), item.Title);
}
if (item.Children) walk(item.Children);
}
};
walk(doc.GetOutlines());Schritt 6: Einen getaggten Strukturbaum erstellen
Document.GetStructTree() gibt den vorhandenen Strukturbaum zurück (oder null, wenn das Dokument nicht getaggt wurde). StructTreeRoot.Append(tag) fügt ein Kindelement wie 'H2' oder 'P' hinzu und gibt ein StructElement zurück, und StructElement.MarkContent(page, quad) verknüpft dieses Element mit dem Seiteninhalt, den es beschreibt:
function tagPage(doc: Document, page: Page, headingText: string): void {
const root = doc.GetStructTree();
if (!root) throw new Error('tagPage: the document is not tagged yet');
for (const block of page.GetStructuredText()) {
const text = block.text.trim();
if (text.length === 0) continue;
const el = root.Append(text.startsWith(headingText) ? 'H2' : 'P');
el.MarkContent(page, block.quad);
}
}Häufige Probleme und Lösungen
Document.GetStructTree() returns null. Das Dokument wurde noch nicht markiert — rufen Sie Document.CreateStructTree() (oder Document.AutoTag()) bevor Sie Elemente per Hand erstellen mit StructTreeRoot.Append() / StructElement.MarkContent().
Ein Gliederungspunkt springt nicht zur richtigen Seite. OutlineItem.Dest muss ein tatsächlich existierendes Ziel benennen — prüfen Sie item.Dest.name against Document.GetNamedDestinations() vor dem Speichern, wie in Schritt5 gezeigt.
Page.AddTOC() Einträge verweisen auf die falsche Seite. page in jedem Inhaltsverzeichnis-Eintrag ist die eigene Seitenzahl der Zielseite — überprüfen Sie sie gegen page.Number auf das tatsächliche Ziel Page, nicht ein angenommener Array-Index.
Lesezeichen verschwinden nach einem späteren Document.SetOutlines() Aufruf. SetOutlines() ersetzt den gesamten Lesezeichenbaum — lesen Sie den aktuellen Baum mit Document.GetOutlines() zuerst das Array ändern, dann das gesamte Array zurückgeben, wenn Lesezeichen hinzugefügt werden, anstatt sie zu ersetzen.
Häufig gestellte Fragen
Kann ein Lesezeichen bereits erweitert geöffnet werden?
Ja — setzen Sie Open: true auf dem OutlineItem, damit die Kinder dieses Knotens standardmäßig im Lesezeichen-Panel sichtbar sind.
Was ist der Unterschied zwischen einem Lesezeichen und einem benannten Ziel?
Ein Lesezeichen (OutlineItem) ist ein sichtbarer Eintrag im Navigations-Panel; ein benanntes Ziel (Document.GetNamedDestinations() / SetNamedDestination()) ist ein internes, wiederverwendbares Seitenziel, auf das ein Lesezeichen, ein Inhaltsverzeichnis-Eintrag oder eine Link-Annotation verweisen können.
Beeinflusst das Taggen eines Dokuments das Aussehen?
Nein — ein Strukturbaum (StructTreeRoot, StructElement) ist eine parallele logische Ebene, die Lesereihenfolge und Semantik beschreibt; er ändert nicht den sichtbaren Inhalt der Seite.
Kann ich Lesezeichen verschachteln?
Ja — setzen Sie Children auf einem OutlineItem auf ein Array weiterer OutlineItem-Objekte, um einen zusammenklappbaren, mehrstufigen Baum zu erstellen.