我需要使用 asp.net 从 html 动态生成 pdf。HTML存储在数据库中。HTML 有表格和 css,最多 10 页。我尝试iTextSharp
过直接传递html,它会生成未打开的 pdf 。Destinationpdf.codeplex.com
没有文档,它生成带有父页面样式的 PDF。
任何其他解决方案都会有所帮助。
我需要使用 asp.net 从 html 动态生成 pdf。HTML存储在数据库中。HTML 有表格和 css,最多 10 页。我尝试iTextSharp
过直接传递html,它会生成未打开的 pdf 。Destinationpdf.codeplex.com
没有文档,它生成带有父页面样式的 PDF。
任何其他解决方案都会有所帮助。
我尝试了许多 HTML 到 PDF 的解决方案,包括 iTextSharp、wkhtmltopdf 和 ABCpdf(付费)
我目前选择PhantomJS是一个无头、开源、基于 WebKit 的浏览器。它可以使用javascript API编写脚本,该 API有很好的文档记录。
我发现的唯一缺点是尝试使用stdin
将 HTML 传递到进程中是不成功的,因为REPL仍然存在一些错误。我还发现使用stdout
似乎比简单地允许进程写入磁盘要慢得多。
下面的代码通过将 javascript 输入创建为临时文件、执行 PhantomJS、将输出文件复制到 astdin
并在最后清理临时文件来避免。stdout
MemoryStream
using System.IO;
using System.Drawing;
using System.Diagnostics;
public Stream HTMLtoPDF (string html, Size pageSize) {
string path = "C:\\dev\\";
string inputFileName = "tmp.js";
string outputFileName = "tmp.pdf";
StringBuilder input = new StringBuilder();
input.Append("var page = require('webpage').create();");
input.Append(String.Format("page.viewportSize = {{ width: {0}, height: {1} }};", pageSize.Width, pageSize.Height));
input.Append("page.paperSize = { format: 'Letter', orientation: 'portrait', margin: '1cm' };");
input.Append("page.onLoadFinished = function() {");
input.Append(String.Format("page.render('{0}');", outputFileName));
input.Append("phantom.exit();");
input.Append("};");
// html is being passed into a string literal so make sure any double quotes are properly escaped
input.Append("page.content = \"" + html.Replace("\"", "\\\"") + "\";");
File.WriteAllText(path + inputFileName, input.ToString());
Process p;
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = path + "phantomjs.exe";
psi.Arguments = inputFileName;
psi.WorkingDirectory = Path.GetDirectoryName(psi.FileName);
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
p = Process.Start(psi);
p.WaitForExit(10000);
Stream strOut = new MemoryStream();
Stream fileStream = File.OpenRead(path + outputFileName);
fileStream.CopyTo(strOut);
fileStream.Close();
strOut.Position = 0;
File.Delete(path + inputFileName);
File.Delete(path + outputFileName);
return strOut;
}