2016-12-05 209 views
0

編輯:下面提出了完美的解決方案(流以錯誤的順序關閉)。我最終選擇了PreMailer.Net + HtmlAgilityPack + wkHTMLtoPDF的開源替代方案,因爲它更符合我的需求。執行iTextSharp將HTML轉換爲PDF的難題

我試圖在C#中實現iTextSharp將HTML轉換爲PDF文件,包括轉換鏈接和圖像的相對URI。我有一個非常基本的實現「更改默認配置」(http://demo.itextsupport.com/xmlworker/itextdoc/flatsite.html),從Java轉換爲C#,以嘗試一下。然而,當通過一個文本編輯器編輯的樣本HTML(我已經測試過),我送入我的腳本返回我創建的PDF以下內容:

%PDF-1.4 
%âãÏÓ 

這似乎是錯誤的。另外,MemoryStream只有很少的字節與它關聯。我的iTextSharp實現有問題,或者我使用流或其他C#構造不正確?

using System.IO; 
using System.Text; 
using iTextSharp.text; 
using iTextSharp.text.pdf; 
using iTextSharp.tool.xml.html; 
using iTextSharp.tool.xml.pipeline.html; 
using iTextSharp.tool.xml; 
using iTextSharp.tool.xml.parser; 
using iTextSharp.tool.xml.pipeline.css; 
using iTextSharp.tool.xml.pipeline.end; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     FontFactory.RegisterDirectories(); 
     var document = new Document(); 
     var memoryStream = new MemoryStream(); 
     var pdfWriter = PdfWriter.GetInstance(document, memoryStream); 
     document.Open(); 

     var htmlContext = new HtmlPipelineContext(null); 
     htmlContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory()); 
     htmlContext.SetImageProvider(new ImageProvider()); 
     htmlContext.SetLinkProvider(new LinkProvider()); 
     htmlContext.CharSet(Encoding.UTF8); 

     var cssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(true); 
     var pipeline = new CssResolverPipeline(cssResolver, new HtmlPipeline(htmlContext, new PdfWriterPipeline(document, pdfWriter))); 
     var xmlWorker = new XMLWorker(pipeline, true); 
     var xmlParser = new XMLParser(xmlWorker); 

     var inputFileStream = new FileStream("testHTML.html", FileMode.Open); 
     xmlParser.Parse(inputFileStream); 
     inputFileStream.Close(); 

     memoryStream.Position = 0; 
     pdfWriter.CloseStream = false; 

     var outputFileStream = new FileStream("testOutput.pdf", FileMode.Create, FileAccess.Write); 
     memoryStream.WriteTo(outputFileStream); 

     outputFileStream.Close(); 
     document.Close(); 
    } 
} 

class ImageProvider : AbstractImageProvider 
{ 
    public override string GetImageRootPath() 
    { 
     return "testDir/"; 
    } 
} 

class LinkProvider : ILinkProvider 
{ 
    public string GetLinkRoot() 
    { 
     return "http://www.examplesite.com/testdir/"; 
    } 
} 

非常感謝您的時間和幫助!

memoryStream.WriteTo(outputFileStream); 

    outputFileStream.Close(); 
    document.Close(); 

但關閉文檔時,才iText的完成輸出PDF,特別是沖洗當前最後一頁的內容,並補充說:

+0

我沒有看到你正在寫'pdfWriter'的任何東西。你期望它打印什麼? –

+0

我曾打算將HTML的內容打印爲PDF –

+0

但是,您得到'testHTML.html',但從不對數據做任何事情。 –

回答

1

您關閉iText的document前搶內存流的內容交叉引用等

因此,你的代碼

memoryStream.Position = 0; 
    pdfWriter.CloseStream = false; 

    var outputFileStream = new FileStream("testOutput.pdf", FileMode.Create, FileAccess.Write); 
    memoryStream.WriteTo(outputFileStream); 

    outputFileStream.Close(); 
    document.Close(); 

改變這個

pdfWriter.CloseStream = false; 
    document.Close(); 

    var outputFileStream = new FileStream("testOutput.pdf", FileMode.Create, FileAccess.Write); 
    memoryStream.Position = 0; 
    memoryStream.WriteTo(outputFileStream); 
    outputFileStream.Close();