0

I have the code rendering PDF on the ASP.NET MVC server, but some characters for example e with accent (ě) are not shown correctly. The library I use is itextsharp-LGPL from nuget.

The PDF rendering code is:

protected ActionResult ViewPdf(object model)
{
    // http://www.codeproject.com/Articles/66948/Rendering-PDF-views-in-ASP-MVC-using-iTextSharp
    // Create the iTextSharp document.
    Document doc = new Document();
    // Set the document to write to memory.
    MemoryStream memStream = new MemoryStream();
    PdfWriter writer = PdfWriter.GetInstance(doc, memStream);
    writer.CloseStream = false;
    doc.Open();

    // Render the view xml to a string, then parse that string into an XML dom.
    string xmltext = this.RenderActionResultToString(this.View(model));
    XmlDocument xmldoc = new XmlDocument();
    xmldoc.InnerXml = xmltext.Trim();

    // Parse the XML into the iTextSharp document.
    ITextHandler textHandler = new ITextHandler(doc);
    textHandler.Parse(xmldoc);

    // Close and get the resulted binary data.
    doc.Close();
    byte[] buf = new byte[memStream.Position];
    memStream.Position = 0;
    memStream.Read(buf, 0, buf.Length);

    // Send the binary data to the browser.
    return new BinaryContentResult(buf, "application/pdf");
}

The Helper method of controller look like this:

public class PDFControllerBase : Controller
{
    protected string RenderActionResultToString(ActionResult result)
    {
        // Create memory writer.
        var sb = new StringBuilder();
        var memWriter = new StringWriter(sb);            

        // Create fake http context to render the view.
        var fakeResponse = new HttpResponse(memWriter);
        var fakeContext = new HttpContext(System.Web.HttpContext.Current.Request, fakeResponse);
        var fakeControllerContext = new ControllerContext(
            new HttpContextWrapper(fakeContext),
            this.ControllerContext.RouteData,
            this.ControllerContext.Controller);
        var oldContext = System.Web.HttpContext.Current;
        System.Web.HttpContext.Current = fakeContext;

        // Render the view.
        result.ExecuteResult(fakeControllerContext);

        // Restore data.
        System.Web.HttpContext.Current = oldContext;

        // Flush memory and return output.
        memWriter.Flush();
        string content = sb.ToString();
        return content;
    }
}

The view looks like:

@model MyNamespace.Model.MyModel

@{
    Layout = null;
}
<?xml version="1.0" encoding="UTF-8" ?>
<itext creationdate="2/4/2015 5:49:07 pm" producer="iTextSharpXML">
    <paragraph leading="18.0" font="arial" size="16.0" align="center">
        <chunk>@Model.Title</chunk><newline /><newline />
    </paragraph>
    <paragraph leading="18.0" font="arial" size="10.0" align="justify">
        <chunk>@Model.TextDetail</chunk><newline />        
    </paragraph>   
</itext>

I tried to add following code to PDF rendering, but it does not help:

string arial = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), "arial.ttf");
FontFactory.Register(arial, "arial");
Tomas Kubes
  • 23,880
  • 18
  • 111
  • 148
  • Please show us the link to itextsharp-LGPL on Nuget. You are using XML Worker and XML Worker didn't exist at the moment we abandoned the LGPL in favor of the AGPL. XML Worker is only available under the AGPL and it's not compatible with LGPL versions of iTextSharp. – Bruno Lowagie Aug 17 '15 at 10:27
  • So... you are using an AGPL version of iTextSharp (5.5.6) in combination with an LGPL version of iTextSharp (4.1.6)? How does that make sense? Why are you using two different versions of the library next to each other? – Bruno Lowagie Aug 17 '15 at 13:15
  • After you solve the license and library conflict, see [this](http://stackoverflow.com/a/6111416/231316) for a discussion on Unicode and [this](http://stackoverflow.com/a/14235010/231316) for an XMLWorker-specific solution – Chris Haas Aug 17 '15 at 13:49
  • @Chris Haas: I solved licence by removing itextSharp 5 and switching to itext XML. But still UTF-8 characters are not rendered correctly. There are no params textHandler.Parse. So where should I specify encoding? – Tomas Kubes Aug 17 '15 at 20:29
  • I'm confused, are you using XMLWorker 5.x alongside iTextSharp 4.x? Or are you using iTextSharp 1.x or 2.x and the XML DTD? – Chris Haas Aug 17 '15 at 20:56
  • iText doesn't directly read anything from disk and instead uses `System.IO` to perform all of the dirty work and if I remember correctly it uses `System.Text.Encoding.Default` for the encoding. If you put a BOM on the file you should be good. If that doesn't work, read the bytes yourself using the appropriate encoding and pass those those bytes into iText. However, **you must have a font available that supports every single Unicode character that you want to use.** iText includes the required default PDF fonts but those fonts only have a limited character set. – Chris Haas Aug 17 '15 at 21:05
  • No, I am using iTextSharp-LGPL 4.1.6 and XML DTD. It was the only way I managed to generate PDF from razor, so I can change PDF report without recompiling the application. Maybe not the newest, but hopefully sufficient. – Tomas Kubes Aug 17 '15 at 21:09

0 Answers0