Share via


Agregar tablas a documentos de procesamiento de texto

En este tema se muestra cómo usar las clases del SDK de Open XML para Office para agregar mediante programación una tabla a un documento de procesamiento de texto. Incluye un método AddTable de ejemplo para ilustrar esta tarea.

AddTable (método)

Puede usar el método AddTable para agregar una tabla simple a un documento de procesamiento de texto. El método AddTable acepta dos parámetros que indican lo siguiente:

  • El nombre del documento que se desea transformar (cadena).

  • Una matriz bidimensional de cadenas para su inserción en el documento en forma de tabla.

    public static void AddTable(string fileName, string[,] data)

Llamada al método AddTable

El método AddTable modifica el documento que especifica el usuario, agregando una tabla que contiene la información de la matriz bidimensional que ha proporcionado el usuario. Para llamar al método, transmita ambos valores de parámetro, tal como se muestra en el código siguiente.

    const string fileName = @"C:\Users\Public\Documents\AddTable.docx";
    AddTable(fileName, new string[,] 
        { { "Texas", "TX" }, 
        { "California", "CA" }, 
        { "New York", "NY" }, 
        { "Massachusetts", "MA" } }
        );

Funcionamiento del código

El código siguiente empieza abriendo el documento, mediante el método WordprocessingDocument.Open e indicando que el documento se debe abrir para acceso de lectura y escritura (el valor de parámetro true final). A continuación, el código recupera una referencia al elemento raíz de la parte principal del documento, utilizando la propiedad Document de MainDocumentPart del documento de procesamiento de texto.

    using (var document = WordprocessingDocument.Open(fileName, true))
    {
        var doc = document.MainDocumentPart.Document;
        // Code removed here…
    }

Crear el objeto de tabla y establecer sus propiedades

Para poder insertar una tabla en un documento, debe crear el objeto Table y configurar sus propiedades. Para establecer las propiedades de una tabla, cree y proporcione valores para un objeto TableProperties . La clase TableProperties proporciona muchas propiedades orientadas a tablas, como Shading, TableBorders, TableCaption, TableCellSpacing, TableJustification, etc. El método de ejemplo incluye el código siguiente.

    Table table = new Table();

    TableProperties props = new TableProperties(
        new TableBorders(
        new TopBorder
        {
            Val = new EnumValue<BorderValues>(BorderValues.Single),
            Size = 12
        },
        new BottomBorder
        {
          Val = new EnumValue<BorderValues>(BorderValues.Single),
          Size = 12
        },
        new LeftBorder
        {
          Val = new EnumValue<BorderValues>(BorderValues.Single),
          Size = 12
        },
        new RightBorder
        {
          Val = new EnumValue<BorderValues>(BorderValues.Single),
          Size = 12
        },
        new InsideHorizontalBorder
        {
          Val = new EnumValue<BorderValues>(BorderValues.Single),
          Size = 12
        },
        new InsideVerticalBorder
        {
          Val = new EnumValue<BorderValues>(BorderValues.Single),
          Size = 12
    }));

    table.AppendChild<TableProperties>(props);

