Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package wbs.jsf1.pdf; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.MalformedURLException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.PostConstruct; import javax.ejb.EJB; import javax.ejb.Stateless; import com.itextpdf.io.font.FontConstants; import com.itextpdf.io.image.ImageDataFactory; import com.itextpdf.kernel.color.Color; import com.itextpdf.kernel.font.PdfFont; import com.itextpdf.kernel.font.PdfFontFactory; import com.itextpdf.kernel.geom.PageSize; import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfWriter; import com.itextpdf.kernel.pdf.canvas.PdfCanvas; import com.itextpdf.layout.Document; import com.itextpdf.layout.border.Border; import com.itextpdf.layout.border.SolidBorder; import com.itextpdf.layout.element.Cell; import com.itextpdf.layout.element.Image; import com.itextpdf.layout.element.Paragraph; import com.itextpdf.layout.element.Table; import com.itextpdf.layout.property.HorizontalAlignment; import com.itextpdf.layout.property.TextAlignment; // import com.itextpdf.text.DocumentException; import wbs.jsf1.business.KostenErmittelnLocal; import wbs.jsf1.persistence.Adresse; import wbs.jsf1.persistence.AdresseFacadeLocal; import wbs.jsf1.persistence.Kunde; import wbs.jsf1.persistence.KundeFacadeLocal; import wbs.jsf1.persistence.Lottoschein; import wbs.jsf1.persistence.LottoscheinFacadeLocal; import wbs.jsf1.util.ByteLongConverter; import wbs.jsf1.util.LottoUtil; /** * Bean : Quittungserstellung als PDF * ================================== * * Beschreibung : * ============== * * Aufbau der Quittung: * * berschrift * Block mit Kundenanschrift. * Block mit Lottoscheinangaben. * Block mit Barcode * Block mit Hinweisen. * */ @Stateless public class LottoReceiptBean implements LottoReceiptBeanLocal { // Komponenten f. Zugriff auf Datenmodell bzw. BussinessFunktionen @EJB private KundeFacadeLocal kundeFacade; // notw. f. Kundenanschrift @EJB private AdresseFacadeLocal adresseFacadeLocal; // notw. f. Kundenanschrift @EJB LottoscheinFacadeLocal lottoscheinFacadeLocal; // notw. f. Infos aus Lottoschein @EJB KostenErmittelnLocal kostenErmittelnLocal; // notw. f. Ermittlung Zahlungsbetrag d. Quittung // Logger private static final Logger LOG = Logger.getLogger(LottoReceiptBean.class.getName()); //Verzeichnisse in dem die Bilder der Quitung liegen private static String bildVerzeichniss = null; // notw. Datenobjekte f. alte Logik der Quittung private static final int annahmeschlussMittwoch = 18; private static final int annahmeschlussSamstag = 19; // TODO hier prfen, ob Konstanten in Konfigurationsdatei-/klasse auslagern. private static final String IMAGE_NAME = "lotto6aus49.png"; // private static final String IMAGE_BACKGROUND = "BackgroundImage.png"; private static final String IMAGE_BARCODE = "barcode.png"; private static String imagePath; private static String backgroundImageimagePath; private static String datum = new SimpleDateFormat("ddMMyyyy").format(new Date()); private Lottoschein lottoscheinForPdfGenerierung; @PostConstruct public void init() { // festlegen der Pfade zum laden der eingebundenen Bilder (Bilder 6aus49 + Hintergrundbild) imagePath = this.getClass().getResource(IMAGE_NAME).getPath(); // laden des Pfades fr das Lottobild // backgroundImageimagePath = this.getClass().getResource(IMAGE_BACKGROUND).getPath(); // laden des Pfades fr Hintergroundbild // imagePath = LottoReceiptBean.class.getResource(IMAGE_NAME).getPath(); // imagePath = Thread.currentThread().getContextClassLoader().getResource(IMAGE_NAME).getPath(); } /** ******************************************************************************************** * * Erstellung der Quittung als PDF * =============================== * * Aufbau der Quittung: * ==================== * * 1) Block f. berschrift * 2) Block mit Kundenanschrift. * 3) Block mit Lottoscheinangaben. * 4) Block mit Barcode * 5) Block mit Hinweisen. * * wenn keine Quittung erstellt werden dann wird null zurckgeliefert. * * *********************************************************************************************/ public byte[] createPdfFrom(Lottoschein lottoschein) { // zuweisung auf den lottoschein, da die alte logik ber das objekt lottoscheinForPdfGenerierung Daten holt this.lottoscheinForPdfGenerierung = lottoschein; /* **************************************************************************** * Datenbeschaffung f. Quittung * ****************************************************************************/ // Datenbeschaffung f. Quittung bzgl. Ermittlung der Kosten (Rechnungsbetrag f. Quittung) TODO mgl. Problem Obj. int kostenLottoschein = this.ermittlungKosten(lottoschein); lottoschein.setKosten(Integer.valueOf(kostenLottoschein)); // Datenbeschaffung f. Quittung bzgl. Kundenaddresse (notw. Bussinessobjekte) Kunde kunde = kundeFacade.find(lottoschein.getKundeId().getKundeId()); Adresse adresse = null; if (kunde.getAdresseList().size() > 0) { adresse = kunde.getAdresseList().get(0); } // Datenbeschaffung f. InfoTexte (Hinweise auf dem Lottoschein) String aktDatum = FormatUtil.formatDatum(new Date(), FormatUtil.Formats.FORMAT_DATUM); // akt. Datum f. Andruck i. Infotexten String[] anzudruckendeInfoTexte = { "Lotto das SuperDing.", "Abgegeben am <AbgabeDatum>", "Infos in ihrer Annahmestelle.", "Rckseite beachten." }; anzudruckendeInfoTexte[1] = anzudruckendeInfoTexte[1].replace("<AbgabeDatum>", "" + aktDatum); /* **************************************************************************** * Erstellen der Quittung mit den ermittelten Daten (quittungsstruktur + Befllung) * ****************************************************************************/ // Formularbefllung, je Block erfolgt ein Methodenaufruf zur Befllung des Blocks try { /* * Begrndung: Bedienen eines Pdf-Dokument-Editor mit ntzl. Operationen * mit denen wir das Dokument erstellen und befllen formatieren. * -> siehe hierzu Aufgaben des PdfDocEditors. */ PdfDocEditor pdfDocEditor = new PdfDocEditor(); /* **************************************************************************** * blockweise Erstellung d. Quittung v. oben nach unten * ****************************************************************************/ // 1) Block f. berschrift pdfDocEditor.writeUeberschrift("SPIELQUITTUNG"); // 2) Block mit Kundenanschrift. -> Angaben zur Kundenanschrift (Vorname, Nachname, Strasse, Hausnummer, Ort) this.createKundenanschriftBlock(pdfDocEditor, kunde, adresse); pdfDocEditor.createTrennstrich(); // 3) Block mit Lottoscheinangaben -> Angaben zur Ziehung (Gewinnzahlen, Superzahl, Losnummer, von, bis ..) this.createZiehungsblock(pdfDocEditor.getDocument(), pdfDocEditor.schriftsatzNormal, pdfDocEditor.schriftsatzFett); pdfDocEditor.createTrennstrich(); // 4) Block mit Barcode -> Angaben zum Barcode (Barcode, Barcodenummer) this.createBarcodeBlock(pdfDocEditor, lottoschein); pdfDocEditor.createTrennstrich(); // 5) Block mit Hinweisen. -> Hinweistexte ( Werbung, Abgabdatum, weitere Hinweise ) this.createInfoBlock(pdfDocEditor, anzudruckendeInfoTexte); pdfDocEditor.createTrennstrich(); /* **************************************************************************** * Erstellung des PdfDokumentes und Rckgabe * ****************************************************************************/ // Konv. in ByteArray z.B. f. BLOB in DB oder File Speicherung + Logging byte[] docContent = pdfDocEditor.convertDokumentToByteArray(); LOG.log(Level.INFO, "PDF succesfully created."); // Rckgabe aktuelles Document als byteArray return docContent; } // wenn keine Quittung erstellt werden konnte oder Fehler, dann null catch (IOException ex) { Logger.getLogger(LottoReceiptBean.class.getName()).log(Level.SEVERE, "pdf creation problem", ex); } return null; } /** ******************************************************************************************** * Methode ermittelt aus den Teilnahme Informationen des Lotteoschein unter Nutzung * der BussinessFunktion ermittleKosten (KostenermittlungLocal) den auf den Lottoschein * zu entrichtenden Gesamtrechnungsbetrag. * * @param lottoschein Lotteschein, in dem die kostenrelevanten Teilnahmen vermerkt sind. * * @return Gesamtbetrag der Rechnung in cent. * ******************************************************************************************** */ public int ermittlungKosten(Lottoschein lottoschein) { // Auslesen rel. Infos f. Aufr. BussinessFunktion (ermittle Kosten) aus Lottoschein Date datumKosten_1 = lottoschein.getAbgabeDatum(); Boolean isMittwoch_1 = lottoschein.getIsMittwoch(); Boolean isSamstag_1 = lottoschein.getIsSamstag(); Boolean isSpiel77_1 = lottoschein.getIsSpiel77(); Boolean isSuper6_1 = lottoschein.getIsSuper6(); int laufzeit_1 = lottoschein.getLaufzeit(); // Ermittlung Anzahl der Lottoscheintipps, da pro Tip eine Gebhr zu entrichten ist. long[] result = ByteLongConverter.byteToLong(lottoschein.getTipps()); int anzahlTips_1 = 0; ; if (result != null) { anzahlTips_1 = result.length; } // Aufruf der Bussinessfunktion f. die Kostenermittlung int kosten_1 = kostenErmittelnLocal.kostenErmitteln(datumKosten_1, isMittwoch_1, isSamstag_1, isSpiel77_1, isSuper6_1, laufzeit_1, anzahlTips_1); return kosten_1; } /** * Block f. Barcode * ======================== * * Style : Schriftart: Normal Ausrichtung:zentriert * Format : * <BARCODE> * <BARBILD> * * @param editor - Editor mit d. akt. Dokument bearb. wird, z.B. Quittung-Rechnung * @throws IOException * @throws DocumentException */ private void createBarcodeBlock(PdfDocEditor editor, Lottoschein lottoschein) { // Style : Schriftart: Normal Ausrichtung:zentriert int tabstop = 0; editor.setSchriftsatz(editor.SIZE_NORMAL); editor.setTextausrichtung(editor.AUSRICHTUNG_CENTER); // Andruck : Belegnummer. editor.writelnText("" + lottoschein.getBelegnummer()); try { // Andruck : Barcode_bild editor.printImage(LottoReceiptBean.IMAGE_BARCODE, 30, 80.0f); } catch (IOException e) { e.printStackTrace(); } } /** * Block f. Kundenanschrift * ======================== * * Style : Schriftart: Normal Ausrichtung:zentriert * Format : * <KUNDE.VORNAME> <KUNDE.NACHNAME> * <ADRESSE.STRASSE> <ADRESSE.HAUSNUMMER> * <ADRESSE.ORT> * * @param editor - Editor mit dem das akt. Dokument editiert wird, z.B. Quittung-Rechnung * @param kunde - BObj Kunde mit Vorname, Name * @param addresse - BObj Adresse mit Strasse, Hausnummer, Ort * * @throws MalformedURLException */ private void createKundenanschriftBlock(PdfDocEditor editor, Kunde kunde, Adresse addresse) throws MalformedURLException { // Style : Schriftart: Normal Ausrichtung:zentriert int tabstop = 0; editor.setSchriftsatz(editor.SIZE_NORMAL); editor.setTextausrichtung(editor.AUSRICHTUNG_CENTER); // Format : StringBuilder gesamttext = new StringBuilder(); // hinzufgen Kundenname gesamttext.append("" + kunde.getVorname() + " " + kunde.getName() + "\n"); // hinzufgen Kundenandresse if (addresse != null) { gesamttext.append("" + addresse.getStrasse() + " " + addresse.getHausnummer() + "\n"); gesamttext.append("" + addresse.getOrt() + "\n"); } // Andruck : gesamte Kundenanschrift editor.writelnText("" + gesamttext.toString()); } /** * Block f. Hinweistexte * ======================== * * Style : Schriftart: Normal Ausrichtung:zentriert * Format : * <HINWEISTEXT_1> * <HINWEISTEXT_2> * ... * * @param editor - Editor mit dem das akt. Dokument editiert wird, z.B. Quittung-Rechnung * @param kunde - Bussinessobjekt Kunde mit Vorname, Name * @param addresse - Bussinessobjekt Adresse mit * * @throws MalformedURLException */ private void createInfoBlock(PdfDocEditor editor, String[] infos) throws MalformedURLException { // Style : Schriftart: Normal Ausrichtung:zentriert int tabstop = 0; editor.setSchriftsatz(editor.SIZE_NORMAL); editor.setTextausrichtung(editor.AUSRICHTUNG_CENTER); // Format : for (String hinweis : infos) { editor.writelnText("" + hinweis); } } /** * Block f. Angaben zur Ziehungsteilnahme * ======================================= * * Style : Schriftart: Normal Ausrichtung:zentriert * * Format : * * 1) <Lottoschein.TIPS> * 2) <Superzahl> * 3) <Losnummer> <Super6 NEIN/JA> * 4) <Spiel77 NEIN/JA> * 5) <Spieltag> * 6) <Laufzeit> <von> * 7) <bis> * ... * * @param document * @param font * @param bold * @throws MalformedURLException */ private void createZiehungsblock(Document document, PdfFont font, PdfFont bold) throws MalformedURLException { document.add(getHeaderTable()); // -- Lottozahlen auflisten -- // 1) <Lottoschein.TIPS> // 2) <Superzahl> document.add(getZiehungsDatenTable(font, bold)); // --- Losnummern --- // 2) <Superzahl> // 3) <Losnummer> <Super6 NEIN/JA> // 4) <Spiel77 NEIN/JA> document.add(getLosnummerTable(font, bold)); // --- Spieltage --- // 5) <Spieltag> document.add(getSpieltageTable(font, bold)); // --- Laufzeit --- // 6) <Laufzeit> <von> // 7) <bis> document.add(getLaufzeitTable(font, bold)); // --- Rechnungsbetrage d. Quittung --- document.add(getBetragTable(font, bold)); } // Ziehuungsblock : Header private Table getHeaderTable() throws MalformedURLException { Table table = new Table(new float[] { 1 }) { }; table.setWidthPercent(100); getHeaderImage(table); table.addCell(new Cell().add("").setBorder(Border.NO_BORDER)); return table; } // Ziehuungsblock : Einfgen des LottoBildes private void getHeaderImage(Table table) { Image headerLogo; try { headerLogo = new Image(ImageDataFactory.create(imagePath)).setAutoScale(true) .setBorder(Border.NO_BORDER); table.addCell(new Cell().add(headerLogo).setBorder(Border.NO_BORDER)); } catch (Exception e) { LOG.log(Level.WARNING, "cannot find the image file for the pdf"); table.addCell(new Cell().setBorder(Border.NO_BORDER)); } } // Ziehuungsblock : Einfgen der abgegebenen Tips auf dem Lottoschein private Table getZiehungsDatenTable(PdfFont font, PdfFont bold) { Table table = new Table(new float[] { 1, 1, 1, 1, 1, 1, 1 }) { }; table.setWidthPercent(100); int lineCnt = 0; long[] result = ByteLongConverter.byteToLong(lottoscheinForPdfGenerierung.getTipps()); for (long l : result) { table.addCell(new Cell().add(new Paragraph(String.valueOf(++lineCnt) + ".").setFont(font)) .setBorder(Border.NO_BORDER).setWidthPercent(20)); List<Integer> lz = LottoUtil.tippAsArrayList(l); for (Integer i : lz) { table.addCell(new Cell().add(new Paragraph(String.valueOf(i)).setFont(font)) .setBorder(Border.NO_BORDER).setWidthPercent(13)); } } return table; } // Ziehuungsblock : Angabe der Lsonummer, Teilnahme an den Spielen super6/Spiel77 private Table getLosnummerTable(PdfFont font, PdfFont bold) { Table table = new Table(new float[] { 1, 1, 1 }) { }; table.setWidthPercent(100); table.addCell(new Cell().add("").setBorder(Border.NO_BORDER)); table.addCell(new Cell().add("").setBorder(Border.NO_BORDER)); table.addCell(new Cell().add("").setBorder(Border.NO_BORDER)); table.addCell(new Cell().add(new Paragraph("Superzahl").setFont(font)).setBorder(Border.NO_BORDER) .setWidthPercent(55)); table.addCell( new Cell().add(new Paragraph("").setFont(font)).setBorder(Border.NO_BORDER).setWordSpacing(35)); String superzahl = String.valueOf(lottoscheinForPdfGenerierung.getLosnummer()); table.addCell(new Cell().add(new Paragraph(superzahl.substring(superzahl.length() - 1)).setFont(font)) .setBorder(Border.NO_BORDER).setWordSpacing(10).setHorizontalAlignment(HorizontalAlignment.RIGHT)); table.addCell(new Cell().add(new Paragraph("Losnummer").setFont(font)).setBorder(Border.NO_BORDER) .setWidthPercent(55)); table.addCell(new Cell().add(new Paragraph("Super6").setFont(font)).setBorder(Border.NO_BORDER) .setWordSpacing(35)); table.addCell( new Cell().add(new Paragraph(isGame(lottoscheinForPdfGenerierung.getIsSuper6())).setFont(font)) .setBorder(Border.NO_BORDER).setWordSpacing(10)); table.addCell(new Cell() .add(new Paragraph(String.valueOf(lottoscheinForPdfGenerierung.getLosnummer())).setFont(font)) .setBorder(Border.NO_BORDER).setWidthPercent(55)); table.addCell(new Cell().add(new Paragraph("Spiel77").setFont(font)).setBorder(Border.NO_BORDER) .setWordSpacing(35)); table.addCell( new Cell().add(new Paragraph(isGame(lottoscheinForPdfGenerierung.getIsSpiel77())).setFont(font)) .setBorder(Border.NO_BORDER).setWordSpacing(10)); return table; } // Ziehuungsblock : Angabe zur Teilnahme an den Ziehungstagen (Mittwoch/Sonnabenziehung) private Table getSpieltageTable(PdfFont font, PdfFont bold) { Table table = new Table(new float[] { 1 }) { }; table.addCell(new Cell().add("").setBorder(Border.NO_BORDER)); table.addCell(new Cell() .add(new Paragraph(getSpieltageText(lottoscheinForPdfGenerierung.getIsMittwoch(), lottoscheinForPdfGenerierung.getIsSamstag()).toString()).setFont(font)) .setBorder(Border.NO_BORDER).setWidthPercent(55)); return table; } // Ziehungsblock : Angabe zur Loaufzeit (Anzahl der Wochen an denen teilgenommen wird) private Table getLaufzeitTable(PdfFont font, PdfFont bold) { Table table = new Table(new float[] { 1, 1 }) { }; table.addCell(new Cell().add("").setBorder(Border.NO_BORDER)); table.addCell(new Cell().add("").setBorder(Border.NO_BORDER)); table.addCell(new Cell().add( new Paragraph(getLaufzeitText(lottoscheinForPdfGenerierung.getLaufzeit()).toString()).setFont(font)) .setBorder(Border.NO_BORDER).setWidthPercent(55)); table.addCell(new Cell().add( new Paragraph("vom " + FormatUtil.formatDatum(getEndDatum(), FormatUtil.Formats.FORMAT_DATUM_YEAR)) .setFont(font)) .setBorder(Border.NO_BORDER).setWidthPercent(45)); table.addCell( new Cell().add(new Paragraph("").setFont(font)).setBorder(Border.NO_BORDER).setWidthPercent(55)); table.addCell(new Cell().add( new Paragraph("bis " + FormatUtil.formatDatum(getEndDatum(), FormatUtil.Formats.FORMAT_DATUM_YEAR)) .setFont(font)) .setBorder(Border.NO_BORDER).setWidthPercent(45)); return table; } // Rechnungsblock : Gesamtbetrag der Rechnung, siehe Fkt. ermittlungKosten(Lottoschein) private Table getBetragTable(PdfFont font, PdfFont bold) { Table table = new Table(new float[] { 1, 1 }) { }; table.addCell(new Cell().add("").setBorder(Border.NO_BORDER)); table.addCell(new Cell().add("").setBorder(Border.NO_BORDER)); table.addCell(new Cell().add("Betrag: ").setBorder(Border.NO_BORDER).setWidthPercent(80)); String formatedBetrag = FormatUtil.formatBetrag(lottoscheinForPdfGenerierung.getKosten(), FormatUtil.Formats.FORMAT_BETRAG, FormatUtil.Formats.PATTERN_BETRAG); table.addCell(new Cell().add("" + formatedBetrag).setBorder(Border.NO_BORDER).setWidthPercent(20) .setHorizontalAlignment(HorizontalAlignment.RIGHT)); return table; } /** * TODO Zuerst prfen, ob diese Function nach LottoDatumUtil verlagern kann! * * @return */ // TODO: Schlauer machen /* * Ermittelt das letzte Spieldatum. Problematik: Um den tatschlich letzten * Ziehungstag zu errechnen, kann man nicht einfach 2 Wochen zum Abgabedatum * dazu rechnen. Reiche ich beispielsweise am Dienstag 20.03. den Lottoschein * ein und gebe 2 Wochen Laufzeit an, spiele aber nur Mittwochslotto, dann wrde * bei einer Aufrechnung von 2 Wochen der letzte Samstag mit eingeschlossen und * somit angezeigt werden, obwohl ich nur Mittwochslotto spiel. Daher muss * geprft werden, welche Tage (Mi oder Sa) gespielt werden, um diese dann von * meinen Zhlern abzuziehen. Wenn 0 erreicht wurde, muss die Schleife beendet * werden. Das dann ermittelte Datum ist der letzte tatschlich Ziehungstag, an * dem man teilnimmt. */ private Date getEndDatum() { int wochenlaufzeit = lottoscheinForPdfGenerierung.getLaufzeit(); int tage = wochenlaufzeit * 7; Date datumStart = lottoscheinForPdfGenerierung.getAbgabeDatum(); int m = wochenlaufzeit; int s = wochenlaufzeit; Calendar curr = Calendar.getInstance(); curr.get(Calendar.HOUR_OF_DAY); Calendar cal = Calendar.getInstance(); cal.setTime(datumStart); if (cal.get(Calendar.DAY_OF_WEEK) == 4 & curr.get(Calendar.HOUR_OF_DAY) > annahmeschlussMittwoch) { cal.add(Calendar.DATE, 1); } if (cal.get(Calendar.DAY_OF_WEEK) == 7 & curr.get(Calendar.HOUR_OF_DAY) > annahmeschlussSamstag) { cal.add(Calendar.DATE, 1); } for (int i = 0; i < tage; i++) { cal.add(Calendar.DATE, 1); if (cal.get(Calendar.DAY_OF_WEEK) == 4) { m--; } if (cal.get(Calendar.DAY_OF_WEEK) == 7) { s--; } if (lottoscheinForPdfGenerierung.getIsMittwoch() & lottoscheinForPdfGenerierung.getIsSamstag()) { if (m == 0 & s == 0) { break; } } else { if (lottoscheinForPdfGenerierung.getIsMittwoch()) { if (m == 0) { break; } } if (lottoscheinForPdfGenerierung.getIsSamstag()) { if (s == 0) { break; } } } } return cal.getTime(); } private StringBuilder getLaufzeitText(int wochen) { StringBuilder laufzeit = new StringBuilder(); laufzeit.append("Laufzeit: " + wochen + " Woche"); if (wochen > 1) { laufzeit.append("n"); } return laufzeit; } private StringBuilder getSpieltageText(boolean isM, boolean isS) { StringBuilder spieltage = new StringBuilder(); spieltage.append("Spieltag"); if (isM & isS) { spieltage.append("e"); } if (isM) { spieltage.append(" Mittwoch "); } if (isM & isS) { spieltage.append("und"); } if (isS) { spieltage.append(" Samstag"); } return spieltage; } private String isGame(boolean check) { return check ? "JA" : "NEIN"; } /********************************************************************************************* * * PdfDocEditor * ============ * * Aufgabe d. PdfDocEditor ist die Bearbeitung eines Pdf-Dokumentes mittels vordefinierter * ntzlich Manipulationsoperationen zur Erstellung der Dokumentstruktur und der Dokumentbefllung. * * Hintergrund : * -------------- * * Werden standardisiert gleichartige Dinge erzeugt, dann sollte man sich standardoperationen * definieren, um ein einheitliches Layout zu erzwingen. * * Bei der nachfolgenden Quittung handelt es sich um Formular das aus Seiten/Blcken/Feldern * besteht, die stets in einer gleichen Art und Weise bearbeitet werden sollten. * Um so etwas zu erzielen sollte man sich einen entsprechende Editor als Wrapper anlegen, * ber den die einzubindenden Editoren (z.B. PdfCancace fr die SeitenEdition usw. bedient werden) * * bei dem nachfolgenden Entwicklungsstand wurden zunchst folgende Operationen erkannt: * * 1) erzeugen eines Dokumentes * 2) Trennstrich einfgen * 3) Text zentriert mit einem Font schreiben * 4) Bild einfgen. * */ public class PdfDocEditor { /* ****************************************************************************** * Formatierungen/Schriftgren * ===================================== * Hier sind leider keine statischen Konstanten nutztbar, siehe OCA nestedKasses * -> Compilerfehler * ******************************************************************************/ public String AUSRICHTUNG_CENTER = "AUSRICHTUNG_CENTER"; public String AUSRICHTUNG_RIGHT = "AUSRICHTUNG_RIGHT"; public String AUSRICHTUNG_LEFT = "AUSRICHTUNG_LEFT"; public String SIZE_SMALL = "SIZE_SMALL"; public String SIZE_NORMAL = "SIZE_NORMAL"; public String SIZE_FETT = "SIZE_FETT"; // Dokument + Bytestream ByteArrayOutputStream pdfStream = new ByteArrayOutputStream(); PdfWriter writer = null; PdfDocument pdf = null; Document bearbeitungsDokument = null; // Auswahl der Schriftstze PdfFont schriftsatzNormal = null; PdfFont schriftsatzFett = null; // // Editierobjekte, die whrend des Prozesses der Dokumentbearbeitung bentigt werden Table table = null; int tabstop = 0; String textausrichtung = this.AUSRICHTUNG_LEFT; String schriftsatz = this.SIZE_NORMAL; // Anlegen eines Editor + leeres Dokument erzeugen public PdfDocEditor() throws IOException { this.initalizeFonts(); this.createDocument(); } /** * Initialisieren der Schriftstze. Z.B: berschriften und normaler Texte * @throws IOException */ public void initalizeFonts() throws IOException { // Schriftstze initialisieren this.schriftsatzNormal = PdfFontFactory.createFont(FontConstants.HELVETICA); this.schriftsatzFett = PdfFontFactory.createFont(FontConstants.HELVETICA_BOLD); } /** * Anlegen eines leeren PDF-Dokumentes * @throws MalformedURLException */ public void createDocument() throws MalformedURLException { // Notwendige Objekte i. Zshg mit einem Pdf Dokument this.pdfStream = new ByteArrayOutputStream(); this.writer = new PdfWriter(pdfStream); this.pdf = new PdfDocument(writer); // Seitengre des Dokuments PageSize pageSize = new PageSize(PageSize.A6); // Dokumenteinrichten und Seitenabstnde festlegen bearbeitungsDokument = new Document(pdf, pageSize); // hinzufgen des Hintergrundbildes auf der ersten seite PdfCanvas canvas = new PdfCanvas(this.pdf.addNewPage()); // Image bgImage = this.loadImage(LottoReceiptBean.IMAGE_BACKGROUND); // canvas.addImage(ImageDataFactory.create(IMAGE_BACKGROUND), pageSize, false); // Seitenrnder bearbeitungsDokument.setMargins(20, 20, 40, 20); bearbeitungsDokument.setBorderLeft(new SolidBorder(Color.YELLOW, 36)); bearbeitungsDokument.setBorderRight(new SolidBorder(Color.YELLOW, 36)); // setzen des aktuellen Dokumentes zur Bearbeitung this.bearbeitungsDokument = bearbeitungsDokument; } /* ********************************************************************* * GET / SET - METHODEN * *********************************************************************/ public Document getDocument() { return bearbeitungsDokument; } public void setDocument(Document document) { this.bearbeitungsDokument = document; } // setzen des Tabstops (Einrckung von Text als abstand vom linken Rand in prozent) public void setTabstop(int tab) { this.tabstop = tab; } public PdfFont getSchriftsatzNormal() { return schriftsatzNormal; } public void setSchriftsatzNormal(PdfFont schriftsatzNormal) { this.schriftsatzNormal = schriftsatzNormal; } public PdfFont getSchriftsatzFett() { return schriftsatzFett; } public void setSchriftsatzFett(PdfFont schriftsatzFett) { this.schriftsatzFett = schriftsatzFett; } /* ********************************************************************* * Edit - METHODEN * *********************************************************************/ // setzen der aktuellen textausrichtung [z.B. AUSRICHTUNG_CENTER] public void setTextausrichtung(String textausrichtung) { this.textausrichtung = textausrichtung; } // setzen der Schriftart [z.B. SIZE_SMALL] public void setSchriftsatz(String schriftsatz) { this.schriftsatz = schriftsatz; } // Editieroperation (Anlegen von Ausgabetabellen): z.B. fr Textzelle, da alle Textausgabe ber Tabellenzellern erfolgen. public void createTable(int rows, int columns, boolean isBorder) { // Anzahl der Zellen einer zeile in der Tabelle, (wichtig fr Formatierung) float[] array = new float[columns]; for (int i = 0; i < columns; i++) { array[i] = 1; } // table = new Table(array); table.setWidthPercent(100); if (isBorder) { table.setBorderRight(new SolidBorder(Color.RED, 10)); } } // Editieroperation ( anl. Trennstrich zum Trennen zwischen Blcken ): ----- public void createTrennstrich() { int columns = 1; float[] array = new float[columns]; for (int i = 0; i < columns; i++) { array[i] = 1; } table = new Table(array); table.setWidthPercent(100); table.setBorderBottom(new SolidBorder(Color.BLACK, 5)); this.addTableToDokument(); } /* ********************************************************************* * Mehtoden zum Bearbeiten des Dokumentes * *********************************************************************/ public void printImage(String path, int zellaufteilung, float verticalScale) throws MalformedURLException { // tabelle mit drei zellen anlegen this.createTable(1, 3, false); // die erste zellen ist horizontalScale % derseitenbreite lang table.addCell(new Cell().add(new Paragraph("").setFont(this.schriftsatzNormal)) .setBorder(Border.NO_BORDER).setWidthPercent(zellaufteilung)); Image image = this.loadImage(path); image = image.scale(verticalScale, verticalScale); // mittlere zelle hat 100-2*horizontalScale % breit Cell cell = new Cell().add(image); cell.setWidthPercent(100 - 2 * zellaufteilung); table.addCell(cell); // die letzte zelle ist horizontalScale % derseitenbreite lang table.addCell(new Cell().add(new Paragraph("").setFont(this.schriftsatzNormal)) .setBorder(Border.NO_BORDER).setWidthPercent(zellaufteilung)); this.addTableToDokument(); } // Methode zum laden eines Bildes public Image loadImage(String path) throws MalformedURLException { String imagePath = this.getClass().getResource(path).getPath(); Image image = new Image(ImageDataFactory.create(imagePath)).setAutoScale(true) .setBorder(Border.NO_BORDER); return image; } // Editieroperation (formatierten Textausgabe mit schriftsatz und ausrichtung ): public void writeFormatedTextToCell(int width, String text, String font, String ausrichtung) { if (text != null) { Cell cell = new Cell().add(text); cell.setFont(this.schriftsatzNormal); this.formatCell(cell, width, font, ausrichtung); table.addCell(cell); } } // Editieroperation (Tabellenzelle): public void formatCell(Cell cell, int width, String font, String ausrichtung) { cell.setBorder(Border.NO_BORDER).setWidthPercent(width); // Zelle entsprechend ausrichtung formatieren switch (ausrichtung) { case "AUSRICHTUNG_CENTER": cell.setTextAlignment(TextAlignment.CENTER).setBorder(Border.NO_BORDER); break; case "AUSRICHTUNG_RIGHT": cell.setTextAlignment(TextAlignment.RIGHT).setBorder(Border.NO_BORDER); break; case "AUSRICHTUNG_LEFT": cell.setTextAlignment(TextAlignment.LEFT).setBorder(Border.NO_BORDER); break; } // Zelle entsprechend Font formatieren, hier sind im moment die Schriftgren Hardcoded switch (font) { case "SIZE_SMALL": cell.setFont(this.schriftsatzNormal); cell.setFontSize(5.0f); break; case "SIZE_NORMAL": cell.setFont(this.schriftsatzNormal); cell.setFontSize(10.0f); break; case "SIZE_FETT": cell.setFont(this.schriftsatzFett); cell.setFontSize(20.0f); break; } } // Editieroperation (Ausgabe einer berschrift): Nutzung z.B. immer vor neuen Blcken als Kapitelberschrift public void writeUeberschrift(String ueberschrift) throws MalformedURLException { this.writelnText(ueberschrift, this.SIZE_FETT, this.AUSRICHTUNG_CENTER); } // Editieroperation (Ausgabe einer Textzeile): mit rechter Balkenmarkierung public void writelnText(String text, boolean border) { // anlegen von zwei zellen createTable(1, 2, border); // erste zelle ist fr "zeilenvorschub" also Einrckung table.addCell(new Cell().add(new Paragraph("").setFont(this.schriftsatzNormal)) .setBorder(Border.NO_BORDER).setWidthPercent(this.tabstop)); // in die zweite Zelle schreiben wir den Text this.writeFormatedTextToCell(100 - this.tabstop, text, this.schriftsatz, this.textausrichtung); // tabelle abschlieen addTableToDokument(); } // Editieroperation (Ausgabe einer Textzeile): public void writelnText(String text) { this.writelnText(text, false); } // Editieroperation (Ausgabe einer Textzeile): unter Angabe der Schriftart (Fett/Normal) und der Ausrichtung(Zentriert, rechts,links) public void writelnText(String text, String font, String ausrichtung) { // anlegen von zwei zellen createTable(1, 2, false); // erste zelle ist fr "zeilenvorschub" also Einrckung table.addCell(new Cell().add(new Paragraph("").setFont(this.schriftsatzNormal)) .setBorder(Border.NO_BORDER).setWidthPercent(this.tabstop)); // in die zweite Zelle schreiben wir den Text this.writeFormatedTextToCell(100 - this.tabstop, text, font, ausrichtung); // tabelle abschlieen addTableToDokument(); } // die editierte Tabelle wird zum Dokument hinzugefgt public void addTableToDokument() { // TODO type. FontProvider and FontSet are empty. Cannot resolve font with string value. if (table != null) { this.bearbeitungsDokument.add(table); } } // Konvertierung des Dokumentes in ein ByteArray public byte[] convertDokumentToByteArray() { this.bearbeitungsDokument.close(); return pdfStream.toByteArray(); } } } /* * ANHANG * ======= * * * * Literatur: * =========== * * [A. Miller,1998] "about the art of programming" * */