открыть чтение xml из файла excel
Я хочу реализовать openXml sdk 2.5 в своем проекте. Я делаю все в этой ссылке
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().First(); string text; int rowCount= sheetData.Elements().Count(); foreach (Row r in sheetData.Elements()) { foreach (Cell c in r.Elements()) { text = c.CellValue.Text; Console.Write(text + " "); } } Console.WriteLine(); Console.ReadKey(); } }
Но я не получаю ни одной строки. Он не вступил в цикл. Примечание. Я также установил openXml sdk 2.5 на свой компьютер
И я нахожу ниже код, это работа для числового значения. Для строкового значения он записывает 0 1 2 …
- OpenKML SDK: сделайте Excel пересчитанной формулой
- Применение формата% number к значению ячейки с использованием OpenXML
- От Excel до DataTable в C # с открытым XML
- Объединение нескольких текстовых документов в один Open Xml
- Что означает, что ячейка Office Open XML содержит значение Date / Time?
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(); foreach (var sheet in sheets) { var worksheetPart = (WorksheetPart)workbookPart.GetPartById(sheet.Id); var sharedStringPart = workbookPart.SharedStringTablePart; //var values = sharedStringPart.SharedStringTable.Elements().ToArray(); string text; var rows = worksheetPart.Worksheet.Descendants(); foreach (var row in rows) { Console.WriteLine(); int count = row.Elements().Count(); foreach (Cell c in row.Elements()) { text = c.CellValue.InnerText; Console.Write(text + " "); } } } } Console.ReadLine(); }
Ваш подход, казалось, работал нормально для меня – в том, что он «входил в цикл». Тем не менее вы также можете попробовать что-то вроде следующего:
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().First(); SharedStringTable sst = sstpart.SharedStringTable; WorksheetPart worksheetPart = workbookPart.WorksheetParts.First(); Worksheet sheet = worksheetPart.Worksheet; var cells = sheet.Descendants(); var rows = sheet.Descendants(); 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()) { 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); } } } } } } | |
Я использовал метод фильтрации, чтобы открыть книгу, потому что это позволяет вам открыть ее с общим доступом – чтобы вы могли открыть книгу в Excel одновременно. Метод Spreadsheet.Open (…) не будет работать, если книга открыта в другом месте.
Возможно, поэтому ваш код не работал.
Обратите также внимание на использование SharedStringTable для получения текста ячейки, где это необходимо.
EDIT 2018-07-11:
Поскольку этот пост все еще получает голоса, я должен также отметить, что во многих случаях было бы намного проще использовать ClosedXML для управления / чтения / редактирования ваших книг. Примеры документации довольно удобны для пользователя, и кодирование в моем ограниченном опыте намного более прямолинейно. Просто имейте в виду, что он (пока) не выполняет все функции Excel (например, INDEX и MATCH), которые могут быть или не быть проблемой. [Не то чтобы я хотел бы пытаться работать с INDEX и MATCH в OpenXML в любом случае.]
У меня была такая же проблема, как и у ОП, и ответ выше не работал для меня.
Я думаю, что это проблема: при создании документа в Excel (не программно) у вас есть 3 листа по умолчанию, а WorksheetParts, которые имеют данные строки для Sheet1, является последним элементом WorksheetParts, а не первым.
Я понял это, поставив часы на document.WorkbookPart.WorksheetParts в Visual Studio, расширяя результаты, затем просматривая все вспомогательные элементы, пока не найду объект SheetData, где HasChildren = true.
Попробуй это:
// 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()) { if (sheetData.HasChildren) { foreach (Row row in sheetData.Elements()) { foreach (Cell cell in row.Elements()) { 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(); |