2017-10-20 95 views
0

我有一個小的C#桌面應用程序,創建一個PDF文件,給出一些HTML,從* .eml文件中檢索。 下面是一個示例:從HTML到PDF轉換生成一個異常

<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)的就好了,但是當我運行在客戶機(贏服務器2008 R2 x64)的相同的代碼,我得到了「文檔中有無iTextsharp異常的「頁面」消息。

對於特定的HTML字符串,例如我剛發佈的字符串,這種情況有時只會發生;我無法在客戶端的機器上運行調試會話,但是我證實程序接收到格式良好的HTML(因爲它是用HTML Agility Pack進行分析的)。

這是一個與字體相關的問題嗎?我完全沒有線索,這些似乎出現在客戶端的機器上。

下面是我用它來創建PDF文檔的代碼片段(它使用的自定義圖像標籤處理器,但它不應該成爲問題,因爲沒有任何給定片斷):

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)); 
} 

回答

1

發現的問題。正如我懷疑的那樣,它與字體有關。

在我的機器上,Calibri字體可以嵌入* .pdf文檔,而在其他機器上,其「字體嵌入性」屬性設置爲「受限制」。

我想我將不得不解析HTML並將「字體家族」標籤中的所有值更改爲非限制性的值。

1

您應該遷移到PDFHTML,即將HTML轉換爲PDF的iText7(最新版本的iText)插件。 多年來修復了很多bug(與表格,字體和佈局有關),因此默認情況下,pdfHTML更有可能進行轉換。

示例代碼:

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

感謝您的建議,我會嘗試獲得試用許可證以驗證這是否是更好的解決方案。我仍然想確定兩臺機器上不同行爲的原因。 – mentre83

+0

我認爲(但是這基於更多的經驗,而不是實際運行代碼),它可能需要對字體或其他資源在一臺計算機上不可用,但在另一臺計算機上可用。例如,如果字形不能被渲染(因爲字體沒有那個字形),iText將不會渲染那個字符。如果所有角色都被跳過,則不會添加任何內容,並且您會看到「文檔沒有頁面」例外。 Arial unicode在所有機器上都不可用。 –

+0

我的想法。雖然字形似乎不是問題,但我懷疑這與字體有關。在資源方面,我用來測試代碼的機器(我也在幾臺虛擬機上試過)似乎幾乎完全相同。 – mentre83