我计算两个工作表中的行,如下所示:
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
两次解析每个列表?
修改
好吧,我找到了解决方案。为了得到它,我想,你应该将这种神圣的知识保存在一个秘密的地方。所以,这是:
while (reader.Read())
{
if (reader.ElementType == typeof(Row))
{
do
{
count_first++;
} while (reader.ReadNextSibling());
}
}
答案 0 :(得分:3)
您获得两倍计数的原因是OpenXmlReader
读取每个元素的方式。阅读器将打开和关闭节点视为可以通过检查IsStartElement
和IsEndElement
属性来区分的独立项目。
为了证明这一点,您可以运行以下内容:
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");
}
}
}
对于包含两行和两列的工作表,我们将沿着以下*的行生成输出(我已经突出显示了行的可读性):
行真假
Cell True False
CellValue True False
CellValue False True Cell False True Cell True False
CellValue True False
CellValue False True Cell False True Row False True
Row True False
Cell True False
CellValue True False
CellValue False True Cell False True Cell True False
CellValue True False
CellValue False True Cell False True Row False True
根据您希望如何阅读文档,有两种方法可以解决此问题。第一种方式(正如你在答案中指出的那样)是通过调用ReadNextSibling
来移动到下一个兄弟 - 这实质上是“跳跃”结束元素(以及Row
的任何子元素)。更改上面的示例以在ReadNextSibling
循环中使用do
:
do
{
Console.WriteLine("{0} {1} {2}",
reader.ElementType,
reader.IsStartElement,
reader.IsEndElement);
} while (reader.ReadNextSibling());
您将获得输出*:
Row True False
Row True False
第二种方法是只计算起始元素(或者实际上是结束元素;只是不计算两者):
while (reader.Read())
{
if (reader.ElementType == typeof(Row) && reader.IsStartElement)
{
count_first++;
}
}
您选择哪一个取决于您是否希望阅读Cell
值以及 您想要阅读它们(SAX或DOM)。
*实际上,每一行的前缀都是“DocumentFormat.OpenXml.Spreadsheet”的命名空间。为了便于阅读,我删除了它。
答案 1 :(得分:0)
这可以按预期工作:
while (reader.Read())
{
if (reader.ElementType == typeof(Row))
{
do
{
count_first++;
} while (reader.ReadNextSibling());
}
}