Prima di procedere con il progetto SqlDocGen è necessario conoscere come si può produrre file PDF con un programma scritto in linguaggio Java, in particolare tramite l'utilizzo della libreria iTextFree. La cosa interessante è che l'input sarà un testo in HTML!
La cosa inizialmente può portare a confusione: cosa c'entra l'HTML con un file PDF? è presto fatto con la libreria iText che mette a disposizione metodi veloci per la conversione di un file HTML, formattato indentato con tabelle e colori, in un pratico file PDF in "sola lettura".
Salto volontariamente la discussione riguardo alla licenza AGPL sotto cui è distribuita attualmente la libreria iText. Vi consiglio di trovare in rete la versione 2.1.5 distribuita sotto LGPL.
Adesso vi mostro la classe-utility che ho pensato per incapsulare le funzionalità di questa interessante libreria:
package org.dgl.manager;
import com.lowagie.text.Document;
import com.lowagie.text.Element;
import com.lowagie.text.Font;
import com.lowagie.text.HeaderFooter;
import com.lowagie.text.PageSize;
import com.lowagie.text.Phrase;
import com.lowagie.text.Rectangle;
import com.lowagie.text.html.simpleparser.HTMLWorker;
import com.lowagie.text.pdf.PdfWriter;
import com.lowagie.text.pdf.codec.Base64;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.util.ArrayList;
public class PDFManager {
private final String CHARSET = "UTF-8";
private final String EXCEPTION_HTMLNOTPARSED = "HTML has not been parsed";
private final String EXCEPTION_UNKNOWNHEADERALIGNMENT = "Unknown header alignment";
private final String EXCEPTION_ILLEGALHEADEREXCEPTION="illegal header size";
private final String PDF_CONTENTTYPE = "application/pdf";
private final boolean DEFAULT_PAGECOUNTING = false;
private final float DEFAULT_HEADERSIZE=12.0f;
private final int DEFAULT_HEADER_ALIGN = HeaderFooter.ALIGN_LEFT;
private final Document document;
private final OutputStream pdfByteArrayOutputStream;
private ArrayList htmlTags;
private boolean htmlParsed;
private final boolean pageCounting;
private float headerSize;
public static final int LEFT_HEADER_ALIGNMENT = HeaderFooter.ALIGN_LEFT;
public static final int RIGHT_HEADER_ALIGNMENT = HeaderFooter.ALIGN_RIGHT;
public static final int CENTER_HEADER_ALIGNMENT = HeaderFooter.ALIGN_CENTER;
public static final float SMALL_HEADER_SIZE = 8;
public static final float NORMAL_HEADER_SIZE =12.0f;
public static final Rectangle LAYOUT_A3V=PageSize.A3;
public static final Rectangle LAYOUT_A3H=PageSize.A3.rotate();
public static final Rectangle LAYOUT_A4V=PageSize.A4;
public static final Rectangle LAYOUT_A4H=PageSize.A4.rotate();
public static final Rectangle LAYOUT_DEFAULT=LAYOUT_A4V;
public PDFManager() {
document = new Document(LAYOUT_DEFAULT);
pdfByteArrayOutputStream = new ByteArrayOutputStream();
htmlParsed = false;
pageCounting = DEFAULT_PAGECOUNTING;
headerSize=DEFAULT_HEADERSIZE;
}
public PDFManager(Rectangle layout) {
document = new Document(layout);
pdfByteArrayOutputStream = new ByteArrayOutputStream();
htmlParsed = false;
pageCounting = DEFAULT_PAGECOUNTING;
headerSize=DEFAULT_HEADERSIZE;
}
public PDFManager(boolean pageCounting) {
document = new Document(LAYOUT_DEFAULT);
pdfByteArrayOutputStream = new ByteArrayOutputStream();
htmlParsed = false;
this.pageCounting = pageCounting;
headerSize=DEFAULT_HEADERSIZE;
}
public PDFManager(boolean pageCounting,Rectangle layout) {
document = new Document(layout);
pdfByteArrayOutputStream = new ByteArrayOutputStream();
htmlParsed = false;
this.pageCounting = pageCounting;
headerSize=DEFAULT_HEADERSIZE;
}
public void parseHTML(String html) throws Exception {
html = purge(html);
Reader tagReader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(html.getBytes(CHARSET))));
if (pageCounting) {
(PdfWriter.getInstance(document, pdfByteArrayOutputStream)).setPageEvent(new PDFPageCounterManager());
} else {
PdfWriter.getInstance(document, pdfByteArrayOutputStream);
}
document.open();
htmlTags = HTMLWorker.parseToList(tagReader, null);
for (int i = 0; i < htmlTags.size(); i++) {
document.add(htmlTags.get(i));
}
document.close();
tagReader.close();
htmlParsed = true;
}
public void parseHTML(File file) throws Exception {
Reader tagReader = new BufferedReader(new FileReader(file));
if (pageCounting) {
(PdfWriter.getInstance(document, pdfByteArrayOutputStream)).setPageEvent(new PDFPageCounterManager());
} else {
PdfWriter.getInstance(document, pdfByteArrayOutputStream);
}
document.open();
htmlTags = HTMLWorker.parseToList(tagReader, null);
for (int i = 0; i < htmlTags.size(); i++) {
document.add(htmlTags.get(i));
}
document.close();
tagReader.close();
htmlParsed = true;
}
public void parseHTML(String html, String header) throws Exception {
html = purge(html);
Reader tagReader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(html.getBytes(CHARSET))));
if (pageCounting) {
(PdfWriter.getInstance(document, pdfByteArrayOutputStream)).setPageEvent(new PDFPageCounterManager());
} else {
PdfWriter.getInstance(document, pdfByteArrayOutputStream);
}
setHeader(header);
document.open();
htmlTags = HTMLWorker.parseToList(tagReader, null);
for (int i = 0; i < htmlTags.size(); i++) {
document.add(htmlTags.get(i));
}
document.close();
tagReader.close();
htmlParsed = true;
}
public void parseHTML(File file, String header) throws Exception {
Reader tagReader = new BufferedReader(new FileReader(file));
if (pageCounting) {
(PdfWriter.getInstance(document, pdfByteArrayOutputStream)).setPageEvent(new PDFPageCounterManager());
} else {
PdfWriter.getInstance(document, pdfByteArrayOutputStream);
}
setHeader(header);
document.open();
htmlTags = HTMLWorker.parseToList(tagReader, null);
for (int i = 0; i < htmlTags.size(); i++) {
document.add(htmlTags.get(i));
}
document.close();
tagReader.close();
htmlParsed = true;
}
public void parseHTML(String html, String header, int alignment) throws Exception {
Reader tagReader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(html.getBytes(CHARSET))));
if (pageCounting) {
(PdfWriter.getInstance(document, pdfByteArrayOutputStream)).setPageEvent(new PDFPageCounterManager());
} else {
PdfWriter.getInstance(document, pdfByteArrayOutputStream);
}
setHeader(header, alignment);
document.open();
htmlTags = HTMLWorker.parseToList(tagReader, null);
for (int i = 0; i < htmlTags.size(); i++) {
document.add(htmlTags.get(i));
}
document.close();
tagReader.close();
htmlParsed = true;
}
public void parseHTML(File file, String header, int alignment) throws Exception {
Reader tagReader = new BufferedReader(new FileReader(file));
if (pageCounting) {
(PdfWriter.getInstance(document, pdfByteArrayOutputStream)).setPageEvent(new PDFPageCounterManager());
} else {
PdfWriter.getInstance(document, pdfByteArrayOutputStream);
}
setHeader(header, alignment);
document.open();
htmlTags = HTMLWorker.parseToList(tagReader, null);
for (int i = 0; i < htmlTags.size(); i++) {
document.add(htmlTags.get(i));
}
document.close();
tagReader.close();
htmlParsed = true;
}
private void setHeader(String headerText) {
Font f=new Font();
f.setSize(headerSize);
HeaderFooter header = new HeaderFooter(new Phrase(headerText,f), false);
header.setAlignment(DEFAULT_HEADER_ALIGN);
document.setHeader(header);
}
private void setHeader(String headerText, int alignment) throws Exception {
if ((alignment != LEFT_HEADER_ALIGNMENT) && (alignment != RIGHT_HEADER_ALIGNMENT) && (alignment != CENTER_HEADER_ALIGNMENT)) {
throw new Exception(EXCEPTION_UNKNOWNHEADERALIGNMENT);
}
Font f=new Font();
f.setSize(headerSize);
HeaderFooter header = new HeaderFooter(new Phrase(headerText,f), false);
header.setAlignment(alignment);
document.setHeader(header);
}
public void writePDF(String file) throws Exception {
if (!htmlParsed) {
throw new Exception(EXCEPTION_HTMLNOTPARSED);
}
byte[] pdfData = ((ByteArrayOutputStream) this.pdfByteArrayOutputStream).toByteArray();
Base64.encodeBytes(pdfData);
FileOutputStream pdfOutputStream = new FileOutputStream(new File(file));
pdfOutputStream.write(pdfData);
pdfOutputStream.close();
}
public void writePDF(File file) throws Exception {
if (!htmlParsed) {
throw new Exception(EXCEPTION_HTMLNOTPARSED);
}
byte[] pdfData = ((ByteArrayOutputStream) this.pdfByteArrayOutputStream).toByteArray();
Base64.encodeBytes(pdfData);
FileOutputStream pdfOutputStream = new FileOutputStream(file);
pdfOutputStream.write(pdfData);
pdfOutputStream.close();
}
public void setHeaderSize(float newHeaderSize) throws Exception{
if(newHeaderSize<=0){
throw new Exception(EXCEPTION_ILLEGALHEADEREXCEPTION);
}
this.headerSize=newHeaderSize;
}
public void close() throws Exception {
pdfByteArrayOutputStream.flush();
pdfByteArrayOutputStream.close();
htmlTags.clear();
}
public static String purge(String text) {
text = text.replaceAll("à", "à");
text = text.replaceAll("é", "é");
text = text.replaceAll("è", "è");
text = text.replaceAll("ì", "ì");
text = text.replaceAll("ò", "ò");
text = text.replaceAll("ù", "ù");
text = text.replaceAll("°", "°");
return text;
}
}
public class PDFPageCounterManager implements PdfPageEvent {
private PdfTemplate total;
@Override
public void onOpenDocument(PdfWriter writer, Document document) {
total = writer.getDirectContent().createTemplate(100, 100);
total.setBoundingBox(new Rectangle(-20, -20, 100, 100));
}
@Override
public void onStartPage(PdfWriter writer, Document dcmnt) {
}
@Override
public void onEndPage(PdfWriter writer, Document document){
String text = writer.getPageNumber()+" ";
float footerBase = document.bottom() - 30;
float textSize = 8;
float adjust = 2;
PdfContentByte cb = writer.getDirectContent();
cb.beginText();
try {
cb.setFontAndSize(BaseFont.createFont(BaseFont.TIMES_ROMAN, "Cp1252",false), 12);
} catch(Exception ex){}
cb.setTextMatrix(document.right() - textSize - adjust, footerBase);
cb.showText(text);
cb.endText();
cb.addTemplate(total, document.right() - adjust, footerBase);
}
@Override
public void onCloseDocument(PdfWriter writer, Document document) {
total.beginText();
try {
total.setFontAndSize(BaseFont.createFont(BaseFont.TIMES_ROMAN, "Cp1252",false), 12);
} catch(Exception ex){}
total.setTextMatrix(0, 0);
total.showText(" di "+String.valueOf(writer.getPageNumber() - 1));
total.endText();
}
@Override
public void onParagraph(PdfWriter writer, Document dcmnt, float f) {
}
@Override
public void onParagraphEnd(PdfWriter writer, Document dcmnt, float f) {
}
@Override
public void onChapter(PdfWriter writer, Document dcmnt, float f, Paragraph prgrph) {
}
@Override
public void onChapterEnd(PdfWriter writer, Document dcmnt, float f) {
}
@Override
public void onSection(PdfWriter writer, Document dcmnt, float f, int i, Paragraph prgrph) {
}
@Override
public void onSectionEnd(PdfWriter writer, Document dcmnt, float f) {
}
@Override
public void onGenericTag(PdfWriter writer, Document dcmnt, Rectangle rctngl, String string) {
}
}
L'utilizzo di questa classe è immediato tramite il codice:
PDFManager pdfm = new PDFManager(true); \\initialize new instance and i want the page counting
pdfm.parseHTML("content","header"); \\it can be used tables, div, font, color, span ...
pdfm.writePDF("C:\\output.pdf"); \\set the output file name and path
pdfm.close(); \\free resources
Nessun commento:
Posta un commento