{"id":104,"date":"2007-11-23T09:46:00","date_gmt":"2007-11-23T09:46:00","guid":{"rendered":"http:\/\/www.tutego.de\/blog\/javainsel\/?p=104"},"modified":"2007-11-23T09:46:00","modified_gmt":"2007-11-23T09:46:00","slug":"openoffice-als-template-engine-dokument-einlesen-verandern-schreiben","status":"publish","type":"post","link":"https:\/\/www.tutego.de\/blog\/javainsel\/2007\/11\/openoffice-als-template-engine-dokument-einlesen-verandern-schreiben\/","title":{"rendered":"OpenOffice als Template-Engine: Dokument einlesen, ver\u00e4ndern, schreiben"},"content":{"rendered":"<p>Da ich meine Rechnungen automatisch generiert und als PDF konvertiert haben m\u00f6chte, habe nach einer L\u00f6sung gesucht, wie ich die Rechnungsdaten aus einer Datenquelle in der Template einsetzten kann, und am Ende eine PDF bekomme. Klar sind Report-Generatoren daf\u00fcr auf der Welt, aber meine Vorlagen m\u00f6chte ich nicht f\u00fcr Eclipse BIRT oder Jasper schreiben, sondern in Word bzw. OpenOffice. RTF ist relativ leicht zu schreiben und f\u00fcr ein Template meines Erachtens ganz gut. Meine Gedanken kreisten daher einige Zeit um RTF-&gt;PDF, doch da gibt es keine freie L\u00f6sung. Auch Wege wie RTF-&gt;FO-&gt;PDF sind m\u00f6glich, aber daf\u00fcr gibt es ebenfalls keine leichtgewichtigen freien L\u00f6sungen.<\/p>\n<p>Schon f\u00fcr meinen PowerPoint-&gt;PDF-Konverter habe ich mit OpenOffice gearbeitet und das klappte ganz gut. Das habe ich f\u00fcr meine Templates nun wieder \u00fcberlegt &#8212; ein recht harter Weg f\u00fcr simple RTFs zwar, aber es funktioniert. Doch anstatt RTF zu nutzen, wollte ich gleich das XML-Format verwenden. Dazu muss man wissen, dass OO ein Zip-Archiv f\u00fcr das OO-Dokument vorsieht und dort in einer XML-Datei den Content ablegt. Mit der gro\u00dfartigen Open-Source-Bibliothek <a href=\"https:\/\/truezip.dev.java.net\/\">https:\/\/truezip.dev.java.net\/<\/a> ist der Zugriff auf Archive sehr einfach.<\/p>\n<p>Mit TrueZIP ist eine einfache L\u00f6sung entstanden, ein OO-Dokument mit Template-Anweisungen wie ${address} zu lesen, Ersetzungen vorzunehmen, und alles wieder zu schreiben. Diesen Text hier zu schreiben hat l\u00e4nger gedauert, als die 90 Zeilen Quellcode. Also los:<\/p>\n<pre><br \/><p>import java.io.*;<br \/>import java.nio.channels.FileChannel;<br \/>import de.schlichtherle.io.ArchiveDetector;<br \/><\/p><p>public class OpenOfficeUtils<br \/>{<br \/>  public static void main( String[] args )<br \/>  {<br \/>    String source      = \"S:\/Private\/Traida\/Bills\/template.ods\";<br \/>    String destination = \"S:\/Private\/Traida\/Bills\/bill1.ods\";<br \/><\/p><p>    copyFile( source, destination );<br \/><\/p><p>    String content = readOpenOfficeContent( source );<br \/><\/p><p>    content = content.replace( \"${addressline1}\", \"Christian Ullenboom\" );<br \/><\/p><p>    writeOpenOfficeContent( destination, content );<br \/>  }<br \/><\/p><p>  public static String readOpenOfficeContent( String filename )<br \/>  {<br \/>    Reader is = null;<br \/><\/p><p>    try<br \/>    {<br \/>      de.schlichtherle.io.File file = new de.schlichtherle.io.File( filename + \"\/content.xml\", ArchiveDetector.ALL );<br \/>      char[] fileContent = new char[ (int) file.length() ];<br \/>      is = new de.schlichtherle.io.FileReader( file );  \/\/ TODO: &lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;<br \/>      is.read( fileContent );<br \/><\/p><p>      return new String(fileContent);<br \/>    }<br \/>    catch ( IOException e )<br \/>    {<br \/>      throw new IllegalArgumentException( e );<br \/>    }<br \/>    finally<br \/>    {<br \/>      try { is.close(); } catch ( Exception e ) { }<br \/>    }<br \/>  }<br \/><\/p><p>  public static void writeOpenOfficeContent( String filename, String content )<br \/>  {<br \/>    Writer os = null;<br \/><\/p><p>    try<br \/>    {<br \/>      de.schlichtherle.io.File file = new de.schlichtherle.io.File( filename + \"\/content.xml\", ArchiveDetector.ALL );<br \/>      os = new de.schlichtherle.io.FileWriter( file );<br \/>      os.write( content );<br \/>    }<br \/>    catch ( IOException e )<br \/>    {<br \/>      throw new IllegalArgumentException( e );<br \/>    }<br \/>    finally<br \/>    {<br \/>      try { os.close(); } catch ( Exception e ) { }<br \/>    }<br \/>  }<br \/><\/p><p>  public static void copyFile( String in, String out )<br \/>  {<br \/>    FileChannel inChannel  = null;<br \/>    FileChannel outChannel = null;<br \/><\/p><p>    try<br \/>    {<br \/>      inChannel  = new FileInputStream( new File(in) ).getChannel();<br \/>      outChannel = new FileOutputStream( new File(out) ).getChannel();<br \/>      inChannel.transferTo( 0, inChannel.size(), outChannel );<br \/>    }<br \/>    catch ( IOException e )<br \/>    {<br \/>      throw new IllegalArgumentException( e );<br \/>    }<br \/>    finally<br \/>    {<br \/>      try { inChannel.close(); } catch ( Exception e ) { }<br \/>      try { outChannel.close(); } catch ( Exception e ) { }<br \/>    }<br \/>  }<br \/>}<br \/><\/p><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Da ich meine Rechnungen automatisch generiert und als PDF konvertiert haben m\u00f6chte, habe nach einer L\u00f6sung gesucht, wie ich die Rechnungsdaten aus einer Datenquelle in der Template einsetzten kann, und am Ende eine PDF bekomme. Klar sind Report-Generatoren daf\u00fcr auf der Welt, aber meine Vorlagen m\u00f6chte ich nicht f\u00fcr Eclipse BIRT oder Jasper schreiben, sondern [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","_links_to":"","_links_to_target":""},"categories":[4],"tags":[],"class_list":["post-104","post","type-post","status-publish","format-standard","hentry","category-open-source"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/104","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/comments?post=104"}],"version-history":[{"count":1,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/104\/revisions"}],"predecessor-version":[{"id":743,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/104\/revisions\/743"}],"wp:attachment":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/media?parent=104"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/categories?post=104"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/tags?post=104"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}