Procedimiento para insertar una hoja de cálculo nueva en un documento de hoja de cálculo

En este tema se muestra cómo usar las clases de Open XML SDK 2.0 para Microsoft Office para insertar una hoja de cálculo nueva en un documento de hoja de cálculo mediante programación.

Se necesitan las siguientes directivas de ensamblado para compilar el código en este tema.

using System.Linq;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;

En Open XML SDK, la clase SpreadsheetDocument representa un paquete de documentos de Excel. Para abrir y trabajar con un documento de Excel, cree una instancia de la clase SpreadsheetDocument desde el documento. Después de crear la instancia desde el documento, puede acceder a la parte de libro principal que contiene las hojas de cálculo. En el paquete, el texto del documento se representa como XML mediante el marcado SpreadsheetML.

Para crear la instancia de clase desde un documento, debe llamar a uno de los métodos Open(). Se proporcionan varios métodos, cada uno con una firma distinta. El código muestra de este tema usa el método Open(String, Boolean) con una firma que necesita dos parámetros. El primero toma una cadena de ruta de acceso completa que representa el documento que desea abrir. El segundo es true o false y representa si desea que el archivo se abra para edición o no. Si el parámetro es false, los cambios que realice en el documento no se guardarán.

El código que llama al método Open se muestra en la siguiente instrucción using.

// Open the document for editing.
using (SpreadsheetDocument spreadSheet = SpreadsheetDocument.Open(docName, true)) 
{
    // Insert other code here.
}

La instrucción using proporciona una alternativa recomendada a la típica secuencia .Open, .Save, .Close. Garantiza que se llamará automáticamente al método Dispose (un método interno que Open XML SDK usa para limpiar recursos) cuando se llegue a la llave de cierre. El bloque que sigue a la instrucción using establece un ámbito para el objeto que se crea o se nombra en la instrucción using, en este caso spreadSheet.

La estructura básica de un documento SpreadsheetML consta de los elementos Sheets y Sheet, que hacen referencia a las hojas de cálculo de Workbook. Se crea un archivo XML independiente para cada Worksheet. Por ejemplo, SpreadsheetML de un libro que tiene dos hojas de cálculo con los nombres MySheet1 y MySheet2 se encuentra en el archivo Workbook.xml y se muestra en el siguiente ejemplo de código.

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 
<workbook xmlns=http://schemas.openxmlformats.org/spreadsheetml/2006/main xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
    <sheets>
        <sheet name="MySheet1" sheetId="1" r:id="rId1" /> 
        <sheet name="MySheet2" sheetId="2" r:id="rId2" /> 
    </sheets>
</workbook>

Los archivos XML de hoja de cálculo contienen uno o más elementos a nivel de bloque, como SheetData. sheetData representa la tabla de celdas y contiene uno o más elementos Row. Una fila, row, contiene uno o más elementos Cell. Cada celda contiene un elemento CellValue que representa el valor de la celda. Por ejemplo, SpreadsheetML para la primera hoja de cálculo del libro, que solo tiene el valor 100 en la celda A1, se encuentra en el archivo Sheet1.xml y se muestra en el siguiente ejemplo de código.

<?xml version="1.0" encoding="UTF-8" ?> 
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
    <sheetData>
        <row r="1">
            <c r="A1">
                <v>100</v> 
            </c>
        </row>
    </sheetData>
</worksheet>

Mediante Open XML SDK 2.0, puede crear una estructura de documento y contenido que use clases fuertemente tipadas que correspondan a los elementos de SpreadsheetML. Estas clases se pueden encontrar en el espacio de nombres DocumentFormat.OpenXML.Spreadsheet. En la siguiente tabla, se enumeran los nombres de las clases que corresponden a los elementos workbook, sheets, sheet, worksheet y sheetData.

Elemento de SpreadsheetML

Clase de Open XML SDK 2.0

Descripción

workbook

DocumentFormat.OpenXml.Spreadsheet.Workbook

El elemento raíz de la parte de documento principal.

sheets

DocumentFormat.OpenXml.Spreadsheet.Sheets

El contenedor de las estructuras a nivel de bloque, como sheet, fileVersion y otras detalladas en la especificación .

sheet

