使用C#pipe理大型Excel文件

我写了一个小的C#过程,比较两个属于两个不同的Excel工作表的列。 每个这些列包含大约23.000个单元格。 对于第一列的每个元素,过程检查元素的值是否存在于第二列中,如果不存在,则从第一个工作表中删除该行。 问题在于这个过程非常慢:大约需要10秒来扫描第二列的匹配值,因此程序执行需要大约10 * 23.000秒= 63小时。

有没有更快的方式在C#中做到这一点?

这是解决这个问题的一种方法。 你说你有大约23000行的GUID,所以你应该能够加载第2列的所有GUID的HashSet 。然后你可以只处理column1,把你在HashSet中find的每个元素。

 var column2 = new HashSet<Guid>(); // Load this set with the data from column2 // Now you can just use a simple LINQ query to create a new column1 var column1Result = column1.Where(x => column2.Contains(x)).ToList(); 

现在,您将获得一个GUID列表,即您的新列1。 只需用新的列replace原来的列1并保存该文件。

在我的机器上进行testing,包括填充两个列表和一个包含100,000个GUID(我的testing列1有50,000个匹配和50,000个不匹配)的集合,整个事情花了大约0.15秒。

编辑 – 基于你的评论与你描述的情况一样,我会parsing工作表2来获取GUIDS,并将所有这些都放在HashSet 。 然后,我只是走在工作表2的第一列,并检查HashSet包含,并根据需要删除。

如果列中的值是双精度型,那么可以对它们进行sorting。 在每一个search循环中,从最后一个循环开始的最后一个位置,当到达一个比你所寻找的更大的数字时停止search。

例如,你想在数组[1,3,4,5,6,7,9,10]中寻找[2,4,7]。 对于第一个循环,你想查找数字2,所以你的search范围是[1,3]。 你停在3,因为3大于2.然后下一个search,你从3开始,到4结束,因为你find了它。

毫无疑问,有一百万种不同的方式来做到这一点。 使用Excel可能会有特别的挂断,你想检查。 其他人提到删除是一个缓慢的function,但也确保你没有创build/处置对象,每次你运行检查。 保留所有的对象,只是改变你需要的variables。 您也可以考虑multithreading并在不同的线程上处理每一行。 除非你对自己的multithreading技能有信心,否则不要试试

试试这个简单的基于sorting的解决scheme来缩短parsing时间 –

  1. 对A行和B行进行sorting
  2. 将值存储在B的中间(单元格B.Count / 2的值)
  3. 通过A进行迭代 – 首先检查B值的上半部分或下半部分,然后仅search该列的一半。

*确保您的列表已经不同,请确保在find该值后中断处理。