【问题标题】:Conversion from HTML to pdf generates an exception从 HTML 转换为 pdf 会产生异常
【发布时间】:2018-04-01 20:26:37
【问题描述】:

我有一个小型 C# 桌面应用程序,它创建一个给定一些 HTML 的 pdf 文件,从 *.eml 文件中检索。 这是一个示例:

<html>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
 <div style="font: normal 13px Arial; color:#000000;">
  <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><font size="3"><font face="Calibri">Some text<o:p></o:p></font></font><br />
  </p>
  <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><o:p><font size="3" face="Calibri">&nbsp;</font></o:p><br />
   <span style="FONT-SIZE: 11pt; FONT-FAMILY: &quot;Calibri&quot;,&quot;sans-serif&quot;; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: &quot;Times New Roman&quot;; mso-fareast-language: EN-US; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-theme-font: minor-bidi; mso-ansi-language: IT; mso-bidi-language: AR-SA">Some other text</span>
  </p>
 </div>
</body>
</html>

在我的机器 (Win10 x64) 上一切正常,但是当我在客户端机器 (Win Server 2008 R2 x64) 上运行相同的代码时,我从 iTextsharp 异常中收到“文档没有页面”消息。

这种情况有时会发生,对于特定的 HTML 字符串,比如我刚刚发布的那个;我无法在客户端机器上运行调试会话,但是我验证了程序接收到格式正确的 HTML(因为它是使用 HTML Agility Pack 解析的)。

这可能是与字体相关的问题吗?我完全不知道,这些似乎存在于客户端的机器上。

这是我用于创建 pdf 文档的代码的 sn-p(它使用自定义图像标签处理器,尽管它不应该是问题,因为给定的 sn-p 中没有任何问题):

using (var document = new Document())
{
    var writer = PdfWriter.GetInstance(document, new FileStream(destinationPath, FileMode.Create));
    writer.CompressionLevel = PdfStream.BEST_COMPRESSION;
    document.Open();

    var tagProcessors = (DefaultTagProcessorFactory)Tags.GetHtmlTagProcessorFactory();
    tagProcessors.RemoveProcessor(HTML.Tag.IMG);
    tagProcessors.AddProcessor(HTML.Tag.IMG, new CustomImageTagProcessor());
    CssFilesImpl cssFiles = new CssFilesImpl();
    cssFiles.Add(XMLWorkerHelper.GetInstance().GetDefaultCSS());
    var cssResolver = new StyleAttrCSSResolver(cssFiles);
    cssResolver.AddCss(@"code { padding: 2px 4px; }", "utf-8", true);
    var charset = Encoding.UTF8;
    var hpc = new HtmlPipelineContext(new CssAppliersImpl(new XMLWorkerFontProvider()));
    hpc.SetAcceptUnknown(true).AutoBookmark(true).SetTagFactory(tagProcessors);
    var htmlPipeline = new HtmlPipeline(hpc, new PdfWriterPipeline(document, writer));                            
    var pipeline = new CssResolverPipeline(cssResolver, htmlPipeline);
    var worker = new XMLWorker(pipeline, true);
    var xmlParser = new XMLParser(true, worker, charset);
    xmlParser.Parse(new StringReader(fixedMarkup));
}

【问题讨论】:

    标签: c# itext xmlworker


    【解决方案1】:

    您应该迁移到 pdfHTML,它是 iText7(iText 的最新版本)插件,可将 HTML 转换为 PDF。 多年来,许多错误(通常与表格、字体和布局有关)已修复,因此默认情况下 pdfHTML 更有可能进行转换。

    示例代码:

    HtmlConverter.convertToPdf(
        "<b>This text should be written in bold.</b>", 
        new PdfWriter(new File("C://users/mentre83/output.pdf")));
    

    【讨论】:

    • 感谢您的建议,我将尝试获得试用许可证以验证这是否是更好的解决方案。我仍然想确定两台机器上不同行为的原因。
    • 我认为(但这更多地基于经验而不是实际运行您的代码)它可能需要对字体或其他在一台计算机上不可用但在另一个。例如,如果一个字形不能被渲染(因为字体没有那个字形),iText 根本不会渲染那个字符。如果您的所有字符都被跳过,则不会添加任何内容,并且您会收到“文档没有页面”异常。并且 Arial unicode 并非在所有机器上都可用。
    • 我的想法完全正确。虽然字形似乎不是问题,但我怀疑这与字体有关。在资源方面,我用来测试代码的机器(我也在一些虚拟机上尝试过)似乎几乎相同。
    【解决方案2】:

    发现问题。正如我所怀疑的,它与字体有关。

    在我的机器上,Calibri 字体可以嵌入到 *.pdf 文档中,而在其他机器上,它的“字体嵌入性”属性设置为“受限”。

    我想我必须解析 HTML 并将“字体系列”标签中的所有值更改为非限制值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-30
      • 1970-01-01
      • 1970-01-01
      • 2015-03-08
      • 1970-01-01
      • 2014-06-09
      相关资源
      最近更新 更多