C# 釋放excel 殺掉excel 而其它Excel進程則相安無事


    最近,做了幾個月的WinForm,接觸了一些進程、句柄方面的知識。於是試着解決一下,沒想到成功了,創建的Excel進程被成功Kill掉了,而其它Excel進程則相安無事。
    關鍵代碼:
    查看源代碼打印?public void KillSpecialExcel()
    {
    try
    {
    if (m_objExcel != null)
    {
    int lpdwProcessId;
    GetWindowThreadProcessId(new IntPtr(m_objExcel.Hwnd), out lpdwProcessId);
    System.Diagnostics.Process.GetProcessById(lpdwProcessId).Kill();
    }
    }
    catch (Exception ex)
    {
    Console.WriteLine("Delete Excel Process Error:" + ex.Message);
    }
    }
    操作生成Excel的全部代碼:
    查看源代碼打印?using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Reflection;
    using System.Runtime.InteropServices;
    using System.Drawing;
    namespace VeryCodes.Common.MyExcel
    {
    ///
    /// ExcelClass 的摘要說明。
    ///
    public class MSExcel
    {
    ///
    /// 構建ExcelClass類
    ///
    public MSExcel()
    {
    //別忘了需要添加Excel Library的引用
    this.m_objExcel = new Microsoft.Office.Interop.Excel.Application();
    }
    ///
    /// 構建ExcelClass類
    ///
    ///
    Excel.Application
    public MSExcel(Microsoft.Office.Interop.Excel.Application objExcel)
    {
    this.m_objExcel = objExcel;
    }
    ///
    /// 列標號,Excel最大列數是256
    ///
    private string[] ALists = new string[] {
    "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
    "AA", "AB", "AC", "AD", "AE", "AF", "AG", "AH", "AI", "AJ", "AK", "AL", "AM", "AN", "AO", "AP", "AQ", "AR", "AS", "AT", "AU", "AV", "AW", "AX", "AY", "AZ",
    "BA", "BB", "BC", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BK", "BL", "BM", "BN", "BO", "BP", "BQ", "BR", "BS", "BT", "BU", "BV", "BW", "BX", "BY", "BZ",
    "CA", "CB", "CC", "CD", "CE", "CF", "CG", "CH", "CI", "CJ", "CK", "CL", "CM", "CN", "CO", "CP", "CQ", "CR", "CS", "CT", "CU", "CV", "CW", "CX", "CY", "CZ",
    "DA", "DB", "DC", "DD", "DE", "DF", "DG", "DH", "DI", "DJ", "DK", "DL", "DM", "DN", "DO", "DP", "DQ", "DR", "DS", "DT", "DU", "DV", "DW", "DX", "DY", "DZ",
    "EA", "EB", "EC", "ED", "EE", "EF", "EG", "EH", "EI", "EJ", "EK", "EL", "EM", "EN", "EO", "EP", "EQ", "ER", "ES", "ET", "EU", "EV", "EW", "EX", "EY", "EZ",
    "FA", "FB", "FC", "FD", "FE", "FF", "FG", "FH", "FI", "FJ", "FK", "FL", "FM", "FN", "FO", "FP", "FQ", "FR", "FS", "FT", "FU", "FV", "FW", "FX", "FY", "FZ",
    "GA", "GB", "GC", "GD", "GE", "GF", "GG", "GH", "GI", "GJ", "GK", "GL", "GM", "GN", "GO", "GP", "GQ", "GR", "GS", "GT", "GU", "GV", "GW", "GX", "GY", "GZ",
    "HA", "HB", "HC", "HD", "HE", "HF", "HG", "HH", "HI", "HJ", "HK", "HL", "HM", "HN", "HO", "HP", "HQ", "HR", "HS", "HT", "HU", "HV", "HW", "HX", "HY", "HZ",
    "IA", "IB", "IC", "ID", "IE", "IF", "IG", "IH", "II", "IJ", "IK", "IL", "IM", "IN", "IO", "IP", "IQ", "IR", "IS", "IT", "IU", "IV"
    };
    ///
    /// 獲取描述區域的字符
    ///
    ///
    ///
    ///
    public string GetAix(int x, int y)
    {
    if (x > 256) { return ""; }
    string s = "";
    s = s + ALists[x - 1].ToString();
    s = s + y.ToString();
    return s;
    }
    ///
    /// 給單元格賦值1
    ///
    ///
    行號
    ///
    列號
    ///
    對齊(CENTER、LEFT、RIGHT)
    ///
    值
    public void setValue(int y, int x, string align, string text)
    {
    Microsoft.Office.Interop.Excel.Range range = sheet.get_Range(this.GetAix(x, y), miss);
    range.set_Value(miss, text);
    if (align.ToUpper() == "CENTER")
    {
    range.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
    }
    if (align.ToUpper() == "LEFT")
    {
    range.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignLeft;
    }
    if (align.ToUpper() == "RIGHT")
    {
    range.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignRight;
    }
    }
    ///
    /// 給單元格賦值2
    ///
    ///
    行號
    ///
    列號
    ///
    值
    public void setValue(int y, int x, string text)
    {
    Microsoft.Office.Interop.Excel.Range range = sheet.get_Range(this.GetAix(x, y), miss);
    range.set_Value(miss, text);
    }
    ///
    /// 給單元格賦值3
    ///
    ///
    行號
    ///
    列號
    ///
    值
    ///
    字符格式
    ///
    顏色
    public void setValue(int y, int x, string text, System.Drawing.Font font, int color)
    {
    this.setValue(x, y, text);
    Microsoft.Office.Interop.Excel.Range range = sheet.get_Range(this.GetAix(x, y), miss);
    range.Font.Size = font.Size;
    range.Font.Bold = font.Bold;
    //這裏是int型的顏色
    range.Font.Color = ColorTranslator.ToOle(ColorTranslator.FromWin32(color));
    range.Font.Name = font.Name;
    range.Font.Italic = font.Italic;
    range.Font.Underline = font.Underline;
    }
    ///
    /// 給單元格賦值3
    ///
    ///
    行號
    ///
    列號
    ///
    值
    ///
    字符格式
    ///
    顏色
    public void setValue(int y, int x, string text, System.Drawing.Font font, int color, string align)
    {
    this.setValue(x, y, text);
    Microsoft.Office.Interop.Excel.Range range = sheet.get_Range(this.GetAix(x, y), miss);
    range.Font.Size = font.Size;
    range.Font.Bold = font.Bold;
    //這裏是int型的顏色
    range.Font.Color = ColorTranslator.ToOle(ColorTranslator.FromWin32(color));
    range.Font.Name = font.Name;
    range.Font.Italic = font.Italic;
    range.Font.Underline = font.Underline;
    if (align.ToUpper() == "CENTER")
    {
    range.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
    }
    if (align.ToUpper() == "LEFT")
    {
    range.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignLeft;
    }
    if (align.ToUpper() == "RIGHT")
    {
    range.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignRight;
    }
    }
    ///
    /// 插入新行
    ///
    ///
    模板行號
    public void insertRow(int y)
    {
    Microsoft.Office.Interop.Excel.Range range = sheet.get_Range(GetAix(1, y), GetAix(255, y));
    range.Copy(miss);
    range.Insert(Microsoft.Office.Interop.Excel.XlDirection.xlDown, miss);
    range.get_Range(GetAix(1, y), GetAix(255, y));
    range.Select();
    sheet.Paste(miss, miss);
    }
    ///
    /// 把剪切內容粘貼到當前區域
    ///
    public void paste()
    {
    string s = "a,b,c,d,e,f,g";
    sheet.Paste(sheet.get_Range(this.GetAix(10, 10), miss), s);
    }
    ///
    /// 設置邊框
    ///
    ///
    ///
    ///
    ///
    ///
    public void setBorder(int x1, int y1, int x2, int y2, int Width)
    {
    Microsoft.Office.Interop.Excel.Range range = sheet.get_Range(this.GetAix(x1, y1), this.GetAix(x2, y2));
    range.Borders.Weight = Width;
    }
    public void mergeCell(int x1, int y1, int x2, int y2)
    {
    Microsoft.Office.Interop.Excel.Range range = sheet.get_Range(this.GetAix(x1, y1), this.GetAix(x2, y2));
    range.Merge(true);
    }
    public Microsoft.Office.Interop.Excel.Range getRange(int x1, int y1, int x2, int y2)
    {
    Microsoft.Office.Interop.Excel.Range range = sheet.get_Range(this.GetAix(x1, y1), this.GetAix(x2, y2));
    return range;
    }
    private object miss = Missing.Value;
    //忽略的參數OLENULL
    private Microsoft.Office.Interop.Excel.Application m_objExcel;
    //Excel應用程序實例
    private Microsoft.Office.Interop.Excel.Workbooks m_objBooks;
    //工作表集合
    private Microsoft.Office.Interop.Excel.Workbook m_objBook;
    //當前操作的工作表
    private Microsoft.Office.Interop.Excel.Worksheet sheet;
    //當前操作的表格
    public Microsoft.Office.Interop.Excel.Worksheet CurrentSheet
    {
    get
    {
    return sheet;
    }
    set
    {
    this.sheet = value;
    }
    }
    public Microsoft.Office.Interop.Excel.Workbooks CurrentWorkBooks
    {
    get
    {
    return this.m_objBooks;
    }
    set
    {
    this.m_objBooks = value;
    }
    }
    public Microsoft.Office.Interop.Excel.Workbook CurrentWorkBook
    {
    get
    {
    return this.m_objBook;
    }
    set
    {
    this.m_objBook = value;
    }
    }
    ///
    /// 打開Excel文件
    ///
    ///
    路徑
    public void OpenExcelFile(string filename)
    {
    UserControl(false);
    m_objExcel.Workbooks.Open(filename, miss, miss, miss, miss, miss, miss, miss,
    miss, miss, miss, miss, miss, miss, miss);
    m_objBooks = (Microsoft.Office.Interop.Excel.Workbooks)m_objExcel.Workbooks;
    m_objBook = m_objExcel.ActiveWorkbook;
    sheet = (Microsoft.Office.Interop.Excel.Worksheet)m_objBook.ActiveSheet;
    }
    public void UserControl(bool usercontrol)
    {
    if (m_objExcel == null) { return; }
    m_objExcel.UserControl = usercontrol;
    m_objExcel.DisplayAlerts = usercontrol;
    m_objExcel.Visible = usercontrol;
    }
    public void CreateExceFile()
    {
    UserControl(false);
    m_objBooks = (Microsoft.Office.Interop.Excel.Workbooks)m_objExcel.Workbooks;
    m_objBook = (Microsoft.Office.Interop.Excel.Workbook)(m_objBooks.Add(miss));
    sheet = (Microsoft.Office.Interop.Excel.Worksheet)m_objBook.ActiveSheet;
    }
    public void SaveAs(string FileName)
    {
    m_objBook.SaveAs(FileName, miss, miss, miss, miss,
    miss, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange,
    Microsoft.Office.Interop.Excel.XlSaveConflictResolution.xlLocalSessionChanges,
    miss, miss, miss, miss);
    //m_objBook.Close(false, miss, miss);
    }
    public void ReleaseExcel()
    {
    m_objExcel.Quit();
    System.Runtime.InteropServices.Marshal.ReleaseComObject((object)m_objExcel);
    System.Runtime.InteropServices.Marshal.ReleaseComObject((object)m_objBooks);
    System.Runtime.InteropServices.Marshal.ReleaseComObject((object)m_objBook);
    System.Runtime.InteropServices.Marshal.ReleaseComObject((object)sheet);
    sheet = null;
    m_objBook = null;
    m_objBooks = null;
    m_objExcel = null;
    GC.Collect(0);
    }
    #region KillAllExcel
    public bool KillAllExcel()
    {
    try
    {
    if (m_objExcel != null)
    // isRunning是判斷xlApp是怎麼啓動的flag.
    {
    m_objExcel.Quit();
    System.Runtime.InteropServices.Marshal.ReleaseComObject(m_objExcel);
    //釋放COM組件,其實就是將其引用計數減1
    //System.Diagnostics.Process theProc;
    foreach (System.Diagnostics.Process theProc in System.Diagnostics.Process.GetProcessesByName("EXCEL"))
    {
    //先關閉圖形窗口。如果關閉失敗……有的時候在狀態裏看不到圖形窗口的excel了,
    //但是在進程裏仍然有EXCEL.EXE的進程存在,那麼就需要殺掉它:p
    if (theProc.CloseMainWindow() == false)
    {
    theProc.Kill();
    }
    }
    m_objExcel = null;
    return true;
    }
    }
    catch
    {
    return false;
    }
    return true;
    }
    #endregion
    #region Kill Special Excel Process
    [DllImport("user32.dll", SetLastError = true)]
    static extern int GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);
    //推薦這個方法,找了很久,不容易啊
    public void KillSpecialExcel()
    {
    try
    {
    if (m_objExcel != null)
    {
    int lpdwProcessId;
    GetWindowThreadProcessId(new IntPtr(m_objExcel.Hwnd), out lpdwProcessId);
    System.Diagnostics.Process.GetProcessById(lpdwProcessId).Kill();
    }
    }
    catch (Exception ex)
    {
    Console.WriteLine("Delete Excel Process Error:" + ex.Message);
    }
    }
    #endregion
    }
    }
    最關鍵的就是KillSpecialExcel()這個方法,找到Excel的進程ID,然後殺死這個進程。
    斷斷續續找了很久,終於發現了這個方法。
    看一個例子:
    查看源代碼打印?protected void Button1_Click(object sender, EventArgs e)
    {
    MSExcel mexc = new MSExcel();
    mexc.CreateExceFile();
    mexc.insertRow(1);
    //注意從1開始的
    int col = (256 * 256 * 255) + (256 * 192) + 192;
    //顏色
    mexc.setValue(1, 1, "Demo", new Font("Arial", 18), col,"center");
    //設置單元格內容和樣式
    mexc.mergeCell(1, 1, 4, 1);
    //合併單元格
    for (int i = 2; i <= 101; i++)
    {
    mexc.insertRow(i);
    //插入行
    for (int j = 1; j <= 4; j++)
    //注意從1開始的
    {
    mexc.setValue(i, j, i + "--" + j);
    //設置單元格內容
    }
    }
    mexc.SaveAs(@"d:\demo.xls");
    //保存文件
    mexc.KillSpecialExcel();
    //關閉創建的Excel進程
    }


    其它方面還沒有測試,有興趣的話可以自己試試。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章