Friday 17 July 2009

ItexSharp generowanie dokumentów PDF z zewnętrznego dokumentu XML wraz z polskimi znakami

Ostatnio musiałem wygenerować dokumenty PDF z zewnętrznych dokumentów XML myślę sobie OK! … użyje biblioteki ITexSharp (port dla .NET C# z iText, a free Java-Pdf libr ary ), jest szybka i pozwala w prosty sposób generować dokumenty PDF. Dokumentacja jest przejrzysta znajduje się nawet przykładowy parser. No ale jak to w życiu bywa... pojawił się problem z generowanie polskich znaków w dokumentach PDF.

Przykładowy parser dostępny w dokumentacji biblioteki w ogóle nie uwzględnia polskich znaków


using System;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.xml;
using iTextSharp.text.pdf;

public class XmlToPdf
{

public static void Main()
{

Console.WriteLine("XML to PDF conversion example");

// step 1: creation of a document-object
Document document = new Document();

try
{

// step 2:
// we create a writer that listens to the document
// and directs a XML-stream to a file
PdfWriter.GetInstance(document, new FileStream("document.pdf", FileMode.Create));

// step 3: we create a parser
ITextHandler xmlHandler = new ITextHandler(document);

// step 4: we parse the document
xmlHandler.Parse("document.xml");
}
catch (Exception e)
{
Console.Error.WriteLine(e.StackTrace);
Console.Error.WriteLine(e.Message);

if (e.InnerException != e)
{
Console.Error.WriteLine(e.InnerException.Message);
}
}
finally
{
Console.WriteLine("Finished - Hit any enter to close this window.");
}

Console.ReadLine();
}
}


Przeglądając różne grupy dyskusyjne znalazłem trochę rozwiązań ale jak już działało to z użyciem „hardcode” czyli dokument XML był zakodowany w wewnątrz plików *.cs .

Metodą testów udało mi się dojść do rozwiązania problemu mianowicie jeśli mamy wygenerować dokument PDF z wykorzystaniem ItexSharp z zewnętrznych dokumentów XML musimy zmodyfikować naszego parsera dokumentów przykład poniżej.

Zmodyfikowany parser :


using System;
using System.Text;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.xml;
using iTextSharp.text.pdf;
using iTextSharp.text.factories;
using iTextSharp.text.html;

namespace generationDocument
{

public class xmlToPdf
{
public static void Main()
{
Console.WriteLine(
"XML to PDF conversion");
BaseFont arial = BaseFont.CreateFont(
@"C:\WINDOWS\Fonts\arial.ttf", "iso-8859-2", BaseFont.EMBEDDED);
Font font = newFont(arial, 9);
//creation of a document-object
Document document = newDocument();
try
{
PdfWriter.GetInstance(document, newFileStream(
"generowanyDokument.pdf", FileMode.Create));
//create a parser
ITextHandler xmlHandler = newITextHandler(document, newHtmlTagMap(), arial);
//parse the document

xmlHandler.Parse(
"generowanyDokument.xml");

}

catch (Exception e)
{
Console.Error.WriteLine(e.StackTrace);
Console.Error.WriteLine(e.Message);
if (e.InnerException != e)
{
Console.Error.WriteLine(e.InnerException.Message);
}

}
finally
{
Console.WriteLine(
"Finished - Hit any enter to close this window.");
}
Console.ReadLine();
}

}
}


W ten oto sposób uzyskamy upragnione polskie znaki w naszych dokumentach PDF.

Dodam że dokument XML musi być zakodowany w formacie utf-8. Przykładowy dokument XML znajduje się poniżej :


<?xml version="1.0" encoding="utf-8" ?>

<itext>

<list numbered="false" symbolindent="350" first="-2" listsymbol="" font="Helvetica" size="20.0" fontstyle="bold">

<listitem leading="18.0" font="unknown" align="Default" indentationleft="20.0">

.....................

</listitem>

</list>

<paragraph leading="18.0" font="unknown" align="Default">

.....................

</paragraph>

<paragraph leading="18.0" font="unknown" align="Default">

.....................

</paragraph>

<paragraph leading="18.0" font="unknown" align="Default">

.....................

</paragraph>

<paragraph leading="18.0" font="unknown" align="Default">

<newline />

</paragraph>

<table columns="0" width="100%" height ="100%" align="Center" borderwidth="0.0" left="true" right="true" top="true" bottom="true" red="0" green="0" blue="0">

<row>

<cell rowspan="0" borderwidth="0.0" left="false" right="false" top="true" bottom="true" horizontalalign="Center" verticalalign="Center" header="true" leading="18.0">

<paragraph leading="10.0" font="arial" size="20.0" align="Center">Przykład : </paragraph>

<paragraph leading="18.0" font="unknown" align="Default">

<newline />

</paragraph>

</cell>

</row>

</table>

<paragraph leading="18.0" font="unknown" align="Center">

<newline />

</paragraph>

<paragraph leading="18.0" font="unknown" align="Center">

<newline />

</paragraph>



<paragraph leading="6.0" font="unknown" align="Center">

<newline />

</paragraph>

<paragraph leading="18.0" font="arial" align="Default">

Polskie Znaki ąśęółźżć

</paragraph>

<paragraph leading="18.0" font="unknown" align="Default">

<newline />

</paragraph>

<list numbered="false" symbolindent="350" first="-2" listsymbol="" font="Helvetica" size="20.0" fontstyle="bold">

</list>

<paragraph leading="18.0" font="unknown" align="Center">

<newline />

</paragraph>

</itext>


Przykładowo wygenerowany dokument PDF z powyższego pliku XML



Mam nadzieje że ten krótki tekst zaoszczędzi trochę czasu oraz nerwów tym, którzy borykają się z problemem generowania polskich znaków z wykorzystaniem ItexSharp.

Strona domowa biblioteki ItexSharp : http://itextsharp.sourceforge.net/

Artykuł został również opublikowany w serwisie codeguru.pl pod adresem :
www.codeguru.pl/Default.aspx?Page=Articles/Details&pubid=761




Monday 6 July 2009

Break Stereotype...

Zauważyłem że pisząc mojego skromnego bloga napotkać można pewną cykliczność co roku max cztery wpisy... :D Stereotyp w tym roku został przełamany i pojawił się o to szósty post :)