ASP.NET MVC: render view to generate PDF: use iTextSharp or better solution?
I display receipt in both HTML and printer-friendly version. HTML version does jQuery tabs, etc, while printer-friendly has zero scripts and external dependencies, no master 开发者_运维知识库layout, no additional buttons, inline CSS, and can be saved as HTML without problems.
Since I use Spark View Engine, I though maybe it's a good idea to generate PDF using iTextSharp engine. But after few paragraphs I decided it's too cumbersome, because a) I would have to rewrite entire receipt (source Spark view is about 5 pages long) b) I had problems with iTextSharp from beginning - for example, numbered lists kept bulleted, with no indentation, and indentationLeft="20" didn't work - maybe because of lack of documentation, but see (a).
So, my requirements for PDF are very simple: I want to keep the same HTML but insert page breaks between individual receipts (yes I have several ones in a single document).
Is there a simple way to generate PDF from view/HTML without rewriting the view using a strange half-documented engine?
UPDATE: tried community HTMLDoc version; didn't use my inline CSS styles, incorrectly displayed Unicode symbols for currencies. wkhtmltopdf did pick the CSS but failed for currency symbol; I suppose there's problem with encoding solved by setting charset to utf-8. wkhtmltopdf seems to be nice but I'm yet to figure out how to set page breaks...
If you can have the HTML in memory then you can convert it to PDF. I've once did something similar using xhtmlrenderer. It is a JAVA framework that bundles iText and that is capable of converting an HTML stream into PDF. As it is written in JAVA I've used the ikvmc.exe to convert the jar file into a .NET assembly and use it directly from managed code.
public class Pdf : IPdf
{
public FileStreamResult Make(string s)
{
using (var ms = new MemoryStream())
{
using (var document = new Document())
{
PdfWriter.GetInstance(document, ms);
document.Open();
using (var str = new StringReader(s))
{
var htmlWorker = new HTMLWorker(document);
htmlWorker.Parse(str);
}
document.Close();
}
HttpContext.Current.Response.ContentType = "application/pdf";
HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=MyPdfName.pdf");
HttpContext.Current.Response.Buffer = true;
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.OutputStream.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length);
HttpContext.Current.Response.OutputStream.Flush();
HttpContext.Current.Response.End();
return new FileStreamResult(HttpContext.Current.Response.OutputStream, "application/pdf");
}
}
}
Finally used wkhtmltopdf which works fine when I set encoding, I found out how to setup page breaks, and it processes my CSS very nice. On issue is that it can't correctly process stdin/out in Windows version (don't remember if it's in or out that doesn't work) - may be fixed in recent versions, but I'm ok with temp files.
精彩评论