【问题标题】:Itextsharp HTMLWorker.Parse errorItextsharp HTMLWorker.Parse 错误
【发布时间】:2012-08-28 01:50:36
【问题描述】:

我遇到了来自 iTextSharp 的 HTMLWorker.Parse 的问题 Windows 窗体程序。每次我执行代码时 从 HTMLWorker.Parse 开始,它给出了 objectDisposedException。 异常表示它无法访问已关闭的文件。但我查了 多次,找不到已关闭的文件。代码如下:

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: 

【问题讨论】:

    标签: c# winforms itextsharp objectdisposedexception


    【解决方案1】:

    您正试图在它已被释放后调用 close 方法。

    你有一个 using 块自动处理对象,所以只需删除这两行:

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

    如果您不相信内部 dispose 代码可以正确关闭文档并希望自己执行此操作,请在 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 正在关闭它正在使用的 Stream,并且在处理时,作者正在尝试使用此流。所以要解决这个问题,你必须自己关闭流并告诉作者不要这样做。

    完整的固定代码:

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

    【讨论】:

    • 我添加了这些 doc.close 和 .closeDocument 作为额外的,以查看是否可行。我已经尝试过你的解决方案,但它仍然不起作用。感谢您的帮助。
    • 是的,找到了真正的原因。请参阅我的编辑。关键的变化是添加writer.CloseStream = false;
    • 现在它给出了另一个例外。这是网络异常。它说它找不到网络路径。这个版本也停在worker.parse,你知道iTextSharp中那个方法有问题吗?它不再给出其他例外。谢谢你帮助我。
    • 也许pdfName 是空的?尝试硬编码路径,例如@"Z:\programs\myfile.pdf" 看看它是否有效。
    • 对不起,没有更多的想法 - 尝试不同的路径然后例如C:\Temp\myfile.pdf
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多