我开始编写一个小的包装器类来处理我的excel操作:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Excel = Microsoft.Office.Interop.Excel;
using System.Reflection;
namespace CSVReader
{
class ExcelManager
{
// Holds instance of application.
public Excel.Application application;
/**
* Class Constructor.
*/
public ExcelManager()
{
// Create a new application instance.
application = new Excel.Application();
}
/**
* Helper to open workbooks.
*/
public void Open(string filename) {
application.Workbooks.Open(filename, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
}
/**
*/
public Excel.Range Find(string search)
{
Excel.Workbooks books = application.Workbooks;
Excel.Range currentFind = null;
Excel.Range firstFind = null;
// Search all workbooks.
foreach(Excel.Workbook book in books)
{
// Get first sheet.
Excel.Worksheet sheet = book.Worksheets.get_Item(1);
// Get all data for sheet.
Excel.Range firstCell = sheet.Range["A1", Type.Missing];
Excel.Range lastCell = sheet.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell, Type.Missing);
Excel.Range sheetData = sheet.Range[firstCell, lastCell];
currentFind = sheetData.Find(search, Type.Missing,
Excel.XlFindLookIn.xlValues, Excel.XlLookAt.xlPart,
Excel.XlSearchOrder.xlByRows, Excel.XlSearchDirection.xlNext, false,
Type.Missing, Type.Missing);
while (currentFind != null)
{
// Keep track of the first range you find.
if (firstFind == null)
{
firstFind = currentFind;
}
// If you didn't move to a new range, you are done.
else if (currentFind.get_Address(Type.Missing, Type.Missing, Excel.XlReferenceStyle.xlA1, Type.Missing, Type.Missing)
== firstFind.get_Address(Type.Missing, Type.Missing, Excel.XlReferenceStyle.xlA1, Type.Missing, Type.Missing))
{
break;
}
currentFind = sheetData.FindNext(currentFind);
}
}
return currentFind;
}
}
}
我实例化该类并告诉它加载两个工作簿并搜索字符串:
ExcelManager manager = new ExcelManager();
manager.Open(@"c:\test\test1.xls");
manager.Open(@"c:\test\test2.XLS");
Excel.Range result = manager.Find('test cell');
if (result != null)
{
// Do something funky.
}
else
{
// Use a log file instead.
Console.WriteLine("item was not found found in the current sheet.");
}
问题是,当我运行此代码时,即使使用小型工作簿,它也非常慢。我的C#知识很少,所以我一整天都在学习教程。这是一个搜索多张床单的好方法吗?会使用OLE更快吗?此应用程序的目的只是运行检查以汇总未在我打开的工作簿中的任何工作表中出现的值。
答案 0 :(得分:0)
我的第一个回复是interop使用您的Excel安装来收集信息。将运行Excel安装中的任何初始化逻辑,这将使代码的加载时间非常慢。
如果是这种情况,您可以做些什么来测试: 基准测试哪个函数使搜索变慢。 find函数或加载ExcelManager类/ open函数。
如果结果是速度损失不是由find函数引起的,你可以考虑一个解析文件本身而不是使用interop的库。