2014-06-24 131 views
1

不確定是否在代碼中跳過了一個步驟,我正在使用ItextSharp版本5.5.1和XML Worker版本5.5.1。 doc.Close拋出一個異常「文檔沒有頁面」,但我看了sw.toString(它有html內容)。使用Itextsharp(XMLWorker)將Asp.net頁面轉換爲pdf返回已損壞/空白pdf

private void ExporttoPDF() 
     { 
      HttpContext.Current.Response.Clear(); 
      HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=RequestSummaryReport.pdf"); 
      HttpContext.Current.Response.Charset = ""; 
      HttpContext.Current.Response.ContentType = "application/pdf"; 

      StringWriter sw = new StringWriter(); 
      HtmlTextWriter htw = new HtmlTextWriter(sw);   

      var doc = new Document(PageSize.A3, 45, 5, 5, 5); 
      PdfWriter writer = PdfWriter.GetInstance(doc, Response.OutputStream); 

      doc.Open(); 

      HtmlPipelineContext htmlContext = new HtmlPipelineContext(null); 
      htmlContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory()); 
      ICSSResolver cssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(false); 

      IPipeline pipeline = new CssResolverPipeline(cssResolver, new HtmlPipeline(htmlContext, new PdfWriterPipeline(doc, writer))); 

      XMLWorker worker = new XMLWorker(pipeline, true); 
      XMLParser xmlParse = new XMLParser(true, worker); 

      pnlReport.RenderControl(htw); 
      StringReader sr = new StringReader(sw.ToString()); 
      xmlParse.Parse(sr); 
      xmlParse.Flush(); 
      doc.Close(); 
      Response.Write(doc); 
     } 
+0

起初看起來大多是正確的。您直接寫入HTTP響應流,因此不需要執行Response.Write(doc);(該行不會執行大多數人認爲它的操作)。我手邊沒有一個ASP.Net服務器,所以我用'StringReader sr = new StringReader'(「Hello」)嘗試了它;'並且它工作正常。 –

回答

0

我剛剛花了差不多兩個小時就出現了同樣的症狀,最後找出了問題的原因。我猜你可能已經找到了答案(因爲這個問題在5個月前被問過),但我想我會提供答案,以防其他人遇到同樣的問題。

當您創建PdfWriter時,您傳入的流(您的情況爲Response.OutputStream)將成爲生成的PDF內容的目標。當PdfWriter將內容寫入流時,流的位置會相應增加。當作者完成時,流位置在內容的末尾,這是有道理的,因爲任何進一步的寫入調用應該繼續在PdfWriter停止的位置。

問題是,當MVC管道採用Response.OutputStream(在您的方法返回後)並嘗試讀取它以將其內容發送到客戶端(或者通常,每當使用PDF目標流時),流位置在內容的末尾,這意味着對於消費者來說,該流看起來是空的,因此是空的PDF輸出。

要解決這個問題,只需在完成寫入之後立即重置流的位置,然後再嘗試從中讀取數據。在你的情況下插入:

Response.OutputStream.Position = 0; 

xmlParse.Flush()行之後,因爲這是將寫入數據流的最後一行。