如何提高在OpenXml Excel电子表格工具中从SharedStringTable中检索值的性能?

我使用DocumentFormat.OpenXml来读取Excel电子表格。 我有一个性能瓶颈用于从SharedStringTable对象查找单元格值的代码(它似乎是某种查找表的单元格值):

 var returnValue = sharedStringTablePart.SharedStringTable.ChildElements.GetItem(parsedValue).InnerText; 

我已经创build了一个字典,以确保我只检索一次值:

 if (dictionary.ContainsKey(parsedValue)) { return dictionary[parsedValue]; } var fetchedValue = sharedStringTablePart.SharedStringTable.ChildElements.GetItem(parsedValue).InnerText; dictionary.Add(parsedValue, fetchedValue); return fetchedValue; 

这使演出时间缩短了近50%。 但是,我的指标表明,从SharedStringTable对象获取值执行123,951次的代码行仍需要208秒。 有没有其他的方法来优化这个操作?

我会一口气把整个共享string表读入字典,而不是根据需要查找每个值。 这将允许您按顺序浏览文件,并将值存储为散列查找,这比为每个需要的值扫描SST效率更高。

在stream程开始时运行如下的代码将允许您使用dictionary[parsedValue]访问每个值。

 private static void LoadDictionary() { int i = 0; foreach (var ss in sharedStringTablePart.SharedStringTable.ChildElements) { dictionary.Add(i++, ss.InnerText); } } 

如果你的文件非常大,你可能会看到使用SAX方法读取文件的一些好处,而不是上面的DOM方法:

 private static void LoadDictionarySax() { using (OpenXmlReader reader = OpenXmlReader.Create(sharedStringTablePart)) { int i = 0; while (reader.Read()) { if (reader.ElementType == typeof(SharedStringItem)) { SharedStringItem ssi = (SharedStringItem)reader.LoadCurrentElement(); dictionary.Add(i++, ssi.Text != null ? ssi.Text.Text : string.Empty); } } } } 

在我的机器上,使用60000行和2列的文件,使用上面的LoadDictionary方法代替了问题中的GetValue方法的速度要快300倍左右。 LoadDictionarySax方法给出了类似的性能,但是在一个更大的文件(100000行,10列)上,SAX方法比LoadDictionary方法快25%左右。 在一个更大的文件(100000行,26列)上, LoadDictionary方法抛出了内存LoadDictionarySaxexception,但LoadDictionarySax没有问题。