【问题标题】:itextsharp generates blank PDF on server but works on dev machine in MVCitextsharp 在服务器上生成空白 PDF,但在 MVC 中的开发机器上工作
【发布时间】:2017-05-22 01:57:09
【问题描述】:

我正在使用 itextsharp 在 MVC 应用程序中生成 PDF,这在开发机器上运行良好。当我在预生产机器上部署它时,这会生成空白 PDF 页面,也不例外。我尝试使用日志记录进行快速调试,以查看在StringReader sr = new StringReader(sb.ToString()); 行之后是否获取内容,我发现它有内容。

经过一番研究,我发现一个人遇到了类似的问题,他只是在PdfWriter.GetInstance 之后写document.Open() 解决了这个问题。来源:"The document is not open" error only in production with iTextSharp

在那之后,我想使用适用于许多开发人员How to convert HTML to PDF using iTextSharp 的代码,我仍然在预生产中看到空白 PDF,但在开发机器上工作。

我怀疑 itextsharp 是否对操作系统或办公套装有某种依赖性(带有 itextsharp 最新更新),因为正如我所说,它可以在开发机器上运行。

这是在生产机器 Windows Server 2012 R2 上生成空白 PDF 的代码。

public ActionResult DownloadOrderReceipt(string id)
{
    string companyName = "Name Here";
    int orderNo = 2303;
    DataTable dt = new DataTable();
    dt.Columns.AddRange(new DataColumn[5]
    {
            new DataColumn("ProductId", typeof(string)),
            new DataColumn("Product", typeof(string)),
            new DataColumn("Price", typeof(int)),
            new DataColumn("Quantity", typeof(int)),
            new DataColumn("Total", typeof(int))
    });
    dt.Rows.Add(101, "Sun Glasses", 200, 5, 1000);
    dt.Rows.Add(102, "Jeans", 400, 2, 800);
    dt.Rows.Add(103, "Trousers", 300, 3, 900);
    dt.Rows.Add(104, "Shirts", 550, 2, 1100);

    using (StringWriter sw = new StringWriter())
    {
        using (HtmlTextWriter hw = new HtmlTextWriter(sw))
        {
            StringBuilder sb = new StringBuilder();

            // generate invoice header
            sb.Append("<table width='100%' cellspacing='0' cellpadding='2'>");
            sb.Append("<tr><td align='center' style='background-color: #18B5F0' colspan = '2'><b>Order Sheet</b></td></tr>");
            sb.Append("<tr><td colspan = '2'></td></tr>");
            sb.Append("<tr><td><b>Order No: </b>");
            sb.Append(orderNo);
            sb.Append("</td><td align = 'right'><b>Date: </b>");
            sb.Append(DateTime.Now);
            sb.Append(" </td></tr>");
            sb.Append("<tr><td colspan = '2'><b>Company Name: </b>");
            sb.Append(companyName);
            sb.Append("</td></tr>");
            sb.Append("</table>");
            sb.Append("<br />");

            // generate invoice items grid
            sb.Append("<table border = '1'>");
            sb.Append("<tr>");
            foreach (DataColumn column in dt.Columns)
            {
                sb.Append("<th style = 'background-color: #D20B0C;color:#ffffff'>");
                sb.Append(column.ColumnName);
                sb.Append("</th>");
            }
            sb.Append("</tr>");
            foreach (DataRow row in dt.Rows)
            {
                sb.Append("<tr>");
                foreach (DataColumn column in dt.Columns)
                {
                    sb.Append("<td>");
                    sb.Append(row[column]);
                    sb.Append("</td>");
                }
                sb.Append("</tr>");
            }
            sb.Append("<tr><td align = 'right' colspan = '");
            sb.Append(dt.Columns.Count - 1);
            sb.Append("'>Total</td>");
            sb.Append("<td>");
            sb.Append(dt.Compute("sum(Total)", ""));
            sb.Append("</td>");
            sb.Append("</tr></table>");

            // export html string into PDF
            StringReader sr = new StringReader(sb.ToString());
            Document pdfDoc = new Document(PageSize.A4, 10f, 10f, 10f, 0f);
            HTMLWorker htmlparser = new HTMLWorker(pdfDoc);
            PdfWriter writer = PdfWriter.GetInstance(pdfDoc, Response.OutputStream);
            pdfDoc.Open();
            htmlparser.Parse(sr);
            pdfDoc.Close();
            Response.ContentType = "application/pdf";
            Response.AddHeader("content-disposition", "attachment;filename=Invoice_" + orderNo + ".pdf");
            Response.Cache.SetCacheability(HttpCacheability.NoCache);
            Response.Write(pdfDoc);
            Response.End();
        }
    }


    return new EmptyResult();
}

非常感谢您对此的任何帮助。

更新了 1(还是同样的问题)

我刚刚根据建议更新并简化了我的代码,但我仍然看到同样的问题:

public ActionResult DownloadOrderReceipt(string id)
{
    var order = orderRepository.Get(id);
    if (order == null)
        return new EmptyResult();

    using (MemoryStream stream = new MemoryStream())
    {
        string htmlContent = "<p>Write this on PDF Page</p>";
        StringReader sr = new StringReader(htmlContent);
        Document pdfDoc = new Document(PageSize.A4, 10f, 10f, 100f, 0f);
        PdfWriter writer = PdfWriter.GetInstance(pdfDoc, stream);
        pdfDoc.Open();
        XMLWorkerHelper.GetInstance().ParseXHtml(writer, pdfDoc, sr);
        pdfDoc.Close();
        return File(stream.ToArray(), "application/pdf", "Invoice_121212.pdf");
    }
}

这也适用于开发机器,但在预生产时会生成空白 PDF 页面。

更新了 2(还是同样的问题)

我尝试在前期制作中解决此问题。这是我刚刚尝试过的另外两个示例,但没有任何帮助。

public ActionResult DownloadOrderReceipt(string id)
{
    byte[] bytes;
    using (var ms = new MemoryStream())
    {
        using (var doc = new Document())
        {
            using (var writer = PdfWriter.GetInstance(doc, ms))
            {
                doc.Open();

                var example_html = @"<p>This <em>is </em><span class=""headline"" style=""text-decoration: underline;"">some</span> <strong>sample <em> text</em></strong><span style=""color: red;"">!</span></p>";
                var example_css = @".headline{font-size:200%}";

                // example 1
                //using (var srHtml = new StringReader(example_html))
                //{
                //    XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, srHtml);
                //}

                // example 2
                using (var msCss = new MemoryStream(Encoding.UTF8.GetBytes(example_css)))
                {
                    using (var msHtml = new MemoryStream(Encoding.UTF8.GetBytes(example_html)))
                    {
                        XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, msHtml, msCss);
                    }
                }

                doc.Close();
            }
        }

        bytes = ms.ToArray();
    }

    Response.ContentType = "application/pdf";
    Response.AddHeader("content-disposition", "attachment;filename=Invoice_1212121212.pdf");
    Response.Cache.SetCacheability(HttpCacheability.NoCache);
    Response.BinaryWrite(bytes);
    Response.End();

    return new EmptyResult();
}

解决方案

很久以后更新这个问题,因为我注意到新的 cmets。 在代码审查过程中,我发现开发人员编写了动态缩小 HTML 内容的逻辑,这也导致了从 PDF 中删除的内容,从而导致 PDF 为空。

【问题讨论】:

  • (1.) 您正在使用已弃用的 HTMLWorker。阅读FAQ,请理解关于HTMLWorker 的问题不再得到答复。 (2.) 如果你得到一个看起来像 PDF 的文件,但它只包含空白页,你就会遇到编码问题:你将 二进制文件 视为纯 ASCII。请参阅stackoverflow.com/questions/20890291/itext-pdf-shows-blank-page(您的问题可能重复)。
  • 所以原因很可能是您的生产服务器上Response.OutputStream 的配置。该生产服务器假定您正在生成 HTML(纯文本),但您正在生成 PDF(这是一种二进制文件格式)。 PDF 的结构是纯 ASCII,这就是您的 PDF 查看器可以显示页面的原因。但是 PDF 文件中每一页的内容都是压缩的(和二进制的)。您的服务器使这些字节损坏。
  • 感谢布鲁诺的快速回复。如果您知道,我们是否有一些更新的 .NET 示例,请分享。
  • @BrunoLowagie 只是用最新和简化的代码更新我的问题,但我仍然看到完全相同的问题。这次没有 HTMLWorker 或纯 ASCII。
  • 向我们展示损坏的 PDF。您承认代码可以在一台机器上运行,但不能在另一台机器上运行。 这意味着您的问题不是由 iTextSharp 引起的。您当然明白分享 有效的代码然后问为什么不这样做是没有意义的这行得通吗? 您的服务器有 90% 的机会“减少字节数”。不幸的是,您似乎不明白这个答案的含义,但是如果您共享两个文件(一个在您的机器上正确创建的文件和一个不正确的文件),我可以向您展示区别和希望您能相信自己的眼睛并理解。

标签: asp.net-mvc pdf model-view-controller pdf-generation itext


【解决方案1】:

这对我有用,MemoryStream 很重要:

    public class PDFController : Controller
    {
    // GET: PDF
    public ActionResult Index(string address)
    {
        SelectPdf.HtmlToPdf converter = new SelectPdf.HtmlToPdf();
        SelectPdf.PdfDocument doc = converter.ConvertUrl(address);
        var bytes = doc.Save();
        MemoryStream mstream = new MemoryStream(bytes);
        doc.Close();
        Response.ContentType = "application/pdf";
        Response.AddHeader("content-disposition", "attachment;filename=kundenvereinbarung.pdf");
        Response.Buffer = true;
        mstream.WriteTo(Response.OutputStream);
        Response.End();
        return null;
    }
}

【讨论】:

  • 我不想为了类似的目的使用另一个库,我希望你已经介绍了 SelectPdf 包。
  • @AbhimanyuKumarVatsa 图书馆不是重点。这是关于安全的。 IIS 应用程序池的权限与您的本地用户帐户不同,例如 windows 临时文件夹。
猜你喜欢
  • 2016-02-15
  • 1970-01-01
  • 2011-05-30
  • 2011-03-02
  • 1970-01-01
  • 1970-01-01
  • 2012-03-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多