Cómo crear una tabla en Word con los datos de un objeto DataTable
Por Enrique Martínez Montejo
Última revisión: 11/02/2007
 

Si tenemos un objeto DataTable como resultado de una consulta a nuestra base de datos, puede ser que nos interese guardarlo en un nuevo documento de Microsoft Word, o en uno que ya tengamos creado.

En este ejemplo, presento una función genérica para crear una tabla en un nuevo documento de Word, con los datos contenidos en un objeto DataTable, devolviendo el objeto Word.Document creado. Al procedimiento hay que pasarle necesariamente un objeto Word.Application y un objeto DataTable, debidamente referenciados ambos objetos, porque de lo contrario, difícilmente vamos a poder crear un documento de Word.

Imports Microsoft.Office.Interop
Imports System.Data.OleDb

''' <summary>
''' Crea una tabla en un documento Microsoft Word con los datos
''' existentes en un objeto DataTable, devolviendo la referencia
''' a un objeto Word.Document.
''' </summary>
''' <author>Enrique Martínez Montejo - 11/02/2007</author>
''' <param name="app">Referencia a un objeto Word.Application
''' que se utilizará para crear el documento.</param>
''' <param name="dt">Objeto DataTable que contiene los datos.</param>
''' <returns></returns>

Public Function CreateTableWord(ByVal app As Word.Application, _
                                ByVal dt As DataTable) As Word.Document

    If (app Is Nothing) Then
        Throw New
ArgumentNullException("app")
    End If

    If (app Is Nothing) Then
        Throw New ArgumentNullException("dt")
    End If

    Dim doc As Word.Document = Nothing

    Try
        ' Número de columnas que tendrá la tabla.
        '

        Dim colsNumbers As Integer = dt.Columns.Count

        ' Número de filas que tendrá la tabla, que será una
        ' fila más que las existentes en el objeto DataTable,
        ' porque la primera fila la utilizaremos para escribir
        ' el nombre de las columnas.
        '

        Dim rowsNumbers As Integer = dt.Rows.Count + 1

        ' Referenciamos el documento de Word, añadiendo un
        ' nuevo documento a la colección Documents.
        '

        doc = app.Documents.Add()

        ' Definimos el área del documento de Word, donde crearemos
        ' la tabla. Al no existir todavía carácter alguno, tanto la
        ' posición de los caracteres inicial y final será cero.
        '

        Dim range As Word.Range = doc.Range(0, 0)
        Dim table As Word.Table = doc.Tables.Add(range, rowsNumbers, colsNumbers)

        ' Insertamos los encabezados de columna de la tabla, que
        ' se corresponderán con los nombres de los campos.
        '

        For col As Int32 = 1 To colsNumbers
            Dim cell As Word.Cell = table.Rows(1).Cells(col)
            cell.Range.Text = dt.Columns(col - 1).ColumnName
        Next

        ' Insertamos las filas en la tabla, comenzando por la
        ' fila número 2, ya que la primera fila está ocupada
        ' por el nombre de las columnas.
        '
       
Dim fila As Integer = 2
      
        For Each row As DataRow In dt.Rows
            Dim columna As Integer = 0
            For Each cell As Word.Cell In table.Rows(fila).Cells
                Dim value As Object = row.Item(columna)
                If ((Not value Is Nothing) OrElse (Not value Is DBNull.Value)) Then
                    ' Escribir el valor de la celda.
                    cell.Range.Text = value.ToString()
                End If
                columna += 1
            Next ' Siguiente columna
            fila += 1
        Next ' Siguiente fila

        ' Formateamos la tabla para que se ajuste a su contenido.
        '

        table.AutoFitBehavior(Word.WdAutoFitBehavior.wdAutoFitContent)

        ' Devolvemos la referencia al documento que se ha creado.
        '

        Return doc

    Catch
        If (Not doc Is Nothing) Then
            ' Indicamos que el documento ya ha sido guardado y lo cerramos.
            '

            doc.Saved = True
            doc.Close()
        End If

        ' Devolver la excepción que se ha producido al procedimiento llamador.
        '

        Throw

    End Try

