Hallo,
hier endlich einmal das Rausgesuchte:
Im Prinzip wird aus einer xml und einer xsl eine sehr triviale Rechnung erstellt.
Das Ganze ist in sofern dynamisch, als das die Rechnungsdaten durch die xml variieren können.
Die xml Datei muß nicht extra gespeichert werden, es reicht, wenn sie als org.w3c.dom.Document vorliegt.
<?xml version="1.0" encoding="UTF-8"?>
<billing>
<date>10.03.2010</date>
<header>Rechnung</header>
<bill-element>
<name>Auftrag vom</name>
<element>08.03.2010</element>
</bill-element>
<bill-element>
<name>Anzahl</name>
<element>96</element>
</bill-element>
<bill-element>
<name>Kostenstelle</name>
<element>1500000 </element>
</bill-element>
<bill-element>
<name>Betrag</name>
<element>904.74</element>
<type>costs</type>
</bill-element>
</billing>
Mit dieser xml Datei kann dann die Rechnung erstellt werden. Dazu nimmt man sich eine xsl Datei, die man vorher schon einmal erstellt hat.
Man kann theoretisch auch einfach die xsl Datei im Quelltext erstellen und zwar wie die xml Datei als org.w3c.dom.Document.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" exclude-result-prefixes="fo">
<xsl:output method="xml" version="1.0" omit-xml-declaration="no" indent="yes"/>
<xsl:param name="versionParam" select="'1.0'"/>
<xsl:template match="billing">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="simpleA4" page-height="29.7cm" page-width="21cm" margin-top="2cm" margin-bottom="2cm" margin-left="2cm" margin-right="2cm">
<fo:region-body margin="2cm 2cm 2cm 2cm"/>
<fo:region-before region-name="xsl-region-before" extent="1cm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="simpleA4">
<!-- A header with page numbering, must be defined in simple-page-master as region-before -->
<fo:static-content flow-name="xsl-region-before" text-align="end" font-size="10pt" font-family="serif" line-height="14pt" color="black">
<fo:block>Seite
<fo:page-number/>
</fo:block>
<fo:block>
<xsl:value-of select="date"/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="xsl-region-body">
<!-- Header -->
<fo:block font-size="16pt" font-weight="bold" space-before.optimum="2cm" space-after="2cm">
<fo:inline text-decoration="underline"><xsl:value-of select="header"/></fo:inline>
</fo:block>
<!-- content -->
<fo:block font-size="10pt">
<fo:table table-layout="fixed" width="100%" border-collapse="separate">
<fo:table-column column-width="2cm"/>
<fo:table-column column-width="0.5cm"/>
<fo:table-column column-width="2cm"/>
<fo:table-body>
<xsl:apply-templates select="bill-element"/>
</fo:table-body>
</fo:table>
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<!-- ========================= -->
<!-- child element: bill -->
<!-- ========================= -->
<xsl:template match="bill-element">
<fo:table-row>
<fo:table-cell>
<fo:block>
<xsl:value-of select="name"/>
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>
:
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>
<xsl:if test="type = 'costs'">
<xsl:attribute name="font-weight">bold</xsl:attribute>
</xsl:if>
<xsl:value-of select="element"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:template>
</xsl:stylesheet>
Nun kann wie übrigens auch hier beschrieben: Apache FOP: Embedding
die pdf Datei erstellt werden.
File xslFile = new File("bill.xsl");
File pdfFile = new File("bill.pdf");
BufferedOutputStream buffOut = new BufferedOutputStream(new FileOutputStream(pdfFile));
FopFactory fopFactory = FopFactory.newInstance();
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
// construct fop with pdf as output format
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, buffOut);
// setup xslt
TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer(new StreamSource(xslFile));
// input for xslt
Source src = new DOMSource(billDoc);
// resulting SAX events must be piped through to FOP
Result res = new SAXResult(fop.getDefaultHandler());
// start xslt transformation and FOP processing
transformer.transform(src, res);
buffOut.close();
Die Kommentare erklären alles, denke ich.
Prinzip ist einfach, dass du eine Source für die xml Datei übergibst und die xsl Datei in Form eines SAXResult.
Es gibt auch noch die Möglichkeit die xsl ebenfalls als Source zu übergeben, wird ebenfalls in dem Link weiter oben erklärt.
Fragen, Meinungen, Probleme?
Für die xsl Datei hier noch ein Link zu einem netten Tutorial XSL-FO.
Falls das alles ein bißchen zu viel ist, hier noch die Alternative: Beitrag aus diesem Forum
bye,
Martin