使用 Excel Interop 打开后文件被锁定
File Locked after Opening with Excel Interop
我正在打开一个 excel 文件,刷新它的数据源,然后使用 c# 应用程序将其保存为 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);
哪些额外的步骤可以确保它在该过程完成后不被锁定?
- 我认为您在这里做的一些工作没有按顺序进行 - 即,在关闭您的应用程序或工作簿之前进行收集。
- 我已经到了清理 Excel 对象的每个部分的地步 - 工作表、工作簿、应用程序和进程 ID。这可能是非常谨慎的,但最好确保您正在清理内存 IMO。
我不知道这是你的问题,但我倾向于使用更完整的语句来导出 PDF。我会考虑的。
xlWorkbook.ExportAsFixedFormat(Excel.XlFixedFormatType.xlTypePDF, 文件路径, Excel.XlFixedFormatQuality.xlQualityStandard, true, false, 1, 1, true, missing);
我为自己的工作所做的是创建两个函数来处理杀死 ghost 进程的工作(这可能会导致您的锁定)。
我的代码打包在一个 class 中,我创建它来为我处理 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();
}
}
我正在打开一个 excel 文件,刷新它的数据源,然后使用 c# 应用程序将其保存为 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);
哪些额外的步骤可以确保它在该过程完成后不被锁定?
- 我认为您在这里做的一些工作没有按顺序进行 - 即,在关闭您的应用程序或工作簿之前进行收集。
- 我已经到了清理 Excel 对象的每个部分的地步 - 工作表、工作簿、应用程序和进程 ID。这可能是非常谨慎的,但最好确保您正在清理内存 IMO。
我不知道这是你的问题,但我倾向于使用更完整的语句来导出 PDF。我会考虑的。
xlWorkbook.ExportAsFixedFormat(Excel.XlFixedFormatType.xlTypePDF, 文件路径, Excel.XlFixedFormatQuality.xlQualityStandard, true, false, 1, 1, true, missing);
我为自己的工作所做的是创建两个函数来处理杀死 ghost 进程的工作(这可能会导致您的锁定)。
我的代码打包在一个 class 中,我创建它来为我处理 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();
}
}