Как читать данные из электронной таблицы с помощью пакета SDK формата OpenXML?
Мне нужно прочитать данные с одного листа в книге Excel 2007 с помощью Open XML SDK 2.0. Я потратил много времени на поиск основных рекомендаций для этого, но я нашел только помощь по созданию электронных таблиц.
Как перебирать строки на листе, а затем перебирать ячейки в каждой строке, используя этот SDK?
2 ответов
то, как я это делаю, с Linq. Есть много примеров по этому вопросу от использования SDK до просто с чистым открытым XML (без SDK). Взгляните на:
- форматы Office Open XML: получение Значения Ячеек Excel 2007 (использует pure OpenXML, а не SDK, но концепции очень близки)
- использование LINQ для запроса таблиц в Excel 2007 (использует Open XML SDK, предполагает Объект listobject)
- чтение данных из SpreadsheetML (вероятно, лучшее " общее введение" статья)
другой ответ больше походил на мета-ответ. Я борюсь с этим, так как использование LINQ работает с отдельными частями документа. Следующий код включает функцию-оболочку для получения значения из ячейки, разрешая любые возможные поисковые запросы строк.
public void ExcelDocTest()
{
Debug.WriteLine("Running through sheet.");
int rowsComplete = 0;
using (SpreadsheetDocument spreadsheetDocument =
SpreadsheetDocument.Open(@"path\to\Spreadsheet.xlsx", false))
{
WorkbookPart workBookPart = spreadsheetDocument.WorkbookPart;
foreach (Sheet s in workBookPart.Workbook.Descendants<Sheet>())
{
WorksheetPart wsPart = workBookPart.GetPartById(s.Id) as WorksheetPart;
Debug.WriteLine("Worksheet {1}:{2} - id({0}) {3}", s.Id, s.SheetId, s.Name,
wsPart == null ? "NOT FOUND!" : "found.");
if (wsPart == null)
{
continue;
}
Row[] rows = wsPart.Worksheet.Descendants<Row>().ToArray();
//assumes the first row contains column names
foreach (Row row in wsPart.Worksheet.Descendants<Row>())
{
rowsComplete++;
bool emptyRow = true;
List<object> rowData = new List<object>();
string value;
foreach (Cell c in row.Elements<Cell>())
{
value = GetCellValue(c);
emptyRow = emptyRow && string.IsNullOrWhiteSpace(value);
rowData.Add(value);
}
Debug.WriteLine("Row {0}: {1}", row,
emptyRow ? "EMPTY!" : string.Join(", ", rowData));
}
}
}
Debug.WriteLine("Done, processed {0} rows.", rowsComplete);
}
public static string GetCellValue(Cell cell)
{
if (cell == null)
return null;
if (cell.DataType == null)
return cell.InnerText;
string value = cell.InnerText;
switch (cell.DataType.Value)
{
case CellValues.SharedString:
// For shared strings, look up the value in the shared strings table.
// Get worksheet from cell
OpenXmlElement parent = cell.Parent;
while (parent.Parent != null && parent.Parent != parent
&& string.Compare(parent.LocalName, "worksheet", true) != 0)
{
parent = parent.Parent;
}
if (string.Compare(parent.LocalName, "worksheet", true) != 0)
{
throw new Exception("Unable to find parent worksheet.");
}
Worksheet ws = parent as Worksheet;
SpreadsheetDocument ssDoc = ws.WorksheetPart.OpenXmlPackage as SpreadsheetDocument;
SharedStringTablePart sstPart = ssDoc.WorkbookPart.GetPartsOfType<SharedStringTablePart>().FirstOrDefault();
// lookup value in shared string table
if (sstPart != null && sstPart.SharedStringTable != null)
{
value = sstPart.SharedStringTable.ElementAt(int.Parse(value)).InnerText;
}
break;
//this case within a case is copied from msdn.
case CellValues.Boolean:
switch (value)
{
case "0":
value = "FALSE";
break;
default:
value = "TRUE";
break;
}
break;
}
return value;
}
Edit: Спасибо @Nitin-Jadhav для исправления GetCellValue ().