2012-09-03 39 views
5

我在使用Windows Form程序的 中的HTMLWorker.Parse從iTextSharp出現問題。每當我執行代碼時,它都會從HTMLWorker.Parse開始,它會給出objectDisposedException。 該例外說明它無法訪問已關閉的文件。但我多次檢查了 ,無法找到已關閉的文件。下面是代碼:Itextsharp HTMLWorker.Parse錯誤

class HtmlToPdfConverter 
{ 
      private iTextSharp.text.Document doc = new iTextSharp.text.Document(); 

    public HtmlToPdfConverter() 
    { 
     this.doc.SetPageSize(PageSize.A4); 

    } 

    public string Run(string html, string pdfName) 
    { 
     try 
     { 
      using (doc) 
      { 
       StyleSheet styles = new StyleSheet(); 
       using (PdfWriter writer = PdfWriter.GetInstance(this.doc, new  FileStream(@"Z:\programs\" + pdfName + ".pdf", FileMode.Create))) 
       { 
        this.doc.Open(); 
        this.doc.OpenDocument(); 
        this.doc.NewPage(); 
        if (this.doc.IsOpen() == true) 
        { 
         StringReader reader = new StringReader(html); 
         //XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, reader); 
         this.doc.Add(new Paragraph(" ")); 
         HTMLWorker worker = new HTMLWorker(this.doc); 
         worker.Open(); 
         worker.StartDocument(); 
         worker.NewPage(); 
         worker.Parse(reader); 
         worker.SetStyleSheet(styles); 

         List<IElement> ie = iTextSharp.text.html.simpleparser.HTMLWorker.ParseToList(reader, null); 

         foreach (IElement element in ie) 
         { 
          this.doc.Add((IElement)element); 
         } 

         worker.EndDocument(); 
         worker.Close(); 
        } 
       } 
      } 
      return string.Empty; 
     } 
     catch (Exception ex) 
     { 
      return ex.Message; 
     } 

    } 
} 

這是例外:

System.ObjectDisposedException was caught 
    Message=Cannot access a closed file. 
    Source=mscorlib 
    ObjectName="" 
    StackTrace: 
     at System.IO.__Error.FileNotOpen() 
     at System.IO.FileStream.Write(Byte[] array, Int32 offset, Int32 count) 
     at iTextSharp.text.pdf.OutputStreamCounter.Write(Byte[] buffer, Int32 offset, Int32 count) 
     at iTextSharp.text.pdf.PdfIndirectObject.WriteTo(Stream os) 
     at iTextSharp.text.pdf.PdfWriter.PdfBody.Add(PdfObject objecta, Int32 refNumber, Boolean inObjStm) 
     at iTextSharp.text.pdf.PdfWriter.PdfBody.Add(PdfObject objecta, Int32 refNumber) 
     at iTextSharp.text.pdf.PdfWriter.PdfBody.Add(PdfObject objecta, PdfIndirectReference refa) 
     at iTextSharp.text.pdf.PdfWriter.AddToBody(PdfObject objecta, PdfIndirectReference refa) 
     at iTextSharp.text.pdf.Type1Font.WriteFont(PdfWriter writer, PdfIndirectReference piref, Object[] parms) 
     at iTextSharp.text.pdf.FontDetails.WriteFont(PdfWriter writer) 
     at iTextSharp.text.pdf.PdfWriter.AddSharedObjectsToBody() 
     at iTextSharp.text.pdf.PdfWriter.Close() 
     at iTextSharp.text.DocWriter.Dispose() 
     at WebPageExtraction.HtmlToPdfConverter.Run(String html, String pdfName) 
    InnerException: 

回答

5

您試圖調用close方法,它已經佈置之後。

你有一個using塊,自動配置的對象,所以才刪除那些兩行:

doc.CloseDocument(); 
doc.Close(); 

如果你不信任的內部處置代碼正確關閉文檔,並希望這樣做自己反正做了using塊內:

using (doc) 
{ 
    StyleSheet styles = new StyleSheet(); 
    using (PdfWriter writer = PdfWriter.GetInstance(this.doc, new  FileStream(@"Z:\programs\" + pdfName + ".pdf", FileMode.Create))) 
    { 
     //..... 
    } 
    doc.CloseDocument(); 
    doc.Close(); 
} 

編輯:試圖爲自己的代碼後,我注意到一些更多的問題和發現真正的原因對於您遇到的錯誤:

  • 您正在關閉並處置全局對象doc並且從不創建新實例。
  • 您不會處理所有可能導致內存泄漏或鎖定文件的對象。
  • 您得到的錯誤是因爲默認情況下,PdfWriter正在關閉它正在使用的流,並且在處置時,作者正在嘗試使用此流。所以要解決這個問題,你必須自己關閉流,並告訴作者不要這樣做。

完全固定碼:

Document doc = new Document(); 
StyleSheet styles = new StyleSheet(); 
string filePath = @"Z:\programs\" + pdfName + ".pdf"; 
using (FileStream pdfStream = new FileStream(filePath, FileMode.Create)) 
{ 
    using (PdfWriter writer = PdfWriter.GetInstance(doc, pdfStream)) 
    { 
     writer.CloseStream = false; 
     doc.Open(); 
     doc.OpenDocument(); 
     doc.NewPage(); 
     if (doc.IsOpen() == true) 
     { 
      using (StringReader reader = new StringReader(html)) 
      { 
       //XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, reader); 
       doc.Add(new Paragraph(" ")); 
       using (HTMLWorker worker = new HTMLWorker(doc)) 
       { 
        worker.Open(); 
        worker.StartDocument(); 
        worker.NewPage(); 
        worker.Parse(reader); 
        worker.SetStyleSheet(styles); 
        List<IElement> ie = iTextSharp.text.html.simpleparser.HTMLWorker.ParseToList(reader, null); 
        foreach (IElement element in ie) 
        { 
         doc.Add((IElement)element); 
        } 
        worker.EndDocument(); 
        worker.Close(); 
       } 
      } 
     } 
     writer.Close(); 
    } 
} 

doc.CloseDocument(); 
doc.Close(); 
doc.Dispose(); 
+0

我加入那些doc.close和.closeDocument作爲額外的看,如果說是去上班。我試過你的解決方案,但它仍然無法工作。感謝您的幫助。 – Emon

+1

是的,找到了真正的原因。看我的編輯。關鍵的變化是添加'writer.CloseStream = false;' –

+0

現在它給出了另一個例外。這是webexception。它說它找不到網絡路徑。這個版本也停在worker.parse上,你知道iTextSharp中的方法有什麼問題嗎?它不再給出其他例外。感謝你們對我的幫助。 – Emon

相關問題