2012-09-03 20 views
5

Tengo un problema con HTMLWorker.Parse de iTextSharp en un programa de formulario de Windows . Cada vez que exijo el código y comienza con HTMLWorker.Parse, le da la objectDisposedException. La excepción dice que no puede acceder a un archivo cerrado. Pero revisé muchas veces y no puedo encontrar el archivo que está cerrado. Aquí está el código:Itextsharp HTMLWorker.Parse error

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

    } 
} 

Ésta es la excepción:

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: 

Respuesta

5

Usted está tratando de llamar a los métodos de cierre después de que ya está dispuesta.

se tiene un bloque using que está disponiendo el objeto de forma automática, por lo que sólo quitar esas dos líneas:

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

Si usted no confía en disponer el código interno para cerrar correctamente el documento y querer hacer eso a sí mismo de todos modos, lo hacen dentro del bloque 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(); 
} 

Editar: después de probar su código por mí mismo me di cuenta de algunos más problemas y encontré la verdadera razón para el error que obtuvo:

  • Está cerrando y eliminando el objeto global doc y nunca crea una nueva instancia.
  • No deseche todos los objetos, lo que podría ocasionar la pérdida de memoria o el archivo bloqueado.
  • El error que recibió fue porque, de forma predeterminada, el PdfWriter está cerrando la transmisión que está utilizando y, cuando se desecha, el escritor está tratando de utilizar esta secuencia. Entonces, para resolver esto, debe cerrar el flujo usted mismo y decirle al escritor que no lo haga.

completa código fijo:

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

añadí esos doc.close y .closeDocument como extra para mirar si eso iba a funcionar. He intentado con tu solución, pero todavía no funciona. Gracias por ayudar. – Emon

+1

Sí, encontré el verdadero motivo. Ver mi edición El cambio crítico es agregar 'writer.CloseStream = false;' –

+0

Ahora ofrece otra excepción. es la webexcepción. dice que no puede encontrar la ruta de red. Esta versión también se detiene en worker.parse, ¿sabes si hay algún problema con ese método en iTextSharp? Ya no da la otra excepción. Gracias por ayudarme. – Emon