关闭Excel工作簿

问题描述 投票:4回答:5

我有一些代码可以打开xls工作簿;

Excel.Workbooks workBooks;
workBooks = excelApp.Workbooks;
workbook = workBooks.Open(sourceFilePath + sourceFileName + ".xls");

然后我得到了工作表;

worksheets = workbook.Worksheets;
worksheet = worksheets.get_Item("Standard");

然后我将文件另存为csv;

worksheet.SaveAs(sourceFilePath + sourceFileName + ".csv", Excel.XlFileFormat.xlCSVWindows, Type.Missing, Type.Missing, false, false, Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing);

然后我尝试关闭工作簿;

Marshal.FinalReleaseComObject(worksheet);
Marshal.FinalReleaseComObject(worksheets);
workbook.Close();
Marshal.FinalReleaseComObject(workbook);

但是,每次我到达line workbook.Close()时,系统都会停止。

如果我不执行另存为,那么工作簿将关闭。

我如何关闭工作簿?

编辑

查看任务管理器会向我显示Excel.exe仍在运行。关闭它会在我的代码中产生错误。

编辑2

我已经看到了所引用的SO帖子,它没有解决问题。

c# excel-interop
5个回答
8
投票

这里是解决方法

第一:using EXCEL = Microsoft.Office.Interop.Excel;

然后,path是您的excel所在的位置。

        EXCEL.Application excel = new EXCEL.Application();
        try
        {
            EXCEL.Workbook book = excel.Application.Workbooks.Open(path);
            EXCEL.Worksheet sheet = book.Worksheets[1];
            // yout operation

        }
        catch (Exception ex) { MessageBox.Show("readExcel:" + ex.Message); }
        finally
        {
            KillExcel(excel);
            System.Threading.Thread.Sleep(100);
        }



    [DllImport("User32.dll")]
    public static extern int GetWindowThreadProcessId(IntPtr hWnd, out int ProcessId);
    private static void KillExcel(EXCEL.Application theApp)
    {
        int id = 0;
        IntPtr intptr = new IntPtr(theApp.Hwnd);
        System.Diagnostics.Process p = null;
        try
        {
            GetWindowThreadProcessId(intptr, out id);
            p = System.Diagnostics.Process.GetProcessById(id);
            if (p != null)
            {
                p.Kill();
                p.Dispose();
            }
        }
        catch (Exception ex)
        {
            System.Windows.Forms.MessageBox.Show("KillExcel:" + ex.Message);
        }
    }

5
投票

为什么不合并2。这将解决保存完成之前关闭的任何问题。Close方法中有一个选项可以保存文件。

workbook.Close(true, fileName, Missing.Value);

另外,如果文件保存正确,而您的问题纯粹是因为excel.exe进程仍在运行,那可能是因为您没有关闭并释放所需的一切。我以前有过这个,并制定了一个更完整的关机程序。我关闭Excel文件的代码是:

        book.Close(true, fileName, Missing.Value); //close and save individual book
        allBooks.Close(); //close all books
        excel.Quit();
        Marshal.ReleaseComObject(allCells); //any used range objects
        Marshal.ReleaseComObject(sheet);
        Marshal.ReleaseComObject(sheets);
        Marshal.ReleaseComObject(book);
        Marshal.ReleaseComObject(allBooks);
        Marshal.ReleaseComObject(excel);

这对我来说是100%的时间。


0
投票

您是否考虑过以下事实:尝试关闭文件时系统可能仍在保存文件中?我只是说,要确保在关闭之前添加一个延迟(例如,在C#中为Thread.Sleep(1000)),看看这是否是问题所在。


0
投票

此问题不断弹出,请参阅:

How to properly clean up Excel interop objects in C#

您需要在您使用的每个excel对象上调用System.Runtime.InteropServices.Marshal.ReleaseComObject(),即使是不可见的对象,例如:

var worksheet = excelApp.Worksheets.Open()

这里有两个对象:1.用Open()打开明显的“工作表”2.“不可见的”集合“工作表”。

它们都需要发布(因此最好保留工作表的参考):

var wkCol = excelApp.Worksheets;var worksheet = wkCol.Open();

0
投票
    EXCEL.Application excel = new EXCEL.Application();
    try
    {
        EXCEL.Workbook book = excel.Application.Workbooks.Open(path);
        EXCEL.Worksheet sheet = book.Worksheets[1];
        // yout operation

    }
    catch (Exception ex) { MessageBox.Show("readExcel:" + ex.Message); }
    finally
    {
        KillExcel(excel);
        System.Threading.Thread.Sleep(100);
    }


[DllImport("User32.dll")]
public static extern int GetWindowThreadProcessId(IntPtr hWnd, out int ProcessId);
private static void KillExcel(EXCEL.Application theApp)
{
    int id = 0;
    IntPtr intptr = new IntPtr(theApp.Hwnd);
    System.Diagnostics.Process p = null;
    try
    {
        GetWindowThreadProcessId(intptr, out id);
        p = System.Diagnostics.Process.GetProcessById(id);
        if (p != null)
        {
            p.Kill();
            p.Dispose();
        }
    }
    catch (Exception ex)
    {
        System.Windows.Forms.MessageBox.Show("KillExcel:" + ex.Message);
    }
}

谢谢!!!

© www.soinside.com 2019 - 2024. All rights reserved.