iText tworzenie PDF,konwertowanie strony do PDF, Polskie znaki i kodowanie


iText to biblioteka na licencji GPL, która daje możliwość bardzo szybko tworzyć pliki PDF z dowolnego dokumentu html, xml, txt, itd. Oficialna strona iText »
Niżej pokazane przykłady pokazują, jak rozwiązać problem wyświetlenia polskich liter, w czasie transformacji z pliku lub strony HTML, do pliku formatu PDF przy użyciu biblioteki iText.
Na początku zaprezentuje klasę GenPDFdoc która pozwoli nam dokonać konwertacji strony HTML, podając jako dane wejściowe url strony.
Przykład:1

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.xhtmlrenderer.pdf.ITextRenderer;
import com.lowagie.text.DocumentException;

public class GenPDFdoc {
    public static void main()
    throws IOException, DocumentException {
        String HTMLpageUrl = "http://localhost:8080/PDF/strona.html"; // URL strony renderowanej .
        String PDFdoc = "C:\\ConvertedFile.pdf"; //Wyjściowy plik PDF
        OutputStream os = new FileOutputStream(PDFdoc);
        ITextRenderer renderer = new ITextRenderer();
        renderer.setDocument(HTMLpageUrl);
        renderer.layout();
        renderer.createPDF(os);
        os.close();
   }
}
Dla poprawnego działania tej klasy potrzebujemy biblioteki itext-paulo i core-renderer Pobrać biblioteki można tu core-renderer.jar i tu itext-paulo-155.jar
Przykładowa strona do konwertacji strona.html powinna wyglądać mniej więcej tak.
Przykład:2

<?xml version="1.0" encoding="UTF-8" ?>
<html>
<body>
<p>Strona do konwertowania .... nie uzywamy na razie polskich liter .. </p>
....
</body>
</html>
Próba użycia polskich liter spowoduje błąd renderowania. Polskie znaki diakrytyczne należy umieszczać na stronie w postaci kodów dziesiętnych (bo zajmują 2 bajty), więcej o tym można przeczytać tutaj » Np. literka ą powinna być pisana jako &#261;
Strona również powinna spełnić podstawowe reguły XHTML np. nie posiada znacznika <!DOCTYPE ... - definicji typu dokumentu, wszystkie tagi <..> powinny posiadać odpowiednio zamykający tag </..> w zagłówku strony warto umieścić definicje dokumentu XHTML i td. Teraz trochę o kodowaniu. Z dokumentacji iText wynika ze zmianę kodowania dokonujemy odwołując do klasy BaseFont zgodnie z konstruktorem np.

Przykład:3

.....
BaseFont bf = BaseFont.createFont("Helvetica", "ISO-8859-2", false);
Font modified_font = new Font(bf, 9 ,Font.NORMAL);
....
Paragraph p = new Paragraph("Dowolny tekst i Polskie znaki diakrytyczne... (ąśćźżęłóń)",modified_font);
document.add(p);
.....
W bibliotece itext-paulo Przykład 1 jest podobno, ale wywołanie metody createFont klasy BaseFont następuje z parametrami domyślnymi gdzie kodowanie ustawione jako CP1252, właśnie to i mamy zmienić.
Aby dokonać tej zmiany ściągamy żródło biblioteki z oficjalnej strony itext-paulo a dokładnie itext-paulo-155.zip
Następnie idziemy do klasy com.lowagie.text.pdf.BaseFont szukamy metody createFont i zamieniamy // encoding = normalizeEncoding(encoding);
encoding = "ISO-8859-2";
Zostaje tylko skompilować bibliotekę (lub ściągnąć juz przekompilowaną itext-paulo-155.jar) i ponownie uruchomić Przykład 1. Tym razem PDF powinien zawierać polskie literki Przykład 1 przedstawia odwołanie do strony statycznej co nie jest rozwiązaniem elastycznym w czasie tworzenia raportów i td. Dużo łatwiejszym jest rozwiązanie na Servlet Przykład 4
Przykład:4

import java.io.IOException;
import java.io.OutputStream;
import java.io.StringBufferInputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.xhtmlrenderer.pdf.ITextRenderer;

....
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

response.setContentType("application/pdf");
//response.setHeader("Content-Disposition", "attachment;filename=\"" + "nazwa-pliku.pdf" + "\"");
StringBuffer buf = new StringBuffer();
buf.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
buf.append("<html>");
buf.append("<body>... zawartość strony... </body>");
buf.append("</html>");

      try {
        DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        Document doc = builder.parse(new StringBufferInputStream(Escaping.escapeHTML(buf.toString())));
                 ITextRenderer renderer = new ITextRenderer();
        renderer.setDocument(doc, null);
        renderer.layout();
        OutputStream os = response.getOutputStream();
                 renderer.createPDF(os);
        os.close();
        } catch (Exception ex) {
        ex.printStackTrace();
        }
    }
Dodatkowe ułatwienie to klasa Escaping która zamienia polskie znaki diakrytyczne na kody dziesiętne. Przykład 5

Przykład:5

public class Escaping {

public static final String escapeHTML(String s){
   StringBuffer sb = new StringBuffer();
   int n = s.length();
   for (int i = 0; i < n; i++) {
    char c = s.charAt(i);
    switch (c) {
        case 'ą': sb.append("&#261;"); break;
        case 'ć': sb.append("&#263;"); break;
        case 'ę': sb.append("&#281;"); break;
        case 'ł': sb.append("&#322;"); break;
        case 'ń': sb.append("&#324;"); break;
        case 'ó': sb.append("&#243;"); break;
        case 'ś': sb.append("&#347;"); break;
        case 'ź': sb.append("&#378;"); break;
        case 'ż': sb.append("&#380;"); break;
        case 'Ą': sb.append("&#260;"); break;
        case 'Ć': sb.append("&#262;"); break;
        case 'Ę': sb.append("&#280;"); break;
        case 'Ł': sb.append("&#321;"); break;
        case 'Ń': sb.append("&#323;"); break;
        case 'Ó': sb.append("&#211;"); break;
        case 'Ś': sb.append("&#346;"); break;
        case 'Ź': sb.append("&#377;"); break;
        case 'Ż': sb.append("&#379;"); break;

       default: sb.append(c); break;
     }
  }

    return sb.toString();
}

}
Artykuł napisany w wolnym czasie, prawa autorskie W.S.
Wsparcie finansowe Autora Artykułu :