End Function

 

Cómo crear una tabla en Word con los datos de un objeto DataTable

Resultará instructivo estudiar el código fuente de la función, para que el lector se familiaricé con el modelo de objetos de la biblioteca de Word, de tal forma que pueda utilizarlo en nuevos procedimientos que desarrolle.

Como observará, la función utiliza dos bucles para escribir los datos en las respectivas celdas de la tabla, ya que tiene que recorrer todas las filas contenidas en el objeto DataTable, y a su vez, recorrer todos los campos de cada fila. Esto significa que la función se tomará su tiempo para hacer su trabajo, dependiendo del número de filas que contenga el objeto DataTable; cuantas más filas existan, más tardará la función en devolver el objeto Document. Con esto quiere decirle que, si no desea tomarse un café mientras se crea el documento, procure no pasar un objeto DataTable con un elevado número de filas, recomendación que se hace extensible cuando se está trabajando con objetos DataTable en otros ámbitos de desarrollo.

Por último, le mostraré un ejemplo para crear un documento de Word con la datos existentes en la tabla Employees de la base de datos de prueba Northwind de Microsoft Access. Para ello, deberá importar en su código el espacio de nombre System.Data.OleDb, y ejecutar lo siguiente:

Dim cadenaConexion As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Mis documentos\Northwind.mdb"
Dim dt As New DataTable("Empleados")

Try
    Using cnn As New OleDbConnection(cadenaConexion)
        Dim cnn As OleDbCommand = cnn.CreateCommand()
        cmd.CommandText = "SELECT EmployeeID, FirstName, LastName, Title FROM Employees"
        Dim da As New OleDbDataAdapter(cmd)
        da.Fill(dt)
    End Using

    ' Creamos la tabla en un documento de Word. Para ello,
    ' primero referenciamos un objeto Word.Application nuevo.
    '

    Dim app As New Word.Application()
    Dim doc As Word.Document = CreateTableWord(app, dt)

    If (Not doc Is Nothing) Then
        With doc
            .SaveAs("C:\Mis documentos\Documento1.doc")
            .Close()
        End With
    End If

    ' Cerramos Word y liberamos los recursos asociados.
    '

    app.Quit()
    app = Nothing

Catch ex As Exception
    ' Se ha producido un error.
    MessageBox.Show(ex.Message)

End Try

Tenga en cuenta que llamar al método SaveAs de un objeto Word.Document, hace que se sobrescriba un archivo que ya exista, por lo que tendrá que establecer las medidas oportunas en su código fuente para no sobrescribir sin previo aviso un documento ya existente.

Por último, le recuerdo que cuando se trabaja con las bibliotecas de Word, Excel, etc., en definitiva, con un objeto Application común a todas las bibliotecas de productos de Microsoft Office, es sumamente importante cerrar explícitamente el objeto Application referenciado, llamando a su método Quit, así como establecer a Nothing el valor del objeto, para que en la siguiente recolección de elementos no utilizados pueda liberarse definitivamente los recursos asociados al objeto. Si esto no se hace así, en el Administrador de Tareas de Windows se le quedará abierto el proceso de la aplicación que haya utilizado, aunque la variable objeto utilizada haya salido fuera de su alcance, con el consiguiente consumo de recursos al que se verá penalizado.

 

Otros enlaces de interés:

Indice de la colección de ejemplos para trabajar con productos Microsoft Office


Enrique Martínez Montejo - 2007

NOTA: La información contenida en este artículo, así como el código fuente incluido en el mismo, se proporciona COMO ESTÁ, sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo explicado, recomendado o sugerido en el presente artículo.

NOTE: The information contained in this article and source code included therein, is provided AS IS without warranty of any kind, and confers no rights. You assume any risk to implement, use or run it explained, recommended or suggested in this article.