何再朗 張梅
摘要:Excel是常見的Office應(yīng)用之一,編程實(shí)踐中經(jīng)常需要對(duì)其進(jìn)行互操作。但在使用C#操作Excel時(shí),經(jīng)常出現(xiàn)無法關(guān)閉進(jìn)程、無法保存文件和用戶無法同時(shí)使用Excel等問題,筆者經(jīng)過摸索研究,得到了針對(duì)以上問題的行之有效的解決方案。
關(guān)鍵詞:Excel;互操作;C#
中圖分類號(hào):TP311? ? ? 文獻(xiàn)標(biāo)識(shí)碼:A
文章編號(hào):1009-3044(2019)26-0080-02
開放科學(xué)(資源服務(wù))標(biāo)識(shí)碼(OSID):
在Office編程實(shí)踐中,經(jīng)常需要將存放在Excel中的初始數(shù)據(jù)導(dǎo)入到軟件中,有時(shí)又需要將軟件解算得到的數(shù)據(jù)導(dǎo)出回Excel予以保存,所以利用C#對(duì)Excel進(jìn)行操作的情形時(shí)有發(fā)生。
利用C#操作Excel,首先需要導(dǎo)入Excel類庫,然后通過互操作調(diào)用Excel類庫的類函數(shù)。這些基礎(chǔ)性內(nèi)容在許多地方都有較為詳細(xì)的介紹,最詳細(xì)的介紹在MSDN,在此不再贅述。本文重點(diǎn)介紹幾個(gè)疑難問題的解決方案。
1 無法關(guān)閉Excel進(jìn)程
利用C#操作Excel,經(jīng)常出現(xiàn)軟件結(jié)束退出,但是Excel進(jìn)程卻沒有被關(guān)閉的現(xiàn)象,在任務(wù)管理器中可以看到殘留的Excel僵尸進(jìn)程。這雖然不影響軟件的使用,但是嚴(yán)格深究起來屬于內(nèi)存泄漏,并且軟件運(yùn)行時(shí)間長了或者次數(shù)多了,會(huì)消耗掉大量系統(tǒng)內(nèi)存,同時(shí)也會(huì)帶來不小的安全隱患。關(guān)于解決方案,有人建議用kill進(jìn)程,但是kill進(jìn)程屬于黑盒操作,存在著不確定性;還有一些人建議用GC回收,但是似乎時(shí)靈時(shí)不靈,實(shí)踐效果也不理想。
這其中的訣竅是,從excelApp中生成、獲取的對(duì)象一定要按照它們對(duì)應(yīng)的順序,反序調(diào)用Close函數(shù)予以關(guān)閉,并將變量值統(tǒng)一置為null。當(dāng)操作系統(tǒng)發(fā)現(xiàn)excelApp所有的衍生對(duì)象的引用計(jì)數(shù)均為0,就會(huì)自動(dòng)徹底地關(guān)閉Excel進(jìn)程了。需要注意的是,如果有一個(gè)衍生對(duì)象沒有被置值為null,從而導(dǎo)致其引用計(jì)數(shù)不為0,操作系統(tǒng)就會(huì)誤認(rèn)為該對(duì)象仍然處在使用狀態(tài),導(dǎo)致Excel進(jìn)程關(guān)閉的失敗。
2 無法保存Excel文件
利用C#操作Excel,有時(shí)會(huì)出現(xiàn)無法保存Excel文件,軟件報(bào)錯(cuò)退出的情況?;谛畔⒈C芎瓦\(yùn)行效率的考慮,我們的軟件一般會(huì)采取靜默模式,即隱藏Excel應(yīng)用的界面,使其在后臺(tái)運(yùn)行。Excel應(yīng)用在保存文件時(shí)往往會(huì)彈出對(duì)話框,要求用戶對(duì)一些操作(如覆蓋同名文件等)予以確認(rèn),但是由于應(yīng)用界面被隱藏,用戶無法操作,軟件在經(jīng)過長時(shí)間的等待后,得不到響應(yīng)最終報(bào)錯(cuò)退出。找到了原因,問題解決起來就簡(jiǎn)單了,需要將Excel應(yīng)用的DisplayAlerts屬性置為false關(guān)閉提示對(duì)話框。
打開Excel應(yīng)用的代碼修改如下。
3 無法同時(shí)使用Excel應(yīng)用
至此,大部分的問題都已得到妥善的解決,剩下的唯一難題是軟件在操作Excel時(shí),用戶無法同時(shí)手工使用Excel。但是軟件在運(yùn)行時(shí),如果用戶雙擊了一個(gè)Excel文件,原本被軟件隱藏的Excel應(yīng)用就會(huì)被顯示出來,其中的數(shù)據(jù)和操作一覽無余。更糟糕的是,如果此時(shí)Excel應(yīng)用彈出了一個(gè)對(duì)話框用戶卻不及時(shí)操作的話,又會(huì)出現(xiàn)上一節(jié)所討論的情況,軟件在經(jīng)過長時(shí)間等待后,得不到響應(yīng)不得不報(bào)錯(cuò)退出。而如果用戶手工操作關(guān)閉了軟件運(yùn)行所需的Excel文件甚或是關(guān)閉了Excel應(yīng)用本身,后果就更為嚴(yán)重了,軟件輕則報(bào)錯(cuò),重則崩潰,還會(huì)導(dǎo)致數(shù)據(jù)的丟失。
筆者經(jīng)過反復(fù)試驗(yàn),終于找到問題的成因。Excel應(yīng)用是一個(gè)典型的Windows自動(dòng)化容器,即便它在隱藏運(yùn)行時(shí)也被要求隨時(shí)響應(yīng)用戶的操作,例如雙擊一個(gè)Excel文件等。解決方案是提供“雙應(yīng)用”備份,即軟件在運(yùn)行時(shí)同時(shí)建立兩個(gè)Excel應(yīng)用,其中第一個(gè)是緩沖應(yīng)用,用來響應(yīng)用戶可能的雙擊操作,第二個(gè)則是真實(shí)應(yīng)用,用來向軟件提供數(shù)據(jù)存取和查詢等服務(wù)。需要注意的是,緩沖應(yīng)用一定要位于真實(shí)應(yīng)用之前,因?yàn)椴僮飨到y(tǒng)會(huì)將檢索到的第一個(gè)Excel應(yīng)用于響應(yīng)用戶的操作。相關(guān)的代碼如下。
進(jìn)一步說,利用C#在操作Office其他應(yīng)用(Word、PowerPoint等)時(shí)有許多類似的場(chǎng)景,所以C#操作Excel的許多經(jīng)驗(yàn)都可以移植借鑒。
以上我們分享了利用C#操作Excel時(shí)幾個(gè)疑難問題的行之有效的解決方案,目的在于拋磚引玉,供大家參考和討論。
【通聯(lián)編輯:李雅琪】