PDFs im Browser erstellen, bearbeiten und anzeigen
Unsere Demo generiert ein PDF-Dokument im Browser. Es werden keine Daten an den Server gesendet.
Bei jeder Änderung des Textes oder durch Hinzufügen eines Bildes wird das PDF in ein canvas-Element gerendert und angezeigt. In einer echten Anwendung würden wir die Vorschau natürlich anders lösen und das PDF erst ganz am Ende erzeugen.
Wir möchten hier folgende Projekte vorstellen:
Da bei unseren Beispielen Dateien per fetch nachgeladen werden, müssen die Scripts in einem (lokalen) Webserver ausgeführt werden. Man kann dazu z.B. die Visual Studio Code Erweiterung Live-Server verwenden.
PDF-LIB
PDF-LIB ist eine JavaScript-Bibliothek für die Erstellung und Bearbeitung von PDF-Dokumenten in Browsern oder Node.js. Die umfangreiche API ermöglicht es, Texte, Bilder, Formulare und andere Inhalte hinzuzufügen oder zu entfernen. Außerdem können mit PDF-LIB mehrere PDF-Dateien zu einer einzigen Datei kombiniert werden.
In diesem Beispiel laden wir eine bestehende PDF-Datei und ergänzen sie mit Text und Bild.
async function addTextAndImageToPdf() {
// Laden des PDF-Dokuments
const existingPdfBytes = await fetch('./bestehendes_dokument.pdf').then(res => res.arrayBuffer());
const pdfDoc = await PDFDocument.load(existingPdfBytes);
// page = Die erste Seite des geladenen PDF's
const page = pdfDoc.getPages()[0];
// Hinzufügen von Text
page.drawText('Hallo Welt!', { x: 10, y: 570, size: 20 });
// Hinzufügen eines Bildes
const imageBytes = await fetch('./monkey.jpg').then(res => res.arrayBuffer());
const image = await pdfDoc.embedJpg(imageBytes);
page.drawImage(image, { x: 10, y: 330, width: image.width / 2, height: image.height / 2, });
// Uint8Array
const pdfBytes = await pdfDoc.save();
// Speichern des geänderten PDF-Dokuments
const blob = new Blob([pdfBytes], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = 'pdf-mit-Makakenselfie.pdf';
link.click();
}
addTextAndImageToPdf();
Diese Demo zeigt den obigen Code in einer Webseite. Nach dem Generieren wird die PDF-Datei heruntergeladen.
pdf.js
Mozilla entwickelt und betreut die JavaScript-Bibliothek pdf.js, um PDF-Dokumente direkt im Webbrowser anzeigen zu können. Die Rendering-Engine wird von Firefox standardmäßig genutzt, um PDFs ohne zusätzliche Plugins darzustellen - ist jedoch nicht auf diesen Browser beschränkt. pdf.js rendert PDFs in ein Canvas-Element.
Anstatt das PDF herunterzuladen, übergeben wir jetzt den von der PDF-Lib erzeugten Uint8Array an folgende Funktion:
async function renderPdf(pdfBytes) {
// Das Canvas-Elements aus dem DOM
const canvas = document.querySelector('canvas');
// Task zum Laden des PDF-Dokuments aus dem übergebenen Uint8Array
const loadingTask = pdfjsLib.getDocument(pdfBytes);
// Warten auf das Laden des Dokuments und Zuweisen des Ergebnisses zur Variable 'pdf'
const pdf = await loadingTask.promise;
// Laden der ersten Seite des PDF-Dokuments
const page = await pdf.getPage(1);
// Erzeugen eines Viewports für die Seite mit einer Skalierung von 1
const viewport = page.getViewport({ scale: 1 });
// Setzen von Höhe und Breite des canvas-Elements entsprechend dem Viewport
canvas.height = viewport.height;
canvas.width = viewport.width;
// Erzeugen eines Tasks zum Rendern der Seite auf dem Canvas
const renderTask = page.render({
canvasContext: canvas.getContext('2d'),
viewport: viewport
});
// Warten auf das Rendern der Seite
await renderTask.promise;
}
Siehe Demo. Jetzt sollte pdf.js unser PDF in das canvas-Element rendern. Wichtig ist, den Worker einzubinden (siehe Quelltext).
Abschließend erweitern wir unsere Seite um einen Button und diese Download-Funktion:
function downloadPdf() {
// Ein Blob repräsentiert einen Binärdatenblock und kann für den Download verwendet werden.
const blob = new Blob([pdfBytes], { type: 'application/pdf' });
// Generiere eine temporäre Object URL, die auf den Blob verweist.
const url = URL.createObjectURL(blob);
// Erstelle ein neues HTML 'a' Element (Link) zur Auslösung des Downloads.
const link = document.createElement('a');
// Setze den URL-Verweis des Links auf die erstellten Object URL, damit sie auf den Blob zeigt.
link.href = url;
// Definiert den Dateinamen, der beim Download verwendet werden soll.
link.download = 'pdf-mit-Makakenselfie.pdf';
// Programmgesteuertes Klicken des Links löst den Download aus.
// Da der Link nicht im DOM eingefügt wird, geschieht der Download ohne sichtbare UI-Interaktion.
link.click();
// Verwerfe die Object URL nach Gebrauch, um Speicher freizugeben.
URL.revokeObjectURL(url);
}
Die fertige Demo.
So! Jetzt ist es an der Zeit, die hart verdiente Urkunde der "Fat-Valley-University" auszudrucken und im goldenen Rahmen über den Kamin zu hängen 🙂 !