El constructor de la clase TableProperties permite especificar tantos elementos secundarios como desee (como el constructor XElement ). En este caso, el código crea elementos secundarios TopBorder, BottomBorder, LeftBorder, RightBorder, InsideHorizontalBorder e InsideVerticalBorder , cada uno de los cuales describe uno de los elementos de borde de la tabla. Para cada elemento, el código configura las propiedades Val y Size como parte de la llamada al constructor. La configuración del tamaño es simple, pero la configuración de la propiedad Val requiere un poco más de esfuerzo: esta propiedad, para este objeto en particular, representa el estilo de borde, y debe definirla como un valor enumerado. Para ello, cree una instancia del tipo genérico EnumValue<T> , pasando el tipo de borde específico (Single como parámetro al constructor. Una vez que el código ha establecido todo el valor de borde de tabla que necesita establecer, llama al método AppendChild<T> de la tabla, lo que indica que el tipo genérico es [TableProperties](/dotnet/api/ ocumentformat.openxml.wordprocessing.tableproperties), es decir, anexa una instancia de la clase TableProperties , utilizando la variable props como valor.

Rellenar la tabla con datos

Una vez se hayan creado esa tabla y sus valores, es el momento de rellenar la tabla con datos. En primer lugar, el procedimiento de ejemplo procesa una iteración de todas las filas de datos en la matriz de cadenas especificada, creando una nueva instancia TableRow para cada fila de datos. En el código siguiente se omiten los detalles de relleno de la fila con datos, pero se muestra el modo en el que el usuario crea y anexa la fila a la tabla:

    for (var i = 0; i <= data.GetUpperBound(0); i++)
    {
        var tr = new TableRow();
        // Code removed here…
        table.Append(tr);
    }

Para cada fila, el código procesa una iteración de todas las columnas de la matriz de cadenas especificada por el usuario. Para cada columna, el código crea un nuevo objeto TableCell , lo rellena con datos y lo anexa a la fila. En el código siguiente se omiten los detalles de relleno de cada celda con datos, pero se muestra el modo en el que el usuario crea y anexa la columna a la tabla:

    for (var j = 0; j <= data.GetUpperBound(1); j++)
    {
        var tc = new TableCell();
        // Code removed here…
        tr.Append(tc);
    }

A continuación, el código hace lo siguiente:

  • Crea un nuevo objeto Text que contiene un valor de la matriz de cadenas.
  • Pasa el objeto Text al constructor para un nuevo objeto Run .
  • Pasa el objeto Run al constructor para un nuevo objeto Paragraph .
  • Pasa el objeto Paragraph al método Appendde la celda.

En otras palabras, el código siguiente anexa el texto al nuevo objeto TableCell.

    tc.Append(new Paragraph(new Run(new Text(data[i, j]))));

A continuación, el código anexa un nuevo objeto TableCellProperties a la celda. Este objeto TableCellProperties, al igual que el objeto TableProperties que ya ha visto, puede aceptar en su constructor todos los objetos que desee proporcionar. En este caso, el código pasa solo un nuevo objeto TableCellWidth , con su propiedad Type establecida en Auto (para que la tabla ajuste automáticamente el ancho de cada columna).

    // Assume you want columns that are automatically sized.
    tc.Append(new TableCellProperties(
        new TableCellWidth { Type = TableWidthUnitValues.Auto }));

Finalizar

El código siguiente termina anexando la tabla al cuerpo del documento y, a continuación, guardando el documento.

    doc.Body.Append(table);
    doc.Save();

Código de ejemplo

A continuación se incluye el ejemplo de código AddTable completo en C# y Visual Basic.

using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System;

AddTable(args[0], args[1]);

// Take the data from a two-dimensional array and build a table at the 
// end of the supplied document.
static void AddTable(string fileName, string json)
{
    // read the data from the json file
    var data = System.Text.Json.JsonSerializer.Deserialize<string[][]>(json);

    if (data is not null)
    {
        using (var document = WordprocessingDocument.Open(fileName, true))
        {
            if (document.MainDocumentPart is null || document.MainDocumentPart.Document.Body is null)
            {
                throw new ArgumentNullException("MainDocumentPart and/or Body is null.");
            }

            var doc = document.MainDocumentPart.Document;

            Table table = new();

            TableProperties props = new(
                new TableBorders(
                new TopBorder
                {
                    Val = new EnumValue<BorderValues>(BorderValues.Single),
                    Size = 12
                },
                new BottomBorder
                {
                    Val = new EnumValue<BorderValues>(BorderValues.Single),
                    Size = 12
                },
                new LeftBorder
                {
                    Val = new EnumValue<BorderValues>(BorderValues.Single),
                    Size = 12
                },
                new RightBorder
                {
                    Val = new EnumValue<BorderValues>(BorderValues.Single),
                    Size = 12
                },
                new InsideHorizontalBorder
                {
                    Val = new EnumValue<BorderValues>(BorderValues.Single),
                    Size = 12
                },
                new InsideVerticalBorder
                {
                    Val = new EnumValue<BorderValues>(BorderValues.Single),
                    Size = 12
                }));

            table.AppendChild<TableProperties>(props);

            for (var i = 0; i < data.Length; i++)
            {
                var tr = new TableRow();
                for (var j = 0; j < data[i].Length; j++)
                {
                    var tc = new TableCell();
                    tc.Append(new Paragraph(new Run(new Text(data[i][j]))));

                    // Assume you want columns that are automatically sized.
                    tc.Append(new TableCellProperties(
                        new TableCellWidth { Type = TableWidthUnitValues.Auto }));

                    tr.Append(tc);
                }
                table.Append(tr);
            }
            doc.Body.Append(table);
            doc.Save();
        }
    }
}