0

我需要使用 asp.net 从 html 动态生成 pdf。HTML存储在数据库中。HTML 有表格和 css,最多 10 页。我尝试iTextSharp过直接传递html,它会生成未打开的 pdf 。Destinationpdf.codeplex.com没有文档,它生成带有父页面样式的 PDF。

任何其他解决方案都会有所帮助。

4

1 回答 1

0

我尝试了许多 HTML 到 PDF 的解决方案,包括 iTextSharp、wkhtmltopdf 和 A​​BCpdf(付费)

我目前选择PhantomJS是一个无头、开源、基于 WebKit 的浏览器。它可以使用javascript API编写脚本,该 API有很好的文档记录。

我发现的唯一缺点是尝试使用stdin将 HTML 传递到进程中是不成功的,因为REPL仍然存在一些错误。我还发现使用stdout似乎比简单地允许进程写入磁盘要慢得多。

下面的代码通过将 javascript 输入创建为临时文件、执行 PhantomJS、将输出文件复制到 astdin并在最后清理临时文件来避免。stdoutMemoryStream

    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;
    }
于 2014-03-12T10:45:41.007 回答