Excel对象无法关闭的解决办法
导出Excel的时候遇到一个问题,在客户那里有很多模板,我的程序经过他们测试基本上都能正常导出,但有一个模板导出的时候出现了“黄页”,这是相当没面子的事,我就把模板要了过来,发现这个模板存在一个问题:就是当你打开模板之后,不做任何修改,随即就关闭,这时仍会提示你保存修改。由于项目经验不足,开始不知道为什么会有这样的问题,经过查资料发现Excel中存在一些易失性函数,常见的易失性函数有:NOW(),TODAY(),RAND(),CELL(),OFFSET(),INDIRECT(),INFO(),RANDBETWEEN(),当你的工作簿中有这些函数的话,每次打开都会重新进行计算,关闭的时候就会提示是否保存修改。客户那里出黄页的模板中就用到了TODAY()函数,这样在我的程序关闭Excel工作表时就会遇到一个弹出框,我不知道怎样去处理它,原先关闭工作表的代码是VBA的WorkBook.Close(true,Missing,Missing)在这里第一个参数不管选保存还是不保存,都会出现异常。
原因找到了,解决办法也得考虑,既然正常的关闭方法出现异常,那只能是强行关闭进程了,然后在网上找到了获得进程ID的方法,如代码中所示。IntPtr为一个句柄,这里实例为ExcelApplication.Hwnd,id作为GetWindowThreadProcessId()函数的一个输出参数,经过该函数处理即得到该句柄的进程ID,然后得到进程,Kill。
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int id);
public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int id);
public void Close(bool isSave)
{
try
{
excelWorkBook.Close(isSave, Type.Missing, Type.Missing);
excelApp.Quit();
}
catch
{
IntPtr t = new IntPtr(excelApp.Hwnd);
int k = 0;
GetWindowThreadProcessId(t, out k);
System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(k);
p.Kill();
}
excelWorkBook = null;
excelApp = null;
GC.Collect();
}
{
try
{
excelWorkBook.Close(isSave, Type.Missing, Type.Missing);
excelApp.Quit();
}
catch
{
IntPtr t = new IntPtr(excelApp.Hwnd);
int k = 0;
GetWindowThreadProcessId(t, out k);
System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(k);
p.Kill();
}
excelWorkBook = null;
excelApp = null;
GC.Collect();
}
或者把ExcelApplication的DisplayAlerts属性设置为false,把WorkBook的Saved属性设置为True,就不会有烦人的对话框弹出了,不知道这样行不行?