Von der Textdatei zum PDF

Oft besteht die Anforderung, einfache Textdateien zum Druck vorzubereiten oder an Dritte weiterzugeben. Dabei bietet sich das Universalformat PDF an. Doch wie soll der Weg dahin geschehen?

Dieser Artikel zeigt, wie einfach es möglich ist, mit jadice server 5 eine Textdatei in ein PDF-Dokument zu konvertieren und dabei zusätzlich Formatierungen einzubringen.

XSL-FO ist der Weg

XSL-FO ist eine Seitenformatierungssprache, die von der W3C standardisiert ist. Mit ihr können hochwertige Druckerzeugnisse in einer XML-Syntax deklariert werden. Die Verarbeitung ist in der Regel zweistufig:

Zunächst wird eine beliebige XML-Datei durch eine XSL-Transformation in die XSL-FO-Syntax überführt. Danach wird ein XSL-FO-Prozessor angesprochen, der diese XML-Datei in das gewünschte Format überführt. jadice server 5 liefert dazu den Prozessor "Apache FOP" mit, der die wesentlichen Teile des XSL-FO-Standards abdeckt.

Vom Text zur XML-Datei

Bevor die unstrukturierte Textdatei mittels XSL-FO konvertiert werden kann, muss aus ihr eine XML-Datei werden. Für diesen ersten Schritt gibt es in jadice server 5 einen sehr einfachen Node, der diese Arbeit übernimmt, den PlaintextToXMLNode. In den Ergebnisdatenstrom können wahlweise auch die Metadaten der Ursprungsdatei in Form ihres StreamDescriptors übernommen werden. Dies machen wir uns in diesem Beispiel zu Nutze, um eine Kopfzeile und den Dateinamen in der spätere PDF einzubringen.

Beispiel einer Textdatei:

Lorem ipsum dolor sit amet, ...

Nach der Transformation mit dem PlaintextToXMLNode:

<?xml version="1.0" encoding="utf-8"?>
<envelope>
  <stream uuid="jadice-server-10.208.0.102-1366291167643">
    <mime-type base="text/xml" primary="text" sub="xml">text/xml
    </mime-type>
    <description>XML from PlainText</description>
    <stream uuid="MARVIN-10.208.2.240-1366350911585" fileName="lorem.txt">
      <mime-type base="text/plain" primary="text" sub="plain">
        text/plain</mime-type>
      <description>This is a text file</description>
    </stream>
  </stream>
  <document xmlns="http://levigo.de/solutions/jadice/server/text"
    style="flowed">
    <p>Lorem ipsum dolor sit amet, ...</p>
  </document>
</envelope>

 Von der XML-Datei zum PDF

Aus der XML-Datei aus dem Schritt und einem statischen XSL-FO-Template, das im Konfigurationsverzeichnis abgelegt wird, kann nun das PDF erstellt werden. jadice server 5 bietet hierfür den XSLFOFormatterNode an, der sowohl die XSL-Transformation von der XML-Datei und dem Template durchführt und das Ergebnis direkt im Anschluss über den XSL-FO-Prozessor konvertiert.

Während der Entwicklung bietet es sich an, nur die XSL-Transformation durchzuführen und das Ergebnis zu kontrollieren. Dazu bietet jadice server 5 den XSLTransformationNode an. Hier das Ergebnis mit dem Beispiel-Template, das Sie im Anhang finden:

<?xml version="1.0" encoding="utf-8"?>
<envelope>
  <stream uuid="jadice-server-10.208.0.102-1366291167643">
    <mime-type base="text/xml" primary="text" sub="xml">text/xml
    </mime-type>
    <description>XML from PlainText</description>
    <stream uuid="MARVIN-10.208.2.240-1366350911585" fileName="lorem.txt">
      <mime-type base="text/plain" primary="text" sub="plain">
        text/plain</mime-type>
      <description>This is a text file</description>
    </stream>
  </stream>
  <document xmlns="http://levigo.de/solutions/jadice/server/text"
    style="flowed">
    <p>Lorem ipsum dolor sit amet, ...</p>
  </document>
