使用Excel Interop打开文件后锁定

时间:2015-02-06 19:52:47

标签: excel-interop

我正在打开一个excel文件,刷新它的数据源,并使用c#app将其保存为PDF。我基于像this这样的代码示例。但是,即使在调用最终版本之后,文件仍保持锁定状态。

Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();

// Open the Workbook:
Microsoft.Office.Interop.Excel.Workbook wb = excelApp.Workbooks.Open(
    @"c:\test\test.xlsx",
    Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
    Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
    Type.Missing, Type.Missing, Type.Missing, Type.Missing);

Microsoft.Office.Interop.Excel.Worksheet ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets[1];

wb.RefreshAll();
Thread.Sleep(4000); //surely a better way to do this

//ws.PrintOut(Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
wb.ExportAsFixedFormat(XlFixedFormatType.xlTypePDF, @"c:\test\test.pdf");

// Cleanup:
GC.Collect();
GC.WaitForPendingFinalizers();

Marshal.FinalReleaseComObject(ws);

wb.Close(false, Type.Missing, Type.Missing);
Marshal.FinalReleaseComObject(wb);

excelApp.Quit();
Marshal.FinalReleaseComObject(excelApp);

在流程完成后,哪些其他步骤可以确保它不会被锁定?

1 个答案:

答案 0 :(得分:1)

  1. 我认为你在这里做了一些无序的工作 - 即在关闭你的应用程序或工作簿之前收集。
  2. 我已经达到了清理Excel对象的每个部分的程度 - 工作表,工作簿,应用程序和processID。这可能是一种谨慎,但更好的是确保你正在清理你的记忆IMO。
  3. 我不知道这是你的问题,但我倾向于使用更完整的语句来导出PDF。我会考虑的。

    xlWorkbook.ExportAsFixedFormat(Excel.XlFixedFormatType.xlTypePDF,filepath,Excel.XlFixedFormatQuality.xlQualityStandard,true,false,1,1,true,missing);

  4. 我为自己的工作所做的是创建两个函数来处理杀死鬼进程的工作(可能导致你的锁定)。

    我的代码打包在我创建的类中,为我处理Excel实例,称为singleExcel,因此可以根据需要进行调整,但它应该让你顺利进行。

    public Excel._Worksheet xlWorksheet { get; set; }
    public Excel.Application xlApp { get; set; }
    public Excel.Workbook xlWorkbook { get; set; }
    public Process excelProcess { get; set; }
    
    public static void CloseSheet(singleExcel thisExcel)
    {
        if (thisExcel.excelProcess != null)
        {
            try
            {
                thisExcel.excelProcess.Kill();
                thisExcel.excelProcess.Dispose();
            }
            catch (Exception ex)
            {
                // depending on your needs   
            }
        }
        else
        {
            thisExcel.xlWorkbook.Close(true);
            thisExcel.xlApp.Quit();
        }
        releaseObject(thisExcel.xlWorksheet);
        releaseObject(thisExcel.xlWorkbook);
        releaseObject(thisExcel.xlApp);
        releaseObject(thisExcel.excelProcess);
        releaseObject(thisExcel);
    }
    
    public static void releaseObject(object obj)
    {
        try
        {
            Marshal.ReleaseComObject(obj);
            obj = null;
        }
        catch
        {
            obj = null;
        }
        finally
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }
    }