概述ASP.NET調(diào)用Excel進(jìn)程
ASP.NET調(diào)用Excel進(jìn)程
關(guān)于在ASP.NET調(diào)用Excel進(jìn)程不能結(jié)束進(jìn)程的問題,常見的解決方法用的是下面這段代碼
- wb.Close(null,null,null);
- app.Workbooks.Close();
- app.Quit();
- if(rng!=null)
- {
- System.Runtime.InteropServices.Marshal.ReleaseComObject(rng);
- rng=null;
- }
- if(ws!=null)
- {
- System.Runtime.InteropServices.Marshal.ReleaseComObject(ws);
- ws=null;
- }
- if(wb!=null)
- {System.Runtime.InteropServices.Marshal.ReleaseComObject(wb);
- wb=null;
- }
- if(app!=null)
- {System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
- app=null;
- }
- GC.Collect();
雖然這段代碼在配置正確的情況下能自動結(jié)束Excel進(jìn)程,但是前提是在操作Excel時沒有引發(fā)異常的情況下,如果有異常發(fā)生,那么Excel進(jìn)程將不能結(jié)束(比如:引用了一個在Excel文件中不存在的文本框時就會出現(xiàn)“HRESULT 中的異常:0x800A03EC?!保?,這時就要借助Process類的Kill()方法來結(jié)束,下面是我寫的測試代碼:
- usingSystem;
- usingSystem.Diagnostics;
- usingexcel=Microsoft.Office.Interop.Excel;
- namespaceExcelTest
- {
- /**////<summary>
- ///Excel的摘要說明。
- ///</summary>
- publicclassExcel
- {
- privateDateTimebeforeTime;//Excel啟動之前時間
- privateDateTimeafterTime;//Excel啟動之后時間
- excel.Applicationapp;
- excel.Workbookwb;
- excel.Worksheetws;
- excel.Rangerng;
- excel.TextBoxtb;
- publicExcel(stringtempletPath)
- {
- //實例化一個ExcelApplication對象并使其可見
- beforeTime=DateTime.Now;
- app=newexcel.ApplicationClass();
- app.Visible=true;
- afterTime=DateTime.Now;
- wb=app.Workbooks.Open(templetPath,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);- ws=(excel.Worksheet)wb.Worksheets.get_Item(1);
- }
- publicvoidExcelMethod()
- {
- rng=ws.get_Range("B5","C7");
- rng.Merge(excel.XlAxisCrosses.xlAxisCrossesAutomatic);
- rng.Value2="Excel2003";
- rng=ws.get_Range("D8","E11");
- rng.MergeCells=true;
- rng.Value2="Excel2003";
- rng.HorizontalAlignment=excel.XlHAlign.xlHAlignCenter;
- rng.VerticalAlignment=excel.XlVAlign.xlVAlignCenter;
- rng=ws.get_Range("A1",Type.Missing);
- rng.Value2=5;
- rng=ws.get_Range("A2",Type.Missing);
- rng.Value2=7;
- for(inti=1;i<100;i++)
- {
- stringstrings=string.Concat("G",i.ToString());
- rng=ws.get_Range(s,Type.Missing);
- rng.Value2=i.ToString();
- }
- tb=(excel.TextBox)ws.TextBoxes("文本框1");
- tb.Text="作者";
- tb=(excel.TextBox)ws.TextBoxes("文本框2");
- tb.Text="KLY.NET的Blog";
- tb=(excel.TextBox)ws.TextBoxes("文本框3");
- tb.Text="日期";
- try
- {
- tb=(excel.TextBox)ws.TextBoxes("文本框5");
- tb.Text=DateTime.Now.ToShortDateString();
- }
- catch
- {
- //這里用Dispose()方法結(jié)束不了Excel進(jìn)程,所有還是要用Process的Kill()方法配合使用
- //this.Dispose();
- this.KillExcelProcess();
- thrownewException("不存在ID為\"文本框5\"的文本框!");
- }
- finally
- {
- //如果有異常發(fā)生,Dispose()方法放在這里也結(jié)束不了Excel進(jìn)程
- //this.Dispose();
- //如果發(fā)生異常,在這里也可以結(jié)束Excel進(jìn)程
- //this.KillExcelProcess();
- }
- }
- /**////<summary>
- ///另存為Excel文件
- ///</summary>
- ///<paramnameparamname="savePath">保存路徑</param>
- publicvoidSaveAsExcelFile(stringsavePath)
- {
- wb.SaveAs(savePath,excel.XlFileFormat.xlHtml,Type.Missing,Type.
Missing,Type.Missing,Type.Missing,excel.XlSaveAsAccessMode.xlExclusive,Type.
Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing);- }
- /**////<summary>
- ///結(jié)束Excel進(jìn)程
- ///</summary>
- publicvoidKillExcelProcess()
- {
- Process[]myProcesses;
- DateTimestartTime;
- myProcesses=Process.GetProcessesByName("Excel");
- //得不到Excel進(jìn)程ID,暫時只能判斷進(jìn)程啟動時間
- foreach(ProcessmyProcessinmyProcesses)
- {
- startTime=myProcess.StartTime;
- if(startTime>beforeTime&&startTime<afterTime)
- {
- myProcess.Kill();
- }
- }
- }
- /**////<summary>
- ///如果對Excel的操作沒有引發(fā)異常的話,用這個方法可以正常結(jié)束Excel進(jìn)程
- ///否則要用KillExcelProcess()方法來結(jié)束Excel進(jìn)程
- ///</summary>
- publicvoidDispose()
- {
- wb.Close(null,null,null);
- app.Workbooks.Close();
- app.Quit();
- //注意:這里用到的所有Excel對象都要執(zhí)行這個操作,否則結(jié)束不了Excel進(jìn)程
- if(rng!=null)
- {
- System.Runtime.InteropServices.Marshal.ReleaseComObject(rng);
- rng=null;
- }
- if(tb!=null)
- {
- System.Runtime.InteropServices.Marshal.ReleaseComObject(tb);
- tb=null;
- }
- if(ws!=null)
- {
- System.Runtime.InteropServices.Marshal.ReleaseComObject(ws);
- ws=null;
- }
- if(wb!=null)
- {
- System.Runtime.InteropServices.Marshal.ReleaseComObject(wb);
- wb=null;
- }
- if(app!=null)
- {
- System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
- app=null;
- }
- GC.Collect();
- }
- }
- }
這段代碼能很好的解決Excel進(jìn)程不能正常結(jié)束的問題,如果主機操作系統(tǒng)不是服務(wù)器版的話,那么就要借助于ntsd -c q -p pid命令來結(jié)束。
還有一個問題的關(guān)于Excel組件訪問權(quán)限的配置,一定要在組件服務(wù)里面正確配置,否則結(jié)束不了Excel進(jìn)程,具體的配置方法在我項目的doc文件夾下;在我前面的文章里面介紹了在web.config文件里面加入假扮用戶的方法,但是經(jīng)我測試發(fā)現(xiàn)這種方法雖然可以訪問Excel組件,但是結(jié)束不了進(jìn)程,除非用Kill方法強行結(jié)束。以上介紹ASP.NET調(diào)用Excel進(jìn)程。
【編輯推薦】