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;
Imports System.Linq
Imports DocumentFormat.OpenXml.Packaging
Imports DocumentFormat.OpenXml.Spreadsheet

Obtención de un objeto SpreadsheetDocument

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.
}
' Open the document for editing.
Dim spreadSheet As SpreadsheetDocument = SpreadsheetDocument.Open(docName, True)
Using (spreadSheet)
    ' Insert other code here.
End Using

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.

Estructura básica de un documento SpreadsheetML

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=https://schemas.openxmlformats.org/spreadsheetml/2006/main xmlns:r="https://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="https://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.

Funcionamiento del código muestra

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);
' Add a blank WorksheetPart.
Dim newWorksheetPart As WorksheetPart = spreadSheet.WorkbookPart.AddNewPart(Of WorksheetPart)()
newWorksheetPart.Worksheet = New Worksheet(New SheetData())
' newWorksheetPart.Worksheet.Save()

Dim sheets As Sheets = spreadSheet.WorkbookPart.Workbook.GetFirstChild(Of Sheets)()
Dim relationshipId As String = 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);
' Get a unique ID for the new worksheet.
Dim sheetId As UInteger = 1
If (sheets.Elements(Of Sheet).Count > 0) Then
    sheetId = sheets.Elements(Of Sheet).Select(Function(s) s.SheetId.Value).Max + 1
End If

' Give the new worksheet a name.
Dim sheetName As String = ("Sheet" + sheetId.ToString())

' Append the new worksheet and associate it with the workbook.
Dim sheet As Sheet = New Sheet
sheet.Id = relationshipId
sheet.SheetId = sheetId
sheet.Name = sheetName
sheets.Append(sheet)

Código muestra

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);
Dim docName As String = "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);
    }
}
' Given a document name, inserts a new worksheet.
Public Sub InsertWorksheet(ByVal docName As String)
    ' Open the document for editing.
    Dim spreadSheet As SpreadsheetDocument = SpreadsheetDocument.Open(docName, True)

    Using (spreadSheet)
        ' Add a blank WorksheetPart.
        Dim newWorksheetPart As WorksheetPart = spreadSheet.WorkbookPart.AddNewPart(Of WorksheetPart)()
        newWorksheetPart.Worksheet = New Worksheet(New SheetData())
        ' newWorksheetPart.Worksheet.Save()

        Dim sheets As Sheets = spreadSheet.WorkbookPart.Workbook.GetFirstChild(Of Sheets)()
        Dim relationshipId As String = spreadSheet.WorkbookPart.GetIdOfPart(newWorksheetPart)

        ' Get a unique ID for the new worksheet.
        Dim sheetId As UInteger = 1
        If (sheets.Elements(Of Sheet).Count > 0) Then
            sheetId = sheets.Elements(Of Sheet).Select(Function(s) s.SheetId.Value).Max + 1
        End If

        ' Give the new worksheet a name.
        Dim sheetName As String = ("Sheet" + sheetId.ToString())

        ' Append the new worksheet and associate it with the workbook.
        Dim sheet As Sheet = New Sheet
        sheet.Id = relationshipId
        sheet.SheetId = sheetId
        sheet.Name = sheetName
        sheets.Append(sheet)
    End Using
End Sub

Vea también

Referencia

Class Library Reference (en inglés)

Otros recursos