Forum How do I...?

[C#] Fill pdfs with content from xml file

Zoba
Hi,

i wanted to know if i could use Prince to generate pdfs from html + css and fill the page with variables, and if possible - how?

I want to use a default invoice.html file with a default css-file to generate said invoices with .net and fill the necessary information through an xml file that should be read by my program.

This is a sample of my current xml file. Every Document node should be run through and each item that is found in the html file should be replaced by the given item in the xml file.

[CODE]<?xml version="1.0" encoding="utf-8"?>
<PdfPrinter>
<Document>
<FNR>FNR</FNR>
<ID>ID</ID>
<KNR>123456</KNR>
</Document>
<Document>
<FNR>10</FNR>
<ID>123456 701</ID>
<KNR>123456</KNR>
</Document>
</PdfPrinter> [/CODE]

Do i have to generate a html file with variable fillers (e.g %%FNR%%) then read said html and build a new string with me replacing each variable, or is there a more... refined way of doing it?
mikeday
People will usually use a template system for doing variable substitutions, such as XSLT, or PHP, or one of the many JavaScript templating systems. Searching for "C# html template" should bring up some useful tips. String replace will also work, but you just need to be careful and make sure that it is sufficiently reliable.
Zoba
what is the key advantage of prince then compared to xsl-fo, if i also have to substitute via xslt? And could i use razorEngine?

Edited by Zoba

mikeday
Many people find HTML + CSS to be a more comfortable method than XSL-FO for designing, since they are already familiar with using it for designing websites. You don't have to use XSLT, there are many ways of generating the HTML; RazorEngine looks fine.
larjo
I work in dotnet (f#) and I use mustache for templating which works very well. (mustache.github.io)

This project, github.com/jdiamond/Nustache, isn't actively updated anymore it seems but the implementation is rock solid and fast. I create quite large and complicated reports and I'm very happy with it:-)
Zoba
Hey, thanks for the tip larjo. Nustache works flawlessly with the my json request i've parsed into xml. Now i've got another question for mikeday.

This is how i generate a couple of pdfs filled with my test setup here: I made a json request for 31 seperate files, but prince merely creates 6-10 files depending on the run. Is that a limitation of the free .dll or is something wrong with my code? deserializedRequest shows 31 objects in the array (which is correct).

dynamic deserializedRequest = JsonConvert.DeserializeObject(json);
foreach (var item in deserializedRequest)
{
string pdfPath = defaultPath + "pdf\\" + DateTime.Now.ToString("ddMMyyyy-HHmmss") + ".pdf";


Render.FileToFile(template, item, output);

// instantiate Prince by specifying the full path to the engine executable
Prince prn = new Prince(@"C:\Program Files\PrinceXML\bin\prince.exe");

// specify the log file for error and warning messages
// make sure that you have write permissions for this file
prn.SetLog(@"C:\docs\log.txt");

// apply a CSS style sheet (optional)
prn.AddStyleSheet(@"C:\docs\css\stylesheet-1.css");

// convert a HTML document into a PDF file
prn.Convert(output, pdfPath);
}
mikeday
Check the return value of the Convert method to ensure that it is succeeding, and see if any error or warning messages are showing up in the log file.
Zoba
My log shows only successful runs:

https://gist.github.com/Zoba273/3ded4d85e209bbfa5fd7c5217ff1fbba

i'll look into failing runs
Zoba
Um... the dumbest error in the history errors happened there... i just took the date + milliseconds. But the tool is faster than 1 pdf per second => overwrote the file... added Guid.NewGuid() and it works like a charm. I'll be off and create stuff.. :) thanks for the help!
mikeday
Nice! :D