为什么OpenXML读两次
我在两个工作表中的行数如下所示:
foreach (WorksheetPart worksheetPart in workbookPart.WorksheetParts) { OpenXmlPartReader reader = new OpenXmlPartReader(worksheetPart); if (count == 0) { while (reader.Read()) { if (reader.ElementType == typeof(Row)) { count_first++; } } } else if (count == 1) { while (reader.Read()) { if (reader.ElementType == typeof(Row)) { count_second++; } } } count++; }
对于count_first
和count_second
两个工作表,我得到的数据是有数据行的两倍。 为什么是这个,它实际上是什么意思? 这是否意味着OpenXML
parsing每个列表两次?
编辑
那么,我find了一个解决scheme。 为了马上得到它,我想,你应该把这个神圣的知识保存在一个秘密的地方。 所以,这里是:
while (reader.Read()) { if (reader.ElementType == typeof(Row)) { do { count_first++; } while (reader.ReadNextSibling()); } }
你得到两倍数的原因是由于OpenXmlReader
读取每个元素的方式。 阅读器将打开和closures的节点视为可以通过检查IsStartElement
和IsEndElement
属性来区分的独立项目。
为了certificate这一点,你可以运行这样的东西:
using (OpenXmlReader reader = OpenXmlReader.Create(worksheetPart)) { while (reader.Read()) { if (reader.ElementType == typeof(Row)) { do { Console.WriteLine("{0} {1} {2}", reader.ElementType, reader.IsStartElement, reader.IsEndElement); } while (reader.Read()); Console.WriteLine("Finished"); } } }
这将产生沿着下面的行输出*为两行两列的表(我已经突出了行的可读性):
行真假
细胞真假
CellValue True False
CellValue假真
单元格错误
细胞真假
CellValue True False
CellValue假真
单元格错误
排假是真的
行真假
细胞真假
CellValue True False
CellValue假真
单元格错误
细胞真假
CellValue True False
CellValue假真
单元格错误
排假是真的
有两种方法可以解决这个问题,这取决于你如何阅读文档。 第一种方法(就像你在答案中指出的那样)是通过调用ReadNextSibling
移动到下一个兄弟ReadNextSibling
– 这实质上是“跳转”了终止元素(以及Row
任何子节点)。 更改上面的示例以在do
循环中使用ReadNextSibling
:
do { Console.WriteLine("{0} {1} {2}", reader.ElementType, reader.IsStartElement, reader.IsEndElement); } while (reader.ReadNextSibling());
你会得到输出*的:
行真假
行真假
第二种方法是只计算开始元素(或实际上是结束元素,而不是两者):
while (reader.Read()) { if (reader.ElementType == typeof(Row) && reader.IsStartElement) { count_first++; } }
你select哪一个取决于你是否希望读取Cell
值, 以及你想如何读取它们(SAX或DOM)。
*实际上,每行都以“DocumentFormat.OpenXml.Spreadsheet”的名称空间作为前缀。 我已经删除了可读性。
这按预期工作:
while (reader.Read()) { if (reader.ElementType == typeof(Row)) { do { count_first++; } while (reader.ReadNextSibling()); } }
- 将DataGridView导出到Excel的简单方法
- 旧格式或无效的types库。 (从HRESULTexception:0x80028018(TYPE_E_INVDATAREAD))
- 在closures由EPPlus创build的Excel文件之前显示“另存为对话框”(没有macros的方式)
- 打开xml sdk,读取excel公式单元格
- 如何使用PdfReport生成.xlsx文件
- c#excel Interop.XlDVType.xlValidateList自动完成IncellDropDown
- 从Excel表中读取数据包含多个表c#
- 当我导入Excel时,一个额外的行被添加到数据库中的C#
- 读取和写入Excel的最佳方法是不依赖于Azure云服务?