</envelope>
<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"
 xmlns:doc="http://levigo.de/solutions/jadice/server/text" xmlns:ext="http://exslt.org/common">
 <fo:layout-master-set>
 <fo:simple-page-master margin-right="2cm"
 margin-left="2cm" margin-bottom="2cm" margin-top="1.5cm"
 page-width="21cm" page-height="29.7cm" master-name="simpleA4">
 <fo:region-body margin-bottom="5mm" margin-top="10mm" />
 <fo:region-before region-name="header" />
 <fo:region-after region-name="footer" />
 </fo:simple-page-master>
 </fo:layout-master-set>
 <fo:page-sequence master-reference="simpleA4">
 <fo:static-content flow-name="header">
 <fo:block border-bottom="1pt solid grey" line-height="14pt"
 font-size="12pt">This is a text file</fo:block>
 </fo:static-content>
 <fo:static-content flow-name="footer">
 <fo:block border-top="1pt solid grey" text-align-last="justify"
 font-size="8pt" padding-top="1mm">
 lorem.txt
 <fo:leader />
 Seite
 <fo:page-number />
 </fo:block>
 </fo:static-content>
 <fo:flow font-size="10pt" text-align="justify" flow-name="xsl-region-body">
 <fo:block>
 <fo:block>Lorem ipsum dolor sit amet, ...</fo:block>
 </fo:block>
 </fo:flow>
 </fo:page-sequence>
</fo:root>

 

Alles zusammen in einem Aufruf

Alle Schritte zur Konvertierung von Text nach PDF können mit einem einzigen Aufruf an jadice server 5 durchgeführt werden. Der folgende Code-Block zeigt schematisch den notwendigen Ausruf an:

    // JobFactory mit Verbindung zum Messaging-System erstellen
    JMSJobFactory jobFactory = new JMSJobFactory(...);

    // Job erstellen und konfigurieren
    Job job = jobFactory.createJob();

    final StreamInputNode si = new StreamInputNode();
    final StreamOutputNode so = new StreamOutputNode();

    final PlaintextToXMLNode text2xml = new PlaintextToXMLNode();
    text2xml.setUseMetadataEnvelope(true); // Metadaten in XML übernehmen
    // Zum Debugging: 
    // final XSLTransformationNode xml2xml = new XSLTransformationNode();
    // xml2xml.setStyleSheet(new URI("resource:xlsfo-demo/plaintext.xsl"));
    final XSLFOFormatterNode xml2pdf = new XSLFOFormatterNode();
    xml2pdf.setStyleSheet(new URI("resource:xlsfo-demo/plaintext.xsl")); // Name des XSL-FO-Template
    xml2pdf.setTargetMimeType("application/pdf");
    job.attach(//
    si.appendSuccessor(text2xml)
    // .appendSuccessor(xml2xml)
     .appendSuccessor(xml2pdf)
     .appendSuccessor(so));

    // Job abschicken
    job.submit();
    try {
      // Eingabedaten schicken
      final File f = ...
      final StreamDescriptor sd = new StreamDescriptor("text/plain");
      sd.setDescription("This is a text file"); // Wird in Kopfzeile übernommen
      sd.setFileName(f.getName()); // Fußzeile
      si.addStream(new FileInputStream(f), sd);
    } catch (Throwable th) {
      job.abort();
      throw th;
    }
    si.complete();

    // Resultat abholen
    for (Stream s : so.getStreamBundle()) {
      ...
    }
  }

 

Benötigte Dateien

Für dieses Beispiel benötigen Sie das XSL-FO-Template, dass Sie im Anhang finden. Dieses muss in der jadice server-Installation in das Verzeichnis <jadice-server>/server-config/xlsfo-demo kopiert werden.

Dort finden Sie außerdem das Ergebnis dieses Beispiels.

  Datei Geändert

PDF-Datei Ergebnis.pdf Ergebnis der XSL-FO-Konvertierung

Apr. 19, 2013 by Former user

XML-Datei plaintext.xsl XSL-FO-Template

Apr. 19, 2013 by Former user

Und andere Formate?

Der XSL-FO-Prozessor Apache FOP kann nicht nur PDF als Zielformat erzeugen, sondern auch weitere Formate wie z.B. TIFF oder PCL. Diese können durch die Angabe des passenden MIME-Types in der Methode setTargetMimeType() ausgewählt werden.