DocumentFormat.OpenXml.Spreadsheet.Sheet

Una hoja que apunta a un archivo de definición de hoja.

worksheet

DocumentFormat.OpenXml.Spreadsheet.Worksheet

Un archivo de definición de hoja que contiene los datos de la hoja.

sheetData

DocumentFormat.OpenXml.Spreadsheet.SheetData

La tabla de celdas agrupadas por filas.

row

DocumentFormat.OpenXml.Spreadsheet.Row

Una fila en una tabla de celdas.

c

DocumentFormat.OpenXml.Spreadsheet.Cell

Una celda en una fila.

v

DocumentFormat.OpenXml.Spreadsheet.CellValue

El valor de una celda.

Después de abrir el documento para su edición como un paquete de documentos de SpreadsheetDocument, el código agrega un nuevo objeto WorksheetPart al objeto WorkbookPart mediante el método AddNewPart. A continuación, agrega un nuevo objeto Worksheet al objecto WorksheetPart.

// Add a blank WorksheetPart.
WorksheetPart newWorksheetPart = 
    spreadSheet.WorkbookPart.AddNewPart<WorksheetPart>();
newWorksheetPart.Worksheet = new Worksheet(new SheetData());

Sheets sheets = spreadSheet.WorkbookPart.Workbook.GetFirstChild<Sheets>();
string relationshipId = 
    spreadSheet.WorkbookPart.GetIdOfPart(newWorksheetPart);

A continuación, el código obtiene un identificador único para la hoja de cálculo nueva al seleccionar el objeto SheetId máximo usado en el documento de hoja de cálculo y al agregar uno para crear el identificador de la hoja nueva. Proporciona un nombre a la hoja de cálculo al concatenar la palabra "Hoja" con el identificador de la hoja y anexa la nueva hoja a la colección de hojas.

// Get a unique ID for the new worksheet.
uint sheetId = 1;
if (sheets.Elements<Sheet>().Count() > 0)
{
    sheetId = 
        sheets.Elements<Sheet>().Select(s => s.SheetId.Value).Max() + 1;
}

// Give the new worksheet a name.
string sheetName = "Sheet" + sheetId;

// Append the new worksheet and associate it with the workbook.
Sheet sheet = new Sheet() 
{ Id = relationshipId, SheetId = sheetId, Name = sheetName };
sheets.Append(sheet);

En el siguiente código, inserte un objeto Worksheet en blanco al agregar un objeto WorksheetPart en blanco. Esto genera un identificador único para el objeto WorksheetPart y registra el objeto WorksheetPart en el objeto WorkbookPart contenido en un paquete de documentos SpreadsheetDocument. Para llamar al método InsertWorksheet, puede usar el siguiente código, que inserta una hoja de cálculo en un archivo denominado “Sheet7.xslx”, por ejemplo.

string docName = @"C:\Users\Public\Documents\Sheet7.xlsx";
InsertWorksheet(docName);

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

// Given a document name, inserts a new worksheet.
public static void InsertWorksheet(string docName)
{
    // Open the document for editing.
    using (SpreadsheetDocument spreadSheet = SpreadsheetDocument.Open(docName, true))
    {
        // Add a blank WorksheetPart.
        WorksheetPart newWorksheetPart = spreadSheet.WorkbookPart.AddNewPart<WorksheetPart>();
        newWorksheetPart.Worksheet = new Worksheet(new SheetData());

        Sheets sheets = spreadSheet.WorkbookPart.Workbook.GetFirstChild<Sheets>();
        string relationshipId = spreadSheet.WorkbookPart.GetIdOfPart(newWorksheetPart);

        // Get a unique ID for the new worksheet.
        uint sheetId = 1;
        if (sheets.Elements<Sheet>().Count() > 0)
        {
            sheetId = sheets.Elements<Sheet>().Select(s => s.SheetId.Value).Max() + 1;
        }

        // Give the new worksheet a name.
        string sheetName = "Sheet" + sheetId;

        // Append the new worksheet and associate it with the workbook.
        Sheet sheet = new Sheet() { Id = relationshipId, SheetId = sheetId, Name = sheetName };
        sheets.Append(sheet);
    }
}
Mostrar: