6

我有一些代码可以打开一个 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);

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

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

如何关闭工作簿?

编辑

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

编辑 2

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

4

5 回答 5

9

这是解决方案

第一的: 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);
        }
    }
于 2013-07-03T05:38:27.000 回答
6

为什么不结合 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% 的时间都有效。

于 2013-07-03T05:46:48.377 回答
0

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

于 2013-07-03T05:22:10.737 回答
0

这个问题不断出现,请参阅:

如何在 C# 中正确清理 Excel 互操作对象

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

var worksheet = excelApp.Worksheets.Open()

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

它们都需要发布(因此您最好保留 Worksheets 的参考):

var wkCol = excelApp.Worksheets;
var 工作表 = wkCol.Open();
于 2013-07-05T00:39:05.587 回答
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);
    }
}

谢谢!!!!

于 2014-01-27T09:12:18.320 回答