关闭Excel工作簿

时间:2013-07-03 05:12:33

标签: c# excel-interop

我有一些打开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()时,系统都会停止。

如果我不执行SaveAs,那么工作簿就会关闭。

如何关闭工作簿?

修改

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

编辑2

我已经看过引用的SO帖子,但它没有解决问题。

5 个答案:

答案 0 :(得分:7)

这是解决方案

第一: 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);
        }
    }

答案 1 :(得分: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%的时间。

答案 2 :(得分:0)

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

答案 3 :(得分: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();

答案 4 :(得分:0)

EXCEL.Application excel = new EXCEL.Application();         尝试         {             EXCEL.Workbook book = excel.Application.Workbooks.Open(path);             EXCEL.Worksheet sheet = book.Worksheets [1];             //你操作

    }
    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);
    }
}

谢谢!!!!

相关问题