none
De ListView a HTML RRS feed

  • Question

  • Hola.

    Como puedo exportar los item y subItems de un ListView a un archivo .HTML cada vez que se agregan al ListView.

    Y como puedo imprtar el HTML a otro ListView.

    Muchas gracias.

     

    Thursday, December 8, 2011 6:40 PM

Answers

  • Perdona por la tardanza, hasta hoy no te he podido contestar.

    Te voy a poner el código que he utilizado yo:

    Partiendo de este html de muestra:

     

    <html>
    	<head>
    		<title></title>
    	</head>
    	<body>
    	    <table id="datos2">
                <thead>
                    <tr>
                        <th>Nombre</th>
                        <th>Apellidos</th>
                        <th>Edad</th>
                     </tr>
                </thead>
                <tbody>
                            <tr>
                    <td> a </td>
                    <td> b </td>
                    <td> c </td>
                </tr>
                <tr>
                    <td> 1 </td>
                    <td> 2 </td>
                    <td> 3 </td>
                </tr>
                </tbody>
            </table>
            <table id="datos">
                <tr>
                    <td> a </td>
                    <td> b </td>
                    <td> c </td>
                </tr>
                <tr>
                    <td> 1 </td>
                    <td> 2 </td>
                    <td> 3 </td>
                </tr>
            </table>
    	</body>
    </html>
    

     


    He construido una serie de funciones a excepcion de RellenarListView(que publique hace ya un tiempo...):

     

     

        
    Sub ImportarTableHtmlAListView(url As String, nombre As String, lvwDestino As ListView)
            If String.IsNullOrEmpty(url) Then Throw New Exception("La url es necesaria.")
            If String.IsNullOrEmpty(nombre) Then Throw New Exception("El nombre de la tabla es necesario.")
            Dim htmlText As String = LeerURL(url)
            If String.IsNullOrEmpty(htmlText) Then Throw New Exception("El código html obtenido está vacio.")
            Dim doc As HtmlDocument = ObtenerHTML(htmlText)
            If doc Is Nothing Then Throw New Exception("El documento HTML no se ha podido generar.")
            Dim tabla As HtmlElement = ObtenerTabla(doc, nombre)
            If tabla Is Nothing Then Throw New Exception("No se ha encontrada la tabla indicada.")
            Dim datos As DataTable = ObtenerDatos(tabla)
            RellenarListview(lvwDestino, datos)
    
        End Sub
        Function LeerURL(url As String) As String
            Dim client As System.Net.WebClient = New System.Net.WebClient()
            Dim html As String = client.DownloadString(url)
            Return html
        End Function
        Private Function ObtenerHTML(texto As String) As HtmlDocument
            Using browser As New WebBrowser()
                browser.DocumentText = texto
                Do
                    Application.DoEvents()
                Loop While browser.ReadyState <> WebBrowserReadyState.Complete
    
                Return browser.Document
            End Using
        End Function
        Private Function ObtenerTabla(doc As HtmlDocument, nombre As String) As HtmlElement
            Return doc.GetElementById(nombre)
        End Function
        Private Function ObtenerDatos(tabla As HtmlElement) As DataTable
            Dim dtbDatos As New DataTable()
            Dim trHead As List(Of HtmlElement) = GetByTagName(tabla, "THEAD")
            Dim trCol As List(Of HtmlElement) = GetByTagName(tabla, "TR")
            Dim row As DataRow
            If trHead.Count = 0 Then
                For Each col As HtmlElement In trCol.FirstOrDefault().All
                    dtbDatos.Columns.Add()
                Next
            Else
                Dim trHeader As HtmlElement = GetByTagName(tabla, "TR").FirstOrDefault()
                For Each element As HtmlElement In trHeader.All
    
                    dtbDatos.Columns.Add(element.InnerText)
                Next
            End If
    
            For Each fila As HtmlElement In trCol
                If fila.Parent.TagName <> "THEAD" Then
                    row = dtbDatos.NewRow
                    Dim tdCol As List(Of HtmlElement) = GetByTagName(fila, "TD")
    
                    For contador As Integer = 0 To dtbDatos.Columns.Count - 1
                        row(contador) = tdCol(contador).InnerText
                    Next
                    dtbDatos.Rows.Add(row)
                End If
            Next
            Return dtbDatos
        End Function
        Private Function GetByTagName(elemento As HtmlElement, tag As String) As List(Of HtmlElement)
            Return elemento.All.Cast(Of HtmlElement)().ToList().Where(Function(a) a.TagName.ToUpper() = tag).ToList()
        End Function
    
    
        Function RellenarListview(ByVal lvw As ListView, ByVal dt As DataTable) As Boolean
            Dim bolResultado As Boolean = True
            Dim lstElemento As ListViewItem
            Try
                lvw.Items.Clear()
                lvw.Columns.Clear()
                For Each col As DataColumn In dt.Columns
                    lvw.Columns.Add(col.ColumnName, col.ColumnName)
                Next
                For Each row As DataRow In dt.Rows
                    lstElemento = New ListViewItem
                    lstElemento.Text = row(0).ToString()
                    For intcontador As Integer = 1 To dt.Columns.Count - 1
                        lstElemento.SubItems.Add(row(intcontador).ToString())
                    Next
                    lvw.Items.Add(lstElemento)
                Next
                lvw.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize)
            Catch ex As Exception
                bolResultado = False
            End Try
            Return bolResultado
        End Function
    

     


    Y para utilizarlo:

     

    ImportarTableHtmlAListView(String.Format("{0}\test.html", Application.StartupPath), "datos", Me.ListView1)

     

    Espero que te sirva.!!

     

    PD: El código es mejorable porque habría que controlar si hay span entre otras cosas....


    Javier Torrecilla
    Para el correcto funcionamiento, y que otros usuarios se puedan beneficiar de la solucion de esta pregunta por favor marca las respuestas que te hayan ayudado como "Respuesta".
    Si la respuesta te ha sido util Votala.
    Mi Blog: Jtorrecilla
    Enlace a Faq de Winforms en Ingles Muy bueno
    TabControl con Mejoras
    Monday, December 19, 2011 10:33 AM
    Moderator

