Homepage: http://xml.apache.org/fop/
Mit Hilfe von FOP (Formatting Objects Processor) lassen sich aus bestimmten XML-Dateien verschiedene andere Dateiformate erzeugen, z.B. PDF, RTF, HTML. Dazu wird XSL-FO verwendet.
FOP selbst ist Teil des Apache-XML-Projekts.
barcode Erweiterungen mit FOP finden sich unter: http://krysalis.org/barcode/fop-ext.html
Tutorial zu FOP
leider unterstützt FOP nicht das gesamte Spektrum an XSL Transformationen; so wird z.B. das Objekt reference-orientation unter XSL-FO nicht unterstützt; nähere Erläuterungen findet man unter http://xml.apache.org/fop/compliance.html
ein ganz brauchbares deutschsprachiges Buch gibt es vom d-punkt Verlag http://www.mid-heidelberg.de/aktuelles/ankuendigung_xsl-fo_buch/ankuendigung_xsl-fo_buch_01.htm
dieses Buch kenne ich selber (noch) nicht http://www.oreilly.de/catalog/xslfo/index.html
Inhaltsverzeichnis
Installation und Start
- Download des tar-Pakets von der o.g. Homepage
Unter Linux und Windows benötigt FOP wohl eine installierte JAVA-Entwicklungsumgebung von SUN (siehe SunJava).
- Im entpackten Hauptverzeichnis kann man mit dem folgenden Aufruf in einer DOS-Konsole ein PDF-Dokument aus einer Beispiel-FOP-Datei erzeugen:
C:\fop-0.20.5>fop examples\fo\tables\borders.fo -pdf C:\fop-output.pdf
Beispiele
jsp
- Aufruf der jsp-Seite "tablelle.jsp" und Ausliefern als PDF:
<%@page contentType="application/pdf" import="org.apache.fop.apps.*,org.xml.sax.*,java.net.*,java.io.*" %><% URL url; Driver driver; String urlStr; try { System.out.println("# liste.jsp: "+session.getId()); urlStr = "/fop/tabelle.fop.jsp;jsessionid="+request.getSession().getId(); url = new URL("http://"+request.getServerName()+":"+request.getServerPort()+urlStr); // url.openStream(); driver = new Driver(new InputSource (url.openStream()), response.getOutputStream()); driver.setRenderer(Driver.RENDER_PDF); driver.run(); // response.setContentType("application/pdf"); } catch (IOException ioex) { response.setContentType("text/html"); out.print("<h1>Sorry...</h1>"); out.print("That is what I now about it:<br><i>"+ioex.toString()+"</i>"); url = null; } catch (RuntimeException ex) { response.setContentType("text/html"); out.print("<h1>Sorry...</h1>"); out.print("That is what I now about it:<br><i>"+ex.toString()+"</i>"); url = null; } %>
- Die URL wird an "tabelle.fop.jsp" weitergereicht - diese sieht dann so aus:
<?xml version="1.0" encoding="iso-8859-1"?> <% System.out.println("# liste.form.jsp: "+session.getId()); %> <%@page contentType='text/xml;charset=iso-8859-1' import='java.net.*'%> <%@ taglib uri="http://jakarta.apache.org/taglibs/dbtags" prefix="sql" %> <%-- open a database connection --%> <sql:connection id="conn1"> <sql:url>jdbc:postgresql://localhost:5432/drako_restore</sql:url> <sql:driver>org.postgresql.Driver</sql:driver> <sql:userId>okit</sql:userId> <sql:password> </sql:password> </sql:connection> <%-- open a database query --%> <sql:statement id="stmt1" conn="conn1"> <sql:query> SELECT * FROM kontakt ORDER BY 4 LIMIT 100 </sql:query> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <fo:simple-page-master margin-right="1.5cm" margin-left="1.5cm" margin-bottom="1cm" margin-top="1cm" page-width="21cm" page-height="29.7cm" master-name="first"> <fo:region-before extent="0.5cm"/> <fo:region-body margin-top="1cm" margin-bottom="1cm"/> <fo:region-after extent="0.5cm"/> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="first" initial-page-number="1"> <fo:static-content flow-name="xsl-region-before"> <fo:block line-height="10pt" font-size="5pt" text-align="center">Beispiele über Beispiele</fo:block> </fo:static-content> <fo:static-content flow-name="xsl-region-after"> <fo:block line-height="5pt" font-size="5pt" text-align="end">Seite <fo:page-number/> von <fo:page-number-citation ref-id="end-of-document" /></fo:block> </fo:static-content> <fo:flow flow-name="xsl-region-body"> <fo:table> <fo:table-column column-width="2cm"/> <fo:table-column column-width="2cm"/> <fo:table-column column-width="2cm"/> <fo:table-column column-width="7cm"/> <fo:table-column column-width="5cm"/> <fo:table-body> <% boolean isgray=true; %> <sql:resultSet id="rset2" > <fo:table-row> <fo:table-cell background-color="<% if (isgray){out.print("gray");} else {out.print("blue");}%>"> <fo:block text-align="center"> <sql:getColumn position="1"/> </fo:block> </fo:table-cell> <fo:table-cell background-color="gray"> <fo:block text-align="left"> <sql:getColumn position="2"/> </fo:block> </fo:table-cell> <fo:table-cell> <fo:block text-align="right"> <sql:getColumn position="3"/> </fo:block> </fo:table-cell> <fo:table-cell background-color="yellow"> <fo:block text-align="left"> <sql:getColumn position="4"/> </fo:block> </fo:table-cell> <fo:table-cell background-color="red"> <fo:block text-align="left"> <sql:getColumn position="5"/> </fo:block> </fo:table-cell> </fo:table-row> <% isgray = !isgray; %> </sql:resultSet> </fo:table-body> </fo:table> <fo:block id="end-of-document" /> </fo:flow> </fo:page-sequence> </fo:root> </sql:statement>
- In den Browser bekommt man eine wunderbar bunt formatierte Tablle im PDF-Format geliefert.
FOP - XML
fortlaufende Seitennummerrierung:
<?xml version="1.0" encoding="UTF-8"?> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <fo:simple-page-master margin-right="2cm" margin-left="2cm" margin-bottom="1cm" margin-top="1cm" page-width="21cm" page-height="29.7cm" master-name="first"> <fo:region-before /> <fo:region-body margin-top="1cm" margin-bottom="3cm" column-count="3" column-gap="1cm"/> <fo:region-after extent="2cm"/> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="first" initial-page-number="1"> <fo:static-content flow-name="xsl-region-after"> <fo:block text-align="end" font-size="12pt" font-family="sans-serif" background-color="yellow"> Page <fo:page-number/> / <fo:page-number-citation ref-id="end-of-document"/> </fo:block> </fo:static-content> <fo:flow flow-name="xsl-region-body"> <fo:block text-align="start" font-size="12pt" font-family="sans-serif"> Text der Seite </fo:block> <fo:block break-before="page" text-align="center" font-size="12pt" font-family="sans-serif"> Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite </fo:block> <fo:block break-before="page" font-size="12pt" font-family="sans-serif" text-align="justify"> Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite Text der Seite </fo:block> <fo:block break-before="page" text-align="end" font-size="12pt" font-family="sans-serif"> Text der Seite </fo:block> <fo:block id="end-of-document"></fo:block> </fo:flow> </fo:page-sequence> </fo:root>
Fragen und Antworten
ich versuche mehr durch Testen mich dem Ganzen zu nähern; ich fand nur, dass die Dokumentation auf den Projektseiten sehr "dünn" ist, insbesondere die Beschreibung der Funktion der einzelnen Tags; da gibt es wohl nicht mehr als eine Übersicht der gültigen Tags -- IngoSchnieders 2003-09-08 12:30:11