打开xml excel读取单元格的值
我正在使用Open XML SDK来打开一个Excel xlsx文件,并尝试读取每个工作表中位置A1上的单元格值。 我使用下面的代码:
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(openFileDialog1.FileName, false)) { var sheets = spreadsheetDocument.WorkbookPart.Workbook.Descendants<Sheet>(); foreach (Sheet sheet in sheets) { WorksheetPart worksheetPart = (WorksheetPart)spreadsheetDocument.WorkbookPart.GetPartById(sheet.Id); Worksheet worksheet = worksheetPart.Worksheet; Cell cell = GetCell(worksheet, "A", 1); Console.Writeline(cell.CellValue.Text); } } private static Cell GetCell(Worksheet worksheet, string columnName, uint rowIndex) { Row row = GetRow(worksheet, rowIndex); if (row == null) return null; return row.Elements<Cell>().Where(c => string.Compare (c.CellReference.Value, columnName + rowIndex, true) == 0).First(); } // Given a worksheet and a row index, return the row. private static Row GetRow(Worksheet worksheet, uint rowIndex) { return worksheet.GetFirstChild<SheetData>(). Elements<Row>().Where(r => r.RowIndex == rowIndex).First(); }
位置A1上的第一个工作表中的文本是简单的“testing”,但是,在我的控制台,我看到值为0 cell.CellValue.Text
有没有人有一个想法,以获得正确的价值的单元格?
Excel工作表中的所有string存储在一个名为SharedStringTable的结构中。 这个表的目标是集中在一个基于索引的数组中的所有string,然后如果在文档中多次使用该string来引用该数组中的索引。 也就是说,当你得到A1单元格的文本值时,你收到的0就是到SharedStringTable的索引。 要获得真正的价值,你可以使用这个帮手function:
public static SharedStringItem GetSharedStringItemById(WorkbookPart workbookPart, int id) { return workbookPart.SharedStringTablePart.SharedStringTable.Elements<SharedStringItem>().ElementAt(id); }
然后在你的代码中调用它来得到真正的价值:
Cell cell = GetCell(worksheet, "A", 1); string cellValue = string.Empty; if (cell.DataType != null) { if (cell.DataType == CellValues.SharedString) { int id = -1; if (Int32.TryParse(cell.InnerText, out id)) { SharedStringItem item = GetSharedStringItemById(workbookPart, id); if (item.Text != null) { cellValue = item.Text.Text; } else if (item.InnerText != null) { cellValue = item.InnerText; } else if (item.InnerXml != null) { cellValue = item.InnerXml; } } } }
阿穆拉的答案似乎走了百分之九十的方式,但它可能需要一些细微的差别。
1)函数“GetSharedStringItemById”返回一个SharedStringItem,而不是一个string,这样的调用代码示例将无法正常工作。 为了得到实际的值作为一个string,我相信你需要问的SharedStringItem的InnerText属性,如下所示:
public static string GetSharedStringItemById(WorkbookPart workbookPart, int id) { return workbookPart.SharedStringTablePart.SharedStringTable.Elements<SharedStringItem>().ElementAt(id).InnerText; }
2)该函数也(正确)要求int作为其签名的一部分,但示例代码调用提供了一个stringcell.CellValue.Text。 将string转换为int值很简单,但需要完成,因为写入的代码可能会造成混淆。
刚发现这个非常有用的片段,所以不能指出作者。
private static string GetCellValue(string fileName, string sheetName, string addressName) { string value = null; using(SpreadsheetDocument document = SpreadsheetDocument.Open(fileName, false)) { WorkbookPart wbPart = document.WorkbookPart; // Find the sheet with the supplied name, and then use that Sheet // object to retrieve a reference to the appropriate worksheet. Sheet theSheet = wbPart.Workbook.Descendants<Sheet>(). Where(s => s.Name == sheetName).FirstOrDefault(); if(theSheet == null) { throw new ArgumentException("sheetName"); } // Retrieve a reference to the worksheet part, and then use its // Worksheet property to get a reference to the cell whose // address matches the address you supplied: WorksheetPart wsPart = (WorksheetPart)(wbPart.GetPartById(theSheet.Id)); Cell theCell = wsPart.Worksheet.Descendants<Cell>(). Where(c => c.CellReference == addressName).FirstOrDefault(); // If the cell does not exist, return an empty string: if(theCell != null) { value = theCell.InnerText; // If the cell represents a numeric value, you are done. // For dates, this code returns the serialized value that // represents the date. The code handles strings and Booleans // individually. For shared strings, the code looks up the // corresponding value in the shared string table. For Booleans, // the code converts the value into the words TRUE or FALSE. if(theCell.DataType != null) { switch(theCell.DataType.Value) { case CellValues.SharedString: // For shared strings, look up the value in the shared // strings table. var stringTable = wbPart. GetPartsOfType<SharedStringTablePart>().FirstOrDefault(); // If the shared string table is missing, something is // wrong. Return the index that you found in the cell. // Otherwise, look up the correct text in the table. if(stringTable != null) { value = stringTable.SharedStringTable. ElementAt(int.Parse(value)).InnerText; } break; case CellValues.Boolean: switch(value) { case "0": value = "FALSE"; break; default: value = "TRUE"; break; } break; } } } } return value; }
另一种select:将数据导出到一个html表格,并利用样式表来指定只读单元格。 更多信息,请参见此页: http : //www.c-sharpcorner.com/UploadFile/kaushikborah28/79Nick08302007171404PM/79Nick.aspx