查看完整版本: 使用C# 寫EXCEL 匯出,如何在不使用最高權限下,關閉excel.exe *32
頁: [1]

solan 發表於 2020-10-30 10:50 PM

使用C# 寫EXCEL 匯出,如何在不使用最高權限下,關閉excel.exe *32

本帖最後由 solan 於 2020-10-30 10:54 PM 編輯

  以下是匯出的原始碼                      ---------------------------------------------------------------------------------------------------------
            Microsoft.Office.Interop.Excel.Application objExcel = null;
            Microsoft.Office.Interop.Excel.Workbook objWorkbook = null;
            Microsoft.Office.Interop.Excel.Worksheet objsheet = null;
            try
            {            
                string fileNameString = "D:\\TEST\\" + FileName;
                if (fileNameString.Trim() == " ")
                { return; }
                int rowscount = dataGridView1.Rows.Count;
                int colscount = dataGridView1.Columns.Count;
                if (rowscount <= 0)
                {
                    MessageBox.Show("");
                    return;
                }
                if (colscount <= 0)
                {
                    MessageBox.Show("");
                    return;
                }
                if (rowscount > 65536)
                {
                    MessageBox.Show("");
                    return;
                }
                if (colscount > 255)
                {
                    MessageBox.Show("");
                    return;
                }

                try
                {
                    objExcel = new Microsoft.Office.Interop.Excel.Application();
                    objWorkbook = objExcel.Workbooks.Add(true);
                    objsheet = (Microsoft.Office.Interop.Excel.Worksheet)objWorkbook.ActiveSheet;
                    objExcel.Visible = false;
                    int displayColumnsCount = 1;
                    int TotelColumnsCount = 0;
                    for (int i = 0; i <= dataGridView1.Columns.Count - 1; i++)
                    {
                        if (dataGridView1.Columns.Visible == true)
                        {
                            objExcel.Cells = dataGridView1.Columns.HeaderText.Trim();
                            displayColumnsCount++;
                            TotelColumnsCount++;
                        }
                    }
                    for (int row = 0; row <= dataGridView1.Rows.Count - 1; row++)
                    {
                        displayColumnsCount = 1;
                        for (int col = 0; col < TotelColumnsCount; col++)
                        {
                            if (dataGridView1.Columns.Visible == true)
                            {
                                try
                                {
                                    if (dataGridView1.Rows.Cells.Value != null)
                                    {
                                        objExcel.Cells = dataGridView1.Rows.Cells.Value;
                                    }
                                    else
                                    {
                                        objExcel.Cells = "";
                                    }
                                    displayColumnsCount++;
                                }
                                catch (Exception ex)
                                {
                                    MessageBox.Show(ex.Message);
                                }
                            }
                        }
                    }
                    objWorkbook.SaveAs(fileNameString, true, null, null, null,
                            null, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlShared, true, true, true,
                            true, true);
                }
                catch (Exception error)
                {
                    MessageBox.Show(error.Message);
                    return;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
           finally
            {
                if (objsheet != null)
                {
                    Marshal.FinalReleaseComObject(objsheet);
                }
                if (objWorkbook != null)
                {
                    objWorkbook.Close(false);
                    objExcel.Quit();
                    Marshal.FinalReleaseComObject(objWorkbook);
                }
                if (objExcel != null)
                {
                    objExcel.DisplayAlerts = false;
                    objExcel.Workbooks.Close();
                    objExcel.Quit();
                    Marshal.FinalReleaseComObject(objExcel);
                }
             }

目前遇到的問題是無法將Excel.exe * 32 的執行檔完全關閉
想請問如何不在最高權限下,將所有的Excel的Unmanaged釋放乾淨?



...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div><div></div>

solan 發表於 2020-11-26 12:25 AM

最後自己的問題自己解...
如果使用這種方式使用者每匯出一個Excel檔案,伺服器端就會啟動一個Excel程序。這回引起兩個問題,一是耗費伺服器資源,二是當程序數達到上限時,會引發異常,呼叫COM失敗。這個時候要想辦法結束Excel程序。我採用了殺程序的方式,類似下面的做法:

private void DoExcel()
{
Microsoft.Office.Interop.Excel.Application application = new Microsoft.Office.Interop.Excel.Application();
//這裡釋放所有引用的資源
application.Quit();
KillExcel(application);
}


public static extern int GetWindowThreadProcessId(IntPtr hwnd,out int ID);
public static void KillExcel(Microsoft.Office.Interop.Excel.Application excel)
{
IntPtr t = new IntPtr(excel.Hwnd); //得到這個控制代碼,具體作用是得到這塊記憶體入口

int k = 0;
GetWindowThreadProcessId(t, out k); //得到本程序唯一標誌k
System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(k); //得到對程序k的引用
p.Kill(); //關閉程序k
}...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

hq5662 發表於 2023-2-4 01:18 PM

可使用NPOI元件,匯出 excel 或 word
本機電腦可不用安裝office 也可執行
頁: [1]