ItextSharp Error al intentar analizar html para la conversión de pdf

c# html-agility-pack html-parsing itext xmlworker

Pregunta

Estaba usando el módulo ItextSharp para convertir el código html a continuación en una página pdf.

        <div style="font-size: 18pt; font-weight: bold;">
    mma<br>mmar</div><br> <br>
    <div style="font-size: 14pt;">Click to View Pricing
    </div>
    <br>
    <div>
    <table>
    <tr><td> <a href="http://www.mma.com/fci" style="color: Blue; font-size: 10pt; text-decoration: underline;"> FCI</a>:</td> 
<td><a href="http://www.mma.com/access/?pn=78211-014" style="color: Blue; font-size: 10pt; text-decoration: underline;"> 78211-014</a></td></tr><tr><td></td> <td>
<a href="http://www.mma.com/access/?pn=78211-009" 
style="color: Blue; font-size: 10pt; text-decoration: underline;">78211-009</td></tr><tr><td></td> <td>
<a href="http://www.mma.com/access/?pn=78211-006" 
style="color: Blue; font-size: 10pt; text-decoration: underline;">78211-006</td></tr><tr><td></td> <td>
<a href="http://www.mma.com/access/?pn=78211-007" 
style="color: Blue; font-size: 10pt; text-decoration: underline;">78211-007</td></tr><tr><td></td> <td>
<a href="http://www.mma.com/access/?pn=78211-003" 
style="color: Blue; font-size: 10pt; text-decoration: underline;">78211-003</td></tr><tr><td></td> <td>
<a href="http://www.mma.com/access/?pn=78211-005" 
style="color: Blue; font-size: 10pt; text-decoration: underline;">78211-005</td></tr><tr><td></td> <td>
<a href="http://www.mma.com/access/?pn=78211-008"
 style="color: Blue; font-size: 10pt; text-decoration: underline;">78211-008</td></tr><tr><td></td> <td>
<a href="http://www.mma.com/access/?pn=78211-004" 
style="color: Blue; font-size: 10pt; text-decoration: underline;">78211-004</td></tr><tr><td></td> <td>
<a href="http://www.mma.com/access/?pn=78211-012" 
style="color: Blue; font-size: 10pt; text-decoration: underline;">78211-012</td></tr><tr><td></td> <td>
<a href="http://www.mma.com/access/?pn=78211-007LF" 
style="color: Blue; font-size: 10pt; text-decoration: underline;">78211-007LF</td></tr><tr><td></td> <td>
<a href="http://www.mma.com/access/?pn=78211-015LF" 
style="color: Blue; font-size: 10pt; text-decoration: underline;">78211-015LF</td></tr><tr><td></td> <td>
<a href="http://www.mma.com/access/?pn=78211-003LF"
 style="color: Blue; font-size: 10pt; text-decoration: underline;">78211-003LF</td></tr><tr><td></td> <td>
<a href="http://www.mma.com/access/?pn=78211-009LF" 
style="color: Blue; font-size: 10pt; text-decoration:
underline;">78211-009LF</td></tr><tr><td></td> <td>
<a href="http://www.mma.com/access/?pn=78211-005LF" 
style="color: Blue; font-size: 10pt; text-decoration: underline;">78211-005LF</td></tr><tr><td></td> <td>
<a href="http://www.mma.com/access/?pn=78211-010LF" 
style="color: Blue; font-size: 10pt; text-decoration: underline;">78211-010LF</td></tr><tr><td></td> <td>
<a href="http://www.mma.com/access/?pn=78211-006LF"
 style="color: Blue; font-size: 10pt; text-decoration: underline;">78211-006LF</td></tr><tr><td></td> <td>
<a href="http://www.mma.com/access/?pn=78211-014LF"
 style="color: Blue; font-size: 10pt; text-decoration: underline;">78211-014LF</td></tr><tr><td></td> <td>
<a href="http://www.mma.com/access/?pn=78211-004LF" 
style="color: Blue; font-size: 10pt; text-decoration: underline;">78211-004LF</td></tr><tr><td></td> <td>
<a href="http://www.mma.com/access/?pn=78211-012LF"
 style="color: Blue; font-size: 10pt; text-decoration: underline;">78211-012LF</td></tr><tr><td></td> <td>
<a href="http://www.mma.com/access/?pn=78211-008LF"
 style="color: Blue; font-size: 10pt; text-decoration: underline;">78211-008LF</td></tr><tr><td></td> <td>
<a href="http://www.mma.com/access/?pn=78211-011LF" 
style="color: Blue; font-size: 10pt; text-decoration: underline;">78211-011LF</td></tr><tr><td></td> <td><a href="http://www.mma.com/access/?pn=78211-013LF" 
style="color: Blue; font-size: 10pt; text-decoration: underline;">78211-013LF</td></tr><tr><td></td> <td><a href="http://www.mma.com/access/?pn=78211-010" style="color: Blue; font-size: 10pt; text-decoration: underline;">78211-010</td></tr><tr><td></td>
<td><a href="http://www.mma.com/access/?pn=78211-015"
 style="color: Blue; font-size: 10pt; text-decoration: underline;">78211-015</td></tr><tr><td> 
<a href="http://www.mma.com/souriau" 
style="color: Blue; font-size: 10pt; text-decoration: underline;"> Souriau</a>:</td>
 <td><a href="http://www.mma.com/access/?pn=24JR124-3" style="color: Blue; font-size: 10pt; text-decoration: underline;"> 24JR124-3</a></td></tr></table></div>

