Abrir un documento de hoja de cálculo desde una secuencia
En este tema se muestra cómo usar las clases del SDK de Open XML para Office para abrir un documento de hoja de cálculo desde una secuencia mediante programación.
Cuándo se debe abrir desde una secuencia
Si tiene una aplicación, como Microsoft SharePoint Foundation 2010, que funciona con documentos mediante la entrada y salida de secuencias y desea usar el SDK de Open XML para trabajar con uno de los documentos, esto está diseñado para ser fácil de hacer. Esto es especialmente cierto si el documento existe y puede abrirlo mediante el SDK de Open XML. Sin embargo, imagine que el documento contiene un flujo abierto en el lugar del código donde necesita trabajar con el SDK. Ese es el escenario de este tema. El método de ejemplo del código de ejemplo acepta una secuencia abierta como parámetro y, a continuación, agrega texto al documento detrás de la secuencia mediante el SDK de Open XML.
Objeto SpreadsheetDocument
La estructura de documento básica de un documento SpreadsheetML se compone de elementos Sheets y Sheet, que hacen referencia a las hojas de cálculo en el libro. Se crea un archivo XML independiente para cada hoja de cálculo. Por ejemplo, el documento SpreadsheetML para un libro que tiene dos hojas de cálculo llamadas MySheet1 y MySheet2 está ubicado 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 de nivel de bloque como SheetData. sheetData representa la tabla de la celda y contiene uno o más elementos Row. Un elemento row contiene uno o más elementos Cell. Cada celda contiene un elemento CellValue que representa el valor de la celda. Por ejemplo, el 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>
Con el SDK de Open XML, puede crear la estructura de documentos y el contenido que usa clases fuertemente tipadas que corresponden a elementos SpreadsheetML. Puede encontrar estas clases 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 | Open XML SDK (clase) | Descripción |
---|---|---|
libro de trabajo | DocumentFormat.OpenXml.Spreadsheet.Workbook | El elemento raíz del elemento de documento principal. |
sheets | DocumentFormat.OpenXml.Spreadsheet.Sheets | El contenedor de las estructuras del nivel de bloque, como sheet, fileVersion y otras que se detallan en la especificación ISO/IEC 29500. |
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. |
Generación del marcado SpreadsheetML para agregar una hoja de cálculo
Cuando tenga acceso al cuerpo de la parte principal del documento, agregue una hoja de cálculo llamando al método AddNewPart<T>(String, String) para crear una nueva WorksheetPart. El siguiente ejemplo de código agrega el nuevo elemento WorksheetPart.
// Add a new worksheet.
WorksheetPart newWorksheetPart = workbookPart.AddNewPart<WorksheetPart>();
newWorksheetPart.Worksheet = new Worksheet(new SheetData());
newWorksheetPart.Worksheet.Save();
Código de ejemplo
En este ejemplo, se puede usar el método OpenAndAddToSpreadsheetStream para abrir un documento de hojas de cálculo desde una secuencia que ya está abierta y anexar texto en él. A continuación se incluye el código de ejemplo completo en C# y Visual Basic.
var fileStream = File.Open(args[0], FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
OpenAndAddToSpreadsheetStream(fileStream);
Tenga en cuenta que el método OpenAddAndAddToSpreadsheetStream no cierra la secuencia que se pasó. De eso se ocupa el código de llamada.
A continuación se incluye el código de ejemplo completo en C# y Visual Basic.
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using System.IO;
using System.Linq;
static void OpenAndAddToSpreadsheetStream(Stream stream)
{
// Open a SpreadsheetDocument based on a stream.
SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(stream, true);
if (spreadsheetDocument is not null)
{
// Get or create the WorkbookPart
WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart ?? spreadsheetDocument.AddWorkbookPart();
// Add a new worksheet.
WorksheetPart newWorksheetPart = workbookPart.AddNewPart<WorksheetPart>();
newWorksheetPart.Worksheet = new Worksheet(new SheetData());
newWorksheetPart.Worksheet.Save();
Workbook workbook = workbookPart.Workbook ?? new Workbook();
if (workbookPart.Workbook is null)
{
workbookPart.Workbook = workbook;
}
Sheets sheets = workbook.GetFirstChild<Sheets>() ?? workbook.AppendChild(new Sheets());
string relationshipId = 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) ?? (uint)sheets.Elements<Sheet>().Count() + 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);
workbookPart.Workbook.Save();
// Dispose the document handle.
spreadsheetDocument.Dispose();
}
}