PDF's manipuleren met JavaScript

Dit artikel is uit 2012. De informatie is waarschijnlijk verouderd. Houd daar rekening mee.

In dit artikel gaan we in op het samenvoegen van PDF's. Een bekend hulpmiddel is pdftk, een toolkit voor het verwerken van PDF's. Stel u wilt x.pdf, een PDF met een productomschrijving, samenvoegen met y.pdf, een set tekeningen van het product. In pdftk gaat het samenvoegen van PDF's als volgt:

$ pdftk x.pdf y.pdf cat output z.pdf

Wilt u echter elke PDF voor het samenvoegen eerst verschalen, dan biedt pdftk hiervoor geen mogelijkheden. De onderstaande benadering biedt uitkomst.

Benodigdheden:

  • Java Runtime
  • iText, een java-bibliotheek voor het genereren en manipuleren van PDF's
  • Rhino, een JavaScript implementatie voor Java

Bij schrijven had iText versienummer 5.3.1 en Rhino versienummer 1.7R4. Download de beide bibliotheken en plaats itextpdf-5.3.1.jar en js.jar in dezelfde map en test de JavaScript interpreter als volgt uit:

$ java -cp js.jar:itextpdf-5.3.1.jar org.mozilla.javascript.tools.shell.Main
Rhino 1.7 release 4 2012 06 18
js>

Of alternatief:

$ export CLASSPATH=js.jar:itextpdf-5.3.1.jar
$ java org.mozilla.javascript.tools.shell.Main
Rhino 1.7 release 4 2012 06 18
js>

Als u de js> prompt te zien krijgt, bent u klaar voor de volgende stap. Verlaat de JavaScript interpreter met het commando quit of de toetsencombinatie Ctrl-D (in Linux).

Maak een tekstbestand pdfcat.js. Dit is een script waarin we beschrijven hoe we de PDF's willen verwerken. In het onderstaande script, lezen we van de commandoregel de namen van de PDF's om samen te voegen. Het script schaalt elke pagina tot 70% van de oorspronkelijke grootte, voordat deze pagina naar de uitvoer gaat. De schalingsfactor is de variabele scale in het script. Deze staat hier op de waarde 0.7. Pas de waarde aan om een andere schaling te krijgen.

$ cat pdfcat.js
// --- BEGIN pdfcat.js
importPackage(java.io);
importPackage(java.lang);
importPackage(com.itextpdf.text);
importPackage(com.itextpdf.text.pdf);

function pdfcat(args) {
    var scale = 0.7;
    var rotation = 0;
    var x = 0, y = 0;

    var stdout = new BufferedOutputStream(System.out);
    var document = new Document();
    var writer = PdfWriter.getInstance(document, stdout);

    document.open();

    var cb = writer.getDirectContent();
    for (var idx = 0; idx < args.length; idx += 1) {
        var reader = new PdfReader(args[idx]);
    var pageCount = reader.getNumberOfPages();
    for (var page = 1; page <= pageCount; page++) {
        var W  = reader.getPageSize(page).getWidth();
        var H  = reader.getPageSize(page).getHeight();

        document.setPageSize(new Rectangle(scale * W, scale * H));
        document.newPage();

        var pdfPage = writer.getImportedPage(reader, page);
        var c = scale * Math.cos(rotation);
        var s = scale * Math.sin(rotation);
        cb.addTemplate(pdfPage, c, s, -s, c, x, y);
        }
    }
    document.close();
}

pdfcat(arguments);
// --- EINDE pdfcat.js

Roep dit script aan op x.pdf en y.pdf:

$ java org.mozilla.javascript.tools.shell.Main pdfcat.js x.pdf y.pdf > z.pdf

De iText-bibliotheek voegt y.pdf achter x.pdf en plaatst het resultaat in z.pdf. Wie in de documentatie van iText in Action kijkt naar het voorbeeldprogramma Concatenate PDFs zal onmiddelijk overeenkomsten zien.

Dat is niet verwonderlijk, aangezien de JavaScript code dezelfde handelingen moet verrichten als de Java-code. In tegenstelling tot de Java-code heeft JavaScript geen aparte compilatieslag en is daardoor eenvoudig aan te passen.

Met deze techniek kunt u relatief eenvoudig

  • PDF's samenvoegen
  • pagina's herschikken
  • pagina's schalen
  • pagina's roteren
  • merktekens, zoals snijtekens en registratiemerken, aanbrengen
  • kleurbanden toevoegen
  • identificatie, zoals tekst of barcodes, toevoegen

Wilt u meer voorbeelden zien? Dan verwijs ik u graag naar het jspdftk-project op GitHub.