[背景] XX項目中需要大量保存讀取Excel操作,目前讀取保存單個Excel文件使用了spreadsheetgear-silverlight進行操作。但是很多Excel間有大量公式引用無法自動更新,因此考慮臺自動刷新及保存,
工具:VS2010(C#)+office2007
引用 Microsoft.Office.Interop.Excel(14.0.0.0)
核心代碼如下:
using System;
using System.Collections.Generic;
using Excel = Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;
//定義句柄變量
public static IntPtr hwnd;
//定義進程ID變量
public static int pid = 0;
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID);
//函數原型;DWORD GetWindowThreadProcessld(HWND hwnd,LPDWORD lpdwProcessld);
//參數:hWnd:窗口句柄
//參數:lpdwProcessld:接收進程標識的32位值的地址。如果這個參數不爲NULL,GetWindwThreadProcessld將進程標識拷貝到這個32位值中,否則不拷貝
//返回值:返回值爲創建窗口的線程標識。
[DllImport("kernel32.dll")]
public static extern int OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
//函數原型:HANDLE OpenProcess(DWORD dwDesiredAccess,BOOL bInheritHandle,DWORD dwProcessId);
//參數:dwDesiredAccess:訪問權限。
//參數:bInheritHandle:繼承標誌。
//參數:dwProcessId:進程ID。
public const int PROCESS_ALL_ACCESS = 0x1F0FFF;
public const int PROCESS_VM_READ = 0x0010;
public const int PROCESS_VM_WRITE = 0x0020;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnOSExcel_Click(object sender, EventArgs e)
{
OPenSaveExcel("");
}
private void OPenSaveExcel(string fileName)
{
Excel.Application xlApp = new Excel.Application();
Excel.Workbook xlBook = null;
Excel.Worksheet xlSheet = null;
try
{
xlBook = xlApp.Workbooks.Open(@"D:\DocCenter\名片.xls");
//獲取Excel App的句柄
hwnd = new IntPtr(xlApp.Hwnd);
//通過Windows API獲取Excel進程ID
GetWindowThreadProcessId(hwnd, out pid);
this.lb_ProcessID.Text = pid.ToString();
xlApp.DisplayAlerts = false;
xlApp.Calculate();
xlBook.RefreshAll();
xlBook.Save();
xlApp.Workbooks.Close();
xlApp.Quit();
}
catch (Exception)
{
//正常退出Excel失敗,可以記錄一下日誌.
}
finally
{
//強制結束Excel進程
if (xlApp != null && pid > 0)
{
int ExcelProcess;
ExcelProcess = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE, false, pid);
//判斷進程是否仍然存在
if (ExcelProcess > 0)
{
try
{
//通過進程ID,找到進程
System.Diagnostics.Process process = System.Diagnostics.Process.GetProcessById(pid);
//Kill 進程
process.Kill();
this.lb_ProcessID.Text += ",強制關閉";
}
catch (Exception)
{
//強制結束Excel進程失敗,可以記錄一下日誌.
}
}
else
{
//進程已經結束了
this.lb_ProcessID.Text += ",自動關閉";
}
}
}
}