nodo - leer y modificar xml c#
Abrir la lectura de XML desde el archivo de Excel (2)
Quiero implementar openXml sdk 2.5 en mi proyecto. Hago todo en este link
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using System.IO.Packaging;
static void Main(string[] args)
{
String fileName = @"C:/OPENXML/BigData.xlsx";
// Comment one of the following lines to test the method separately.
ReadExcelFileDOM(fileName); // DOM
//ReadExcelFileSAX(fileName); // SAX
}
// The DOM approach.
// Note that the code below works only for cells that contain numeric values.
//
static void ReadExcelFileDOM(string fileName)
{
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(fileName, false))
{
WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart;
WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();
string text;
int rowCount= sheetData.Elements<Row>().Count();
foreach (Row r in sheetData.Elements<Row>())
{
foreach (Cell c in r.Elements<Cell>())
{
text = c.CellValue.Text;
Console.Write(text + " ");
}
}
Console.WriteLine();
Console.ReadKey();
}
}
Pero no estoy recibiendo ninguna fila. No ha entrado en bucle. Nota: También configuro openXml sdk 2.5 en mi computadora
Y encuentro el código a continuación, este es el trabajo para el valor numérico. Para el valor de la cadena escribe 0 1 2 ...
private static void Main(string[] args)
{
var filePath = @"C:/OPENXML/BigData.xlsx";
using (var document = SpreadsheetDocument.Open(filePath, false))
{
var workbookPart = document.WorkbookPart;
var workbook = workbookPart.Workbook;
var sheets = workbook.Descendants<Sheet>();
foreach (var sheet in sheets)
{
var worksheetPart = (WorksheetPart)workbookPart.GetPartById(sheet.Id);
var sharedStringPart = workbookPart.SharedStringTablePart;
//var values = sharedStringPart.SharedStringTable.Elements<SharedStringItem>().ToArray();
string text;
var rows = worksheetPart.Worksheet.Descendants<Row>();
foreach (var row in rows)
{
Console.WriteLine();
int count = row.Elements<Cell>().Count();
foreach (Cell c in row.Elements<Cell>())
{
text = c.CellValue.InnerText;
Console.Write(text + " ");
}
}
}
}
Console.ReadLine();
}
Su enfoque pareció funcionar bien para mí, ya que "entró en el bucle". Sin embargo también puedes probar algo como lo siguiente:
void Main()
{
string fileName = @"c:/path/to/my/file.xlsx";
using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (SpreadsheetDocument doc = SpreadsheetDocument.Open(fs, false))
{
WorkbookPart workbookPart = doc.WorkbookPart;
SharedStringTablePart sstpart = workbookPart.GetPartsOfType<SharedStringTablePart>().First();
SharedStringTable sst = sstpart.SharedStringTable;
WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
Worksheet sheet = worksheetPart.Worksheet;
var cells = sheet.Descendants<Cell>();
var rows = sheet.Descendants<Row>();
Console.WriteLine("Row count = {0}", rows.LongCount());
Console.WriteLine("Cell count = {0}", cells.LongCount());
// One way: go through each cell in the sheet
foreach (Cell cell in cells)
{
if ((cell.DataType != null) && (cell.DataType == CellValues.SharedString))
{
int ssid = int.Parse(cell.CellValue.Text);
string str = sst.ChildElements[ssid].InnerText;
Console.WriteLine("Shared string {0}: {1}", ssid, str);
}
else if (cell.CellValue != null)
{
Console.WriteLine("Cell contents: {0}", cell.CellValue.Text);
}
}
// Or... via each row
foreach (Row row in rows)
{
foreach (Cell c in row.Elements<Cell>())
{
if ((c.DataType != null) && (c.DataType == CellValues.SharedString))
{
int ssid = int.Parse(c.CellValue.Text);
string str = sst.ChildElements[ssid].InnerText;
Console.WriteLine("Shared string {0}: {1}", ssid, str);
}
else if (c.CellValue != null)
{
Console.WriteLine("Cell contents: {0}", c.CellValue.Text);
}
}
}
}
}
}
Utilicé el método filestream para abrir el libro porque esto le permite abrirlo con acceso compartido, de modo que pueda tener el libro abierto en Excel al mismo tiempo. El método Spreadsheet.Open (... no funcionará si el libro está abierto en otra parte.
Quizás es por eso que su código no funcionó.
Tenga en cuenta, también, el uso de la SharedStringTable para obtener el texto de la celda cuando sea apropiado.
EDITAR 2018-07-11:
Como esta publicación aún está recibiendo votos, también debo señalar que en muchos casos puede ser mucho más fácil usar ClosedXML para manipular / leer / editar sus libros de trabajo. Los ejemplos de documentación son bastante fáciles de usar y la codificación es, en mi experiencia limitada, mucho más sencilla. Solo tenga en cuenta que no (todavía) implementa todas las funciones de Excel (por ejemplo, INDEX y MATCH) que pueden o no ser un problema. [No es que quiera tratar de tratar con INDEX y MATCH en OpenXML de todos modos]
Tuve el mismo problema que el OP, y la respuesta anterior no funcionó para mí.
Creo que este es el problema: cuando creas un documento en Excel (no programáticamente), tienes 3 hojas de manera predeterminada y el WorksheetParts que tiene los datos de la fila de Sheet1 es el último elemento de WorksheetParts, no el primero.
Descubrí esto poniendo un reloj para document.WorkbookPart.WorksheetParts en Visual Studio, expandiendo Resultados, luego observando todos los subelementos hasta que encontré un objeto SheetData donde HasChildren = true.
Prueba esto:
// open the document read-only
SpreadSheetDocument document = SpreadsheetDocument.Open(filePath, false);
SharedStringTable sharedStringTable = document.WorkbookPart.SharedStringTablePart.SharedStringTable;
string cellValue = null;
foreach (WorksheetPart worksheetPart in document.WorkbookPart.WorksheetParts)
{
foreach (SheetData sheetData in worksheetPart.Worksheet.Elements<SheetData>())
{
if (sheetData.HasChildren)
{
foreach (Row row in sheetData.Elements<Row>())
{
foreach (Cell cell in row.Elements<Cell>())
{
cellValue = cell.InnerText;
if (cell.DataType == CellValues.SharedString)
{
Console.WriteLine("cell val: " + sharedStringTable.ElementAt(Int32.Parse(cellValue)).InnerText);
}
else
{
Console.WriteLine("cell val: " + cellValue);
}
}
}
}
}
}
document.Close();