# Geschäftsbrief PDF mit Java



## Steini (20. Dez 2012)

Guten Tag,
ich versuche ein Programm zu erstellen, mit dem ein Angebot erstellt werden kann. Die Daten dazu werden aus Excel Tabellen herrausgelesen. Anschließend sollen die Daten zusammengeführt werden und als PDF abgespeichert werden. Das abspeichern des PDF habe ich mit itext versucht aber nicht hinbekommen.
Deswegen schreibe ich jetzt hier.

Das PDF soll das Layout eines Geschäftsbriefes nach Form B besitzen. 
Kann mit irgendjemand helfen, ein PDF mit Java zu erstellen das dieses Layout hat? 
Es muss auch nicht itext sein, ich freue mich auch über eine Alternative.

Der bisherige Quelltext zum Schreiben des PDF sieht so aus.


```
import java.io.FileOutputStream;
import java.net.URL;
import java.io.IOException;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.*;
import com.itextpdf.text.ExceptionConverter;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.GrayColor;
import com.itextpdf.text.pdf.PdfAnnotation;
import com.itextpdf.text.pdf.PdfBorderDictionary;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfFormField;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPCellEvent;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.TextField;



public class PDFerstellen
{
  public static Document document = new Document(PageSize.A4);
  public static PdfWriter writer;
  
  public static void pdf(String[][] mitarbeiter, int indexmitarbeiter, String produkt, String[] anschrift)
  {
    //Document document = new Document();
    
    try 
    {
      writer = PdfWriter.getInstance(document, new FileOutputStream("pdf/angebot"+produkt+".pdf"));
      
      document.open();
      Rectangle border = new Rectangle(0f,0f);
      //border.setBorderWidthLeft(6f);
      //border.setBorderWidthRight(5f);
      
      
      Image image = Image.getInstance("bilder/nouvellecom.png");
      image.scaleAbsolute(244.6f,42.3f);   
      image.setAbsolutePosition(20f, 770f);
      document.add(image);         
      
      image = Image.getInstance("bilder/qsc.png");
      image.scaleAbsolute(120f,50.8f);
      image.setAbsolutePosition(425f, 760f);
      document.add(image);
      
      image = Image.getInstance("bilder/roter_strich.png");
      image.setAbsolutePosition(0f, 730f);
      document.add(image);
      
      String eintext;
      //Adresse Absender
      eintext="Nouvelle Com GmbH & Co. KG, Börsenstraße 42, 26382 Wilhelmshaven";
      text(eintext,30,680,6,0);
      
      // Daten Absender
      eintext="Nouvelle Com GmbH & Co. KG";
      text(eintext,400,680,8, 0);
      eintext="Börsenstraße 42";
      text(eintext,400,670,8, 0);
      eintext="26382 Wilhelmshaven";
      text(eintext,400,660,8, 0);
      eintext="Geschäftskundenvertrieb";
      text(eintext,400,650,8, 0);
      eintext=mitarbeiter[0][(indexmitarbeiter+1)]+" "+mitarbeiter[1][(indexmitarbeiter+1)];
      text(eintext,400,640,8, 0);
      
      eintext="Tel";
      text(eintext,365,630,8, 0); 
      eintext=mitarbeiter[6][(indexmitarbeiter+1)]+" "+mitarbeiter[7][(indexmitarbeiter+1)]+" "+mitarbeiter[8][(indexmitarbeiter+1)];
      text(eintext,400,630,8, 0);
      
      eintext="Fax";
      text(eintext,365,620,8, 0);  
      eintext=mitarbeiter[6][(indexmitarbeiter+1)]+" "+mitarbeiter[7][(indexmitarbeiter+1)]+" "+mitarbeiter[9][(indexmitarbeiter+1)];
      text(eintext,400,620,8, 0);
      
      eintext="E-Mail";
      text(eintext,365,610,8, 0);
      eintext=mitarbeiter[10][(indexmitarbeiter+1)];
      text(eintext,400,610,8, 0);
      
      eintext="Web";
      text(eintext,365,600,8, 0);
      eintext=mitarbeiter[11][(indexmitarbeiter+1)];
      text(eintext,400,600,8, 0);
      
      eintext="Datum";
      text(eintext,365,590,8, 0);
      eintext="17.12.2012";
      text(eintext,400,590,8, 0);
      
      
      //Anschrift Firma
      eintext=anschrift[0];
      text(eintext,30,620,10, 0);
      
      eintext=anschrift[1];
      text(eintext,30,610,10, 0);
      
      eintext=anschrift[2];
      text(eintext,30,600,10, 0);
      
      eintext=anschrift[3];
      text(eintext,30,590,10, 0);
      
      //Betreff
      eintext="Angebot für einen QSC Breitband-Internetzugang";
      text(eintext,30,500,10, 1);
      
      //Ansprache
      eintext="Sehr geehrter "+anschrift[1];
      text(eintext,30,470,10, 1);
      
      //Einleitungstext
      eintext="vielen Dank für das freundliche Gespräch und Ihr Interesse an unseren Dienstleistungen.";
      text(eintext,30,450,10, 0);
      
      //Text1
      eintext="Wie vereinbart, erhalten Sie das gewünschte freibleibende Angebot. Ihren Anforderungen entsprechend haben wir ";
      text(eintext,30,430,10, 0);                                                                                             
      eintext="ein qualitativ hochwertiges und wirtschaftlich interessantes Leistungspaket für sie geschnürt.";
      text(eintext,30,420,10, 0);
      
      eintext="Mit der QSC AG setzen Sie auf einen leistungsstarken und erfahrenen Partner mit eigenem Sprach- und Datennetz. ";
      text(eintext,30,400,10, 0);
      eintext="Viele namhafte Unternehmen in Deutschland vertrauen seit Jahren auf die Qualität, die Sicherheit";
      text(eintext,30,390,10, 0);
      eintext="und den anerkannt guten Service der QSC AG.";
      text(eintext,30,380,10, 0);
            
      
      
      document.close();
    } 
    catch (Exception e) 
    {
      e.printStackTrace();
    }
  } 
  
  private static void text(String text, int x, int y, int sg, int bold) 
  {
    Document document = new Document();
    try
    {      
      PdfContentByte cb = writer.getDirectContent();
      
      BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
      BaseFont bfbold = BaseFont.createFont(BaseFont.HELVETICA_BOLD , BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
      cb.saveState();
      cb.beginText();
      cb.moveText(x, y);
      cb.setFontAndSize(bf, sg);
      if(bold==1)
      {
        cb.setFontAndSize(bfbold, sg);
      }  
      cb.newlineShowText(text);
      cb.endText();
      cb.restoreState();
    }
    catch (DocumentException e) 
    {
      e.printStackTrace();
    } catch (IOException e) 
    {
      e.printStackTrace();
    }  
    
  }
}
```

Ich weiß das noch keine Kommentare vorhanden sind und auch das der Programmierstil nicht alzu schön ist. Ich würde mich trotzdem über jede Anmerkung freuen


----------



## Landei (20. Dez 2012)

Hab ich nicht probiert, nur so als Idee: Vielleicht könnte man JasperReport dafür missbrauchen, um das Ganze etwas mehr "high-level" zu gestalten, statt selber mit Rechtecken und so rumzuwursteln?


----------



## Melfis (20. Dez 2012)

Wo ist den das Problem mit itext?

Alternativ kann man es auch mit einem PDF-Drucker machen. Ist zwar nicht so elegant, erspart einem aber fremd-libs.

MFg Melfis


----------



## Steini (20. Dez 2012)

Das Problem ist, dass ich nicht weiß wie ich das ganze automatisch Positionieren soll. Ich habe zunächst versucht das ganze absolut zu machen, allerdings komme ich so auch nicht weiter da sich je nach Produkt das ganze in die Länge ziehen kann.

Deswegen kann ich kein absolutes Layout verwenden.
Was mir helfen würde ist, wenn jemand schon einmal ein Brief mit itext erstellt hätte und mir seinen Quelltext zu Verfügung stellen würde. Dann könnte ich diesen anpassen und so versuchen das Problem zu lösen


----------



## AndiE (20. Dez 2012)

Wenn ich das richtig interpretiere, hast du für deinen Text von Punkt 430 bis Punkt 80( ca. 2,5 cm Rand bei 1 Punkt = 1772 Zoll) Platz. Das sind bei 10 Punkt-Schrift 35 Zeilen. Wenn du die Schluß und Grußformel( 10 Zeilen) abziehst, verbleiben noch 25 Zeilen Text.

Die Grußformel beginnt doch bei 


```
430 - Textzeilen*10
```


----------



## Phash (20. Dez 2012)

iReport Designer | Jaspersoft Community

iReport is the free, open source report designer for JasperReports and JasperReports Server. Create very sophisticated layouts containing charts, images, subreports, crosstabs and much more. Access your data through JDBC, TableModels, JavaBeans, XML, Hibernate, CSV, and custom sources. Then publish your reports as PDF, RTF, XML, XLS, CSV, HTML, XHTML, text, DOCX, or OpenOffice.

wenn du eh iText nutzt, nutz auch iReport dazu... 
geht recht elegant


----------



## Ullenboom (21. Dez 2012)

Ach ja, PDFs in Java erstellen, ein leidiges Thema. Im Grunde gibt es folgende Ansätze.

* Selbst die PDF erstellen, mit allen Linien, Grafiken, Texten. Das geht etwa mit iText. Nachteil: Sehr aufwändig, insbesondere wenn der Kunde einmal sagt: Die Box bitte noch ein wenig nach links oben.

* Mit Report-Programmen wie BIRT oder Japser arbeiten, die dann über iText die PDF rausspucken. Vorteil: Netter Report-Designer. Nachteil: Die Designer sind im Sekretariat, die nur Word oder vielleicht OO (OpenOffice, Libre Office) kennen, ungewohnt.

* PDF mit XForms erstellen. Siehe OpenOffice Draw + XForms Export + iText = PDF. Das mache ich bei unseren Rechnungen so. Läuft gut. Die Vorlagen erstelle ich mit OO. Weiterer Vorteil: Sekretariat kann selbst das aussehen verändern.

* Word/Excel/OO/RTF-Templates nutzen, dann in PDF konvertieren. Zum Füllen der Vorlagen gibt es einige (auch open-source) Lösungen, siehe Apache POI, jexcelapi, xdocreport, jRTF. Doch dann kommt das Problem: Das in PDF zu konvertieren. Mann kann nun die eigentlichen Programme nutzen und einen PDF-Export mit einem Druckertreiber verwenden, oder das automatisieren. Entweder über Java oder nicht-Java-Programme (etwa der Shell). Im Java-open-source Bereich gibt es hier nach meinem Kenntnisstand nichts wirklich Funktionierendes. Mit OO kann man die UNO-Brücke nutzen, das kappt mit ODT usw. sehr gut, aber man braucht eine Installation und das ist relativ langsam für Massenexports. jOpenDocument Homepage. Open Document library macht das in purem Java, ist aber noch nicht so weit. xdocreport sollte das für Word können, das Resultat ist bei meiner Vorlage aber unbrauchbar. xdocreport kann auch mit FOP -> iText -> PDD arbeiten, das habe ich noch nicht getestet.


----------



## Bleiglanz (21. Dez 2012)

Also ich hab früher mal ganz gute Erfahrungen mit Apache FOP gesammelt; wenn man gute XSLT Kenntnisse hat und sich mit den Grundlagen von XSL-FO vertraut machen will ist der Weg

XML (wenn nötig 'on the fly')  
tranformieren mit XSLT in XSL-FO
in PDF verwanden mit FOP

ziemlich einfach, allerdings pfriemelt man da auch ziemlich rum bis es passt. Damit hängt man dafür nicht so an binären Tools von Drittanbietern (OpenOffice, iReport, BIRT,..) und kann Änderungen am Layout ziemlich schnell realisieren.


----------