All replies

  • hola

    trabajar con html es como hacer con xml, ya que en ambos son nodos

    por lo tanto si recorres los items y subitems del listview y usando ya sea el XmlDocument o el XElement (esto es si te animas a linq to xml)

    podrias armar la estructura del html y grabarla en un archivo sin problemas

    entonces el tema seria

    - sabes recorrer un listview para tomar la informacion ?

    - sabes trabajar un xml desde codigo ?

    - te animas a usar linq to xml ? puedo asegurar que seria el mejor camino, en un solo paso podrias exportat el listview a xml (o sea html)

     

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    Thursday, December 8, 2011 6:56 PM
  • Gracias Leandro.

    Dejo la pregunta abierta y, probare con XML.

     

     

    Thursday, December 8, 2011 7:25 PM
  • vuelvo a recomendarte que veas linq to xml

    puedo asegurar que en una sola instruccion xml podrias armar todo el xml usando linq

    es muy potente


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    Thursday, December 8, 2011 7:27 PM
  •  Oiga, Eduardo Portescheller! ¿Tiene Ud. la costumbre de marcar como valida las respuestas que a Ud. le parecen antes de que quien abre el hilo pueda siquiera, leerlas? ¿O es por el placer de que la opinion de uno tambien cuente? Tambien podria ser que somos muchos los que preguntamos y pocos los que responden. Pero creo que esta es una decision que ha de tomar quien hizo la pregunta. Por otra parte, no seria de agradecer que quienes quieren ayudar con sus respuestas no abran el hilo porque ya esta respondida la pregunta.

    En este caso, la respuesta de Leandro Tuttini que Ud. ha marcado como valida, es solo un consejo y no una respuesta valida a la pregunta que abre el hilo.

    Si. Se que XML es mas rapido, se necesita menos codigo y las demas buenas y mejores cualidades que pueda poseer en comparacion con HTML. Pero yo necesito una pagina en HTML que se pueda abrir con IE. para ver imagenes, botones, cuadros de texto, etc. y no solo el codigo escrito.

    PD: No se!. Tal vez este no sea un foro libre! Mas bien parece una gerarquia feudal!

    Por fabor. Marque como posible respuesta y no como tal.

    Attentamente.




    • Edited by Rafael F M Friday, December 16, 2011 7:14 PM
    Friday, December 16, 2011 10:21 AM
  • Hola RafMand,

     

    Te pongo un ejemplo de código para generar el código HTML:

     

    Private Function ExportarListViewAHtml(milistView As ListView) As String
            If milistView.View <> View.Details Then Return String.Empty
            If milistView.Items.Count = 0 Then Return String.Empty
            Dim builder As New System.Text.StringBuilder()
            builder.AppendLine("<html>")
            builder.AppendLine("<body>")
            builder.AppendLine("<table>")
            For Each item As ListViewItem In milistView.Items
                builder.AppendLine("<tr>")
                builder.AppendLine(String.Format("<td>{0}</td>", item.Text))
                For Each col As ListViewItem.ListViewSubItem In item.SubItems
                    builder.AppendLine(String.Format("<td>{0}</td>", Convert.ToString(col.Text)))
                Next
                builder.AppendLine("</tr>")
            Next
            builder.AppendLine("</table>")
            builder.AppendLine("</body>")
            builder.AppendLine("</html>")
            Return builder.ToString()
        End Function
    

    El código es mejorable, pudiendo generar los ids de los elementos para que luego pudieras volver a tratarlo.

    Espero que te sirva.


    Javier Torrecilla
    Para el correcto funcionamiento, y que otros usuarios se puedan beneficiar de la solucion de esta pregunta por favor marca las respuestas que te hayan ayudado como "Respuesta".
    Si la respuesta te ha sido util Votala.
    Mi Blog: Jtorrecilla
    Enlace a Faq de Winforms en Ingles Muy bueno
    TabControl con Mejoras
    Friday, December 16, 2011 11:53 AM
    Moderator
  • Gracias Jtorrecilla.

    Pero lo que verdaderamente me interesa es saber si hay alguna forma no muy complicada de hacer lo contrario. Importar a un ListView una tabla escrita en HTML.

    Perdonen por no expresarlo asi en el titulo.

    Atentamente.


    • Edited by Rafael F M Friday, December 16, 2011 1:38 PM
    Friday, December 16, 2011 1:36 PM
  • Perdona por la tardanza, hasta hoy no te he podido contestar.

    Te voy a poner el código que he utilizado yo:

    Partiendo de este html de muestra:

     

    <html>
    	<head>
    		<title></title>
    	</head>
    	<body>
    	    <table id="datos2">
                <thead>
                    <tr>
                        <th>Nombre</th>
                        <th>Apellidos</th>
                        <th>Edad</th>
                     </tr>
                </thead>
                <tbody>
                            <tr>
                    <td> a </td>
                    <td> b </td>
                    <td> c </td>
                </tr>
                <tr>
                    <td> 1 </td>
                    <td> 2 </td>
                    <td> 3 </td>
                </tr>
                </tbody>
            </table>
            <table id="datos">
                <tr>
                    <td> a </td>
                    <td> b </td>
                    <td> c </td>
                </tr>
                <tr>
                    <td> 1 </td>
                    <td> 2 </td>
                    <td> 3 </td>
                </tr>
            </table>
    	</body>
    </html>
    

     


    He construido una serie de funciones a excepcion de RellenarListView(que publique hace ya un tiempo...):

     

     

        
    Sub ImportarTableHtmlAListView(url As String, nombre As String, lvwDestino As ListView)
            If String.IsNullOrEmpty(url) Then Throw New Exception("La url es necesaria.")
            If String.IsNullOrEmpty(nombre) Then Throw New Exception("El nombre de la tabla es necesario.")
            Dim htmlText As String = LeerURL(url)
            If String.IsNullOrEmpty(htmlText) Then Throw New Exception("El código html obtenido está vacio.")
            Dim doc As HtmlDocument = ObtenerHTML(htmlText)
            If doc Is Nothing Then Throw New Exception("El documento HTML no se ha podido generar.")
            Dim tabla As HtmlElement = ObtenerTabla(doc, nombre)
            If tabla Is Nothing Then Throw New Exception("No se ha encontrada la tabla indicada.")
            Dim datos As DataTable = ObtenerDatos(tabla)
            RellenarListview(lvwDestino, datos)
    
        End Sub
        Function LeerURL(url As String) As String
            Dim client As System.Net.WebClient = New System.Net.WebClient()
            Dim html As String = client.DownloadString(url)
            Return html
        End Function
        Private Function ObtenerHTML(texto As String) As HtmlDocument
            Using browser As New WebBrowser()
                browser.DocumentText = texto
                Do
                    Application.DoEvents()
                Loop While browser.ReadyState <> WebBrowserReadyState.Complete
    
                Return browser.Document
            End Using
        End Function
        Private Function ObtenerTabla(doc As HtmlDocument, nombre As String) As HtmlElement
            Return doc.GetElementById(nombre)
        End Function
        Private Function ObtenerDatos(tabla As HtmlElement) As DataTable
            Dim dtbDatos As New DataTable()
            Dim trHead As List(Of HtmlElement) = GetByTagName(tabla, "THEAD")
            Dim trCol As List(Of HtmlElement) = GetByTagName(tabla, "TR")
            Dim row As DataRow
            If trHead.Count = 0 Then
                For Each col As HtmlElement In trCol.FirstOrDefault().All
                    dtbDatos.Columns.Add()
                Next
            Else
                Dim trHeader As HtmlElement = GetByTagName(tabla, "TR").FirstOrDefault()
                For Each element As HtmlElement In trHeader.All
    
                    dtbDatos.Columns.Add(element.InnerText)
                Next
            End If
    
            For Each fila As HtmlElement In trCol
                If fila.Parent.TagName <> "THEAD" Then
                    row = dtbDatos.NewRow
                    Dim tdCol As List(Of HtmlElement) = GetByTagName(fila, "TD")
    
                    For contador As Integer = 0 To dtbDatos.Columns.Count - 1
                        row(contador) = tdCol(contador).InnerText
                    Next
                    dtbDatos.Rows.Add(row)
                End If
            Next
            Return dtbDatos
        End Function
        Private Function GetByTagName(elemento As HtmlElement, tag As String) As List(Of HtmlElement)
            Return elemento.All.Cast(Of HtmlElement)().ToList().Where(Function(a) a.TagName.ToUpper() = tag).ToList()
        End Function
    
    
        Function RellenarListview(ByVal lvw As ListView, ByVal dt As DataTable) As Boolean
            Dim bolResultado As Boolean = True
            Dim lstElemento As ListViewItem
            Try
                lvw.Items.Clear()
                lvw.Columns.Clear()
                For Each col As DataColumn In dt.Columns
                    lvw.Columns.Add(col.ColumnName, col.ColumnName)
                Next
                For Each row As DataRow In dt.Rows
                    lstElemento = New ListViewItem
                    lstElemento.Text = row(0).ToString()
                    For intcontador As Integer = 1 To dt.Columns.Count - 1
                        lstElemento.SubItems.Add(row(intcontador).ToString())
                    Next
                    lvw.Items.Add(lstElemento)
                Next
                lvw.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize)
            Catch ex As Exception
                bolResultado = False
            End Try
            Return bolResultado
        End Function
    

     


    Y para utilizarlo:

     

    ImportarTableHtmlAListView(String.Format("{0}\test.html", Application.StartupPath), "datos", Me.ListView1)

     

    Espero que te sirva.!!

     

    PD: El código es mejorable porque habría que controlar si hay span entre otras cosas....


    Javier Torrecilla
    Para el correcto funcionamiento, y que otros usuarios se puedan beneficiar de la solucion de esta pregunta por favor marca las respuestas que te hayan ayudado como "Respuesta".
    Si la respuesta te ha sido util Votala.
    Mi Blog: Jtorrecilla
    Enlace a Faq de Winforms en Ingles Muy bueno
    TabControl con Mejoras
    Monday, December 19, 2011 10:33 AM
    Moderator
  • Hola, le has podido dar un vistazo a la solución?
    Javier Torrecilla
    Para el correcto funcionamiento, y que otros usuarios se puedan beneficiar de la solucion de esta pregunta por favor marca las respuestas que te hayan ayudado como "Respuesta".
    Si la respuesta te ha sido util Votala.
    Mi Blog: Jtorrecilla
    Enlace a Faq de Winforms en Ingles Muy bueno
    TabControl con Mejoras
    Thursday, December 22, 2011 3:06 PM
    Moderator
  • Muchas gracias jtorrecilla.

    Aunque supongo que con databases es mejor el HTML es mas sencillito.

    Atentamente.

    Wednesday, January 4, 2012 12:26 AM