您好, 访客   登录/注册

C#操作Excel实用技巧三则

来源:用户上传      作者:何再朗 张梅

  摘要:Excel是常见的Office应用之一,编程实践中经常需要对其进行互操作。但在使用C#操作Excel时,经常出现无法关闭进程、无法保存文件和用户无法同时使用Excel等问题,笔者经过摸索研究,得到了针对以上问题的行之有效的解决方案。
  关键词:Excel;互操作;C#
  中图分类号:TP311      文献标识码:A
  文章编号:1009-3044(2019)26-0080-02
  开放科学(资源服务)标识码(OSID):
  在Office编程实践中,经常需要将存放在Excel中的初始数据导入到软件中,有时又需要将软件解算得到的数据导出回Excel予以保存,所以利用C#对Excel进行操作的情形时有发生。
  利用C#操作Excel,首先需要导入Excel类库,然后通过互操作调用Excel类库的类函数。这些基础性内容在许多地方都有较为详细的介绍,最详细的介绍在MSDN,在此不再赘述。本文重点介绍几个疑难问题的解决方案。
  1 无法关闭Excel进程
  利用C#操作Excel,经常出现软件结束退出,但是Excel进程却没有被关闭的现象,在任务管理器中可以看到残留的Excel僵尸进程。这虽然不影响软件的使用,但是严格深究起来属于内存泄漏,并且软件运行时间长了或者次数多了,会消耗掉大量系统内存,同时也会带来不小的安全隐患。关于解决方案,有人建议用kill进程,但是kill进程属于黑盒操作,存在着不确定性;还有一些人建议用GC回收,但是似乎时灵时不灵,实践效果也不理想。
  这其中的诀窍是,从excelApp中生成、获取的对象一定要按照它们对应的顺序,反序调用Close函数予以关闭,并将变量值统一置为null。当操作系统发现excelApp所有的衍生对象的引用计数均为0,就会自动彻底地关闭Excel进程了。需要注意的是,如果有一个衍生对象没有被置值为null,从而导致其引用计数不为0,操作系统就会误认为该对象仍然处在使用状态,导致Excel进程关闭的失败。
  2 无法保存Excel文件
  利用C#操作Excel,有时会出现无法保存Excel文件,软件报错退出的情況。基于信息保密和运行效率的考虑,我们的软件一般会采取静默模式,即隐藏Excel应用的界面,使其在后台运行。Excel应用在保存文件时往往会弹出对话框,要求用户对一些操作(如覆盖同名文件等)予以确认,但是由于应用界面被隐藏,用户无法操作,软件在经过长时间的等待后,得不到响应最终报错退出。找到了原因,问题解决起来就简单了,需要将Excel应用的DisplayAlerts属性置为false关闭提示对话框。
  打开Excel应用的代码修改如下。
  3 无法同时使用Excel应用
  至此,大部分的问题都已得到妥善的解决,剩下的唯一难题是软件在操作Excel时,用户无法同时手工使用Excel。但是软件在运行时,如果用户双击了一个Excel文件,原本被软件隐藏的Excel应用就会被显示出来,其中的数据和操作一览无余。更糟糕的是,如果此时Excel应用弹出了一个对话框用户却不及时操作的话,又会出现上一节所讨论的情况,软件在经过长时间等待后,得不到响应不得不报错退出。而如果用户手工操作关闭了软件运行所需的Excel文件甚或是关闭了Excel应用本身,后果就更为严重了,软件轻则报错,重则崩溃,还会导致数据的丢失。
  笔者经过反复试验,终于找到问题的成因。Excel应用是一个典型的Windows自动化容器,即便它在隐藏运行时也被要求随时响应用户的操作,例如双击一个Excel文件等。解决方案是提供“双应用”备份,即软件在运行时同时建立两个Excel应用,其中第一个是缓冲应用,用来响应用户可能的双击操作,第二个则是真实应用,用来向软件提供数据存取和查询等服务。需要注意的是,缓冲应用一定要位于真实应用之前,因为操作系统会将检索到的第一个Excel应用于响应用户的操作。相关的代码如下。
  进一步说,利用C#在操作Office其他应用(Word、PowerPoint等)时有许多类似的场景,所以C#操作Excel的许多经验都可以移植借鉴。
  以上我们分享了利用C#操作Excel时几个疑难问题的行之有效的解决方案,目的在于抛砖引玉,供大家参考和讨论。
  【通联编辑:李雅琪】
转载注明来源:https://www.xzbu.com/8/view-15043889.htm