项目中有个需求,需要读取Excel2003的文件内容,还可能需要导出报表到Excel2003(别问我为什么是2003,客户的要求就是2003),由于是在web form中实现,有诸多限制。另外Excel文件本身也不是一个简单的行列关系表,里面有差不多10个sheet,有说明性的instruction,也有放list来供用户选择的sheet。基本上前面8个sheet是为了收集用户数据,就是让用户来填写信息的。后来2个sheet是隐藏的,用户全然不知,但是前面填的信息会用公式或者链接到隐藏的单元格。处理的时候只需要处理后面隐藏的sheet就可以了。由于Excel本身的内容有很多事圈定写死的,作者有在excel上加workbook level的password protection。就是这个workbook level的password protection为以后的工作带来了很多不便。
在项目调研初期,没有考虑到保护的工作表的读取问题,很简单的认为不是很麻烦的事情,真正到做的时候还设有遇到了不少挑战的。主要的solution有:
- Microsoft Excel component interoperation:这个组件操作excel真的没话说,但是弊端也是很致命的,就是要开发机和server端都要安装Excel。开发机还好说,server端安装excel?这对一个大公司,很多服务外包出去,按照ticket收费的公司来说,根本就是扯淡。所以这种方案根本就没有试验,直接抹去了,连微软的技术顾问都不建议使用。
- NPOI:研究过Excel操作的应该都听说过这个东东。由于之前的一个项目用过它,我开始不假思索的认为NPOI是最佳备选方案。它是开源社区的一个从Java社区移植过来的一个组件(这样的组件多的去了,很多以N开头的工具都是如此)。并且该组件的作者是一个在上海的年轻人tony,应该是高人。不过用的是和才发现,NPOI在读取密码保护的Excel的时候,莫名的报错,网上有人遇到同样的问题。作者声称已经在新版本里解决,当我兴致冲冲的下来最新版本,测试后发现,在新版本里照样有同样的问题,后来找到NPOI的作者了解详情。作者告诉我这个特性NPOI不支持,需要付费作者可以帮忙解解,解解不了退后费用。就是说作者靠支持NPOI的问题收取服务费,每次200快(汗一个,跟小姐差不多)。后来报告给项目经理,觉得不太靠谱,如果最后解决不了,对项目的风险太大。总的感觉NPOI的开发速度太慢,更新太慢,社区参与的人不多,不是一个很好的开源项目,由于后来作者向我收取服务费,感觉下降已一截,有违背开源的精神。
- OLE DB:这个是很久以前微软的访问数据的一个通用驱动(规范),可以访问很多类型的数据源,如Excel、Access、Sql server。就连大名鼎鼎的ADO。Net好像也是建立在OLE DB基础上的。OLE DB访问Excel的时候同样的问题,密码保护的工作表不支持。还有一些其他问题,如日期格式的cell读出来是一个整形的数值。这个数值是1900-01-01加上这个值得到日期才是真正的value。另外,性能也是一个问题,一般在连接好excel以后,执行select sql command,把excel中的数据fill到一个dataset中要2秒左右,可能是我的exce sheet数据比较大,还没有试过其他的。
- SpreadsheetGear:这个是商业社会的东西,试用过以后觉得确实不错,简单、直观。并且支持密码保护的工作表,还可以读取cell的值和文字,性能也不错。问题就是人家要收费,一个开发的licence要999美元,只能用于一个人开发。(所幸目前项目就我一个人开发,再汗一个)
中间尝试过其他方法,比如干脆不锁workbook。还有一个网友给出建议就是当用户打开excel的时候,利用macro来把工作表锁定。用户填写完了,关闭excel的时候,再把工作表解锁。代码如下:
Private Sub Workbook_Open()
ThisWorkbook.Protect Password:="mikealu"
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
ThisWorkbook.Unprotect Password:="mikealu"
End Sub
这样用户用excel的时候是锁定的,用户不用的时候,比如导入的时候,就不是锁定的,这样就不存在上面的问题了。可是,这个当用户打开excel的时候macro会提示用户是否启用,如果不启用就没有效果了,macro不会默认就启用的,所以效果也不能能保证。
调研结果如上,目前等项目经理排版到底采取哪种方式。
另外:在调研期间还试验了一种商业工具,GemBox,好像也不支持保护的工作表的读取。