在Excel催化剂推出的这一年多时间里,经常性听到一种声音,大概意思是真正会写代码的人,都不会看上Excel催化剂写出来的功能,自己造一个更舒服贴心,仿佛会一点VBA就可以天下无敌一般,也好像Excel催化剂出的所有的功能,在他们眼中都是幼儿园级别,过家家玩玩而已。 这里不对此看法置评,只用事实说话,看看会一点VBA的人,能否造出以下的超强性能保障的代码功能来。
遍历单元格性能问题
学过VBA的群体,都知道遍历单元格是一个很慢的过程,最好将其放进数组中再遍历。
为何会慢这个问题,可能就没有深入研究过,而笔者用自己不专业的语言表达下原因,是因为VBA或VSTO等代码与Excel交互是用的是COM的通信,这个COM通信非常臃肿,遍历过程中,不断地来回通信,产生了十分低效的性能。
而数据在数组里,即放到内存里访问了,无需再频繁和COM接口通信,所以可以快起来。
除了COM接口访问还有其他访问方式
对于VBA、VB的开发来说,也只能用COM接口访问了,没有专业程序员世界给他们造一些好用的轮子可以直接访问xls或xlsx文件。
但在VSTO的.Net世界中,这个需求非常刚需,特别是服务器级别的应用,不可能再用COM接口来通信应付高并发性需求。所以出现了大量优秀的第3方访问类库轮子,在.Net的世界比较出名的有NPOI和EPPLUS。
因Excel催化剂并且为了满足所有用户需求而存在,对仍然使用低版本OFFICE2003版本是不支持的,所以就有所取舍,大量的场景会使用EPPLUS这个只支持OFFICE2007及以上的格式的类库轮子。
在普通遍历上可以用数组或原生的查找方法,但在需要查找替换旧数据,并且需要使用正则表达式来匹配的场景中,用以上两种方法就显得非常笨拙。
EPPLUS遍历单元格方式
以下应用的功能原始出处为:第75波-标签式报表转标准数据源https://www.jianshu.com/p/a876134c9e8f
遍历单元格在EPPLUS上非常简单,和直接在VBA对象模型上操作差不多(用NPOI就差异性较大,所以不喜欢用它)。
直接上代码 此段代码是第75波核心代码,用于将查找到的结果存储为新的表格内容,最终返回给用户一个结构化的数据源。
代码语言:javascript复制 private static void AddMatchDataToDataTable(bool isActWkb, string filePath, DataTable settingTable, ref DataTable resultTable)
{
using (var package = new ExcelPackage(new FileInfo(filePath)))
{
ExcelWorkbook wkb = package.Workbook;
foreach (var itemSht in wkb.Worksheets)
{
string itemShtName = itemSht.Name;
if (itemShtName != settingShtName && itemShtName != resultShtName)
{
foreach (var cell in itemSht.Cells)
{
if (cell.Value != null)
{
bool isMatch = IsMatchPattern(pattern, matchType, isIgnoreCase, lookin, isRegexMatch, cell);
if (isMatch)
{
DataRow dr = resultTable.NewRow();
dr["工作薄路径"] = package.File;
dr["工作表名称"] = itemShtName;
int iStart = 2;
foreach (DataRow row in settingTable.Rows)
{
//todo
dr[iStart] = GetCellInfo(cell.Offset(Convert.ToInt32(row[1]), Convert.ToInt32(row[2])));
iStart ;
}
resultTable.Rows.Add(dr);
}
}
}
}
if (isActWkb)
{
AddDataToResultSht(resultTable, wkb);
package.Save();
}// if (isActWkb)
}//foreach (var itemSht in wkb.Worksheets)
}
}
结语
在VSTO的世界中,可以调用一切专业程序员所写给我们的轮子库,相对VBA的开发来说,有天然的优势,有追求的群体,不妨再走一步,走出VBA的舒适区,拥抱VSTO的开发,会是一片更广阔的天空。