Código C # para generar el html anterior:

 var html = new StringBuilder(@"<div style=""font-size: 18pt; font-weight: bold;"">Authorized Distributor</div><br> <br><div style=""font-size: 14pt;"">Click to View Pricing, Inventory, Delivery & Lifecycle Information:</div><br>");
            List<MfrBrandView> mfrBrands = MfrBrandView.Load(fileId);
            var uniquesuppliers = mfrBrands.GroupBy(t => new {t.Manufacturer,t.SupplierVirtualDirectory}).Select(g => g.First());
            html.Append("<div><table>");
            foreach (var uniquesupplier in uniquesuppliers)
            {
                var mfrPartNums =
                    mfrBrands.Where(t => t.ManufacturerId == uniquesupplier.ManufacturerId).Select(
                        t => t.ManufacturerPartNumber).ToList();
                html.AppendFormat(@"<tr><td> <a href=""http://www.mma.com/{0}"" style=""color: Blue; font-size: 10pt; text-decoration: underline;""> {1}</a>:</td> <td><a href=""http://www.mma.com/access/?pn={2}"" style=""color: Blue; font-size: 10pt; text-decoration: underline;""> {2}</a></td></tr>", uniquesupplier.SupplierVirtualDirectory, uniquesupplier.MouserizationLabel, mfrPartNums[0]);

                for (int i = 1; i < mfrPartNums.Count(); i++)
                {
                    html.AppendFormat(
                        @"<tr><td></td> <td><a href=""http://www.mma.com/access/?pn={0}"" style=""color: Blue; font-size: 10pt; text-decoration: underline;"">{0}</td></tr>",
                        mfrPartNums[i]);
                }
            }
            html.Append("</table></div>");
            return html.ToString();

Código para generar la página después de que se forma html:

PdfWriter writer = null;
            PdfDocument doc = null;
            //PdfReader reader = new PdfReader(content);
           // reader.Info["Title"]

            try
            {
                doc = new PdfDocument();
                doc.SetPageSize(PageSize.LETTER);
                writer = PdfWriter.GetInstance(doc, content);
                writer.CloseStream = false;
                doc.Open();
                doc.NewPage();

                foreach (IElement element in iTextSharp.text.html.simpleparser.HTMLWorker.ParseToList(new StringReader(html), null))
                {
                    doc.Add(element);
                }
            }

a continuación es donde obtengo una excepción que dice "No se puede convertir el objeto de tipo 'iTextSharp.text.html.simpleparser.CellWrapper' para escribir 'iTextSharp.text.Paragraph' ". iTextSharp.text.html.simpleparser.HTMLWorker.ParseToList(new StringReader(html), null)

¿Hay algo mal con el html que estoy tratando de analizar? ¿Hay una mejor manera de hacer esto? Muchas gracias de antemano por su ayuda. Es muy apreciado.

Respuesta aceptada

`HTMLWorker ' ha quedado en desuso a favor de XMLWorker . Aquí hay un ejemplo de trabajo probado con un fragmento de HTML como el que usaste anteriormente:

StringReader html = new StringReader(@"
<div style='font-size: 18pt; font-weight: bold;'>
Mouser Electronics <br />Authorized Distributor</div><br /> <br />
<div style='font-size: 14pt;'>Click to View Pricing, Inventory, Delivery & Lifecycle Information:
</div>
<br />
<div>
<table>
<tr><td></td><td>
<a href='http://www.mouser.com/access/?pn=78211-009' 
style='color: Blue; font-size: 10pt; text-decoration: underline;'>78211-009</a></td></tr>
</table></div>    
");      
using (Document document = new Document()) {
  PdfWriter writer = PdfWriter.GetInstance(document, STREAM);
  document.Open();
  XMLWorkerHelper.GetInstance().ParseXHtml(
    writer, document, html
  );
}

Cuando use XMLWorker , necesita usar HTML bien formado: es un analizador XML, después de todo. El HTML muestra de su pregunta anterior no tiene etiquetas de cierre <a> o <br> . Un analizador de HTML como HtmlAgilityPack solucionará esos problemas y cambiará esto:

<div><img src='a.gif'><br><hr></div>

dentro de esto:

<div><img src='a.gif' /><br /><hr /></div>

con sólo unas pocas líneas de código:

var hDocument = new HtmlDocument()
{
    OptionWriteEmptyNodes = true,
    OptionAutoCloseOnEnd = true
};
hDocument.LoadHtml("<div><img src='a.gif'><br><hr></div>");
var closedTags  = hDocument.DocumentNode.WriteTo();

XMLWorker está disponible como un paquete nuget , o como una descarga separada en sourceforge .

Vea aquí para un uso más avanzado de XMLWorker .


Respuesta popular

Aquí están los pasos que debes hacer.

1- Instale itext sharp y XMLWorker desde Itextsharp desde nuget

2-Luego ponga su diseño en html (aquí Invoice.html) con CSS en línea

3-Asegúrate de que todas las etiquetas terminen correctamente como punto de interrupción o td (aquí obtuve el error anterior)

La imagen 4-here no se mostraría localmente, así que sin perder tiempo, cargué la imagen en el servidor y le di la Ruta al servidor para acceder a la Imagen. Puede investigar más para ejecutarla localmente.

Document doc = new Document();

PdfPTable tableLayout = new PdfPTable(4);

PdfWriter writer= PdfWriter.GetInstance(doc, new FileStream(Server.MapPath("~/Admin/T13.pdf"), FileMode.Create));                 

doc.Open();

string contents = File.ReadAllText(Server.MapPath("~/Admin/invoice.html"));

StringReader sr = new StringReader(contents);


XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, sr);  

doc.Close();


Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué