问:Interop.Excel 打开两个文件实例

Q. Interop.Excel opens two instances of File

我有一个 C# 程序可以从 .txt 文件创建 Excel 文件报告。

它运行完美,但有时(经常)当我打开一个电子表格时 Excel 打开 2 个电子表格:

1 个用于我保存的文件。 1 有一些名为 "Plan1" 的垃圾数据未保存。

我不确定 excel 在哪里可以找到 Plan1 的垃圾数据。

这是保存电子表格的代码:

protected string ExportOC(Application app, OcFile oc, bool configurator) 
{
    string ocFinalName;
    if (configurator)
        ocFinalName = string.Format("{0}{1}", ocFinalName = oc.Name, Models.Constants.CHECK_CONFIGURATOR);
    else if (oc.Error)
        ocFinalName = string.Format("{0}{1}", ocFinalName = oc.Name, Models.Constants.CHECK_STRUCT_ERROR);
    else
        ocFinalName = string.Format("{0}{1}", ocFinalName = oc.Name, Models.Constants.CHECK_OK);
    try 
    {
        string savePath = string.Format("{0}{1}", Importer.GetPathWithType(ConfigurationManager.AppSettings[Modelos.Constants.SAVE_ROOT_PATH].ToString(), oc.Type), ocFinalName);
        app.DisplayAlerts = false;
        app.ActiveWorkbook.WebOptions.Encoding = Microsoft.Office.Core.MsoEncoding.msoEncodingUTF8;
        app.ActiveWorkbook.SaveAs(savePath, XlFileFormat.xlOpenXMLWorkbook, Missing.Value,Missing.Value, false, false, XlSaveAsAccessMode.xlNoChange,XlSaveConflictResolution.xlUserResolution,true,Missing.Value, Missing.Value, Missing.Value);
        return string.Format("{0}{1}", ocFinalName, Models.Constants.EXTENSION_EXCEL_X);
    } 
    catch (Exception) 
    {
        return InvalidOC(oc, Models.Constants.CHECK_NO_SAVED);
    } finally 
    {
        ClearCOM(app);
    }
}

下面是我清理 COM 对象的方法:

protected void ClearCOM(Application app) 
{
    try 
    {
        app.DisplayAlerts = false;
        app.ActiveWorkbook.Close(0);
        app.Quit();
        Marshal.ReleaseComObject(app);
    }
    catch 
    {
        return;
    }
}

我不确定我是否应该把打开电子表格的代码放在这里,因为即使我在程序外打开文件时也会出现这个问题(据我所知,比在程序内打开文件时更频繁)。

感谢帮助

编辑

工作表名称必须包含特殊字符,例如:5198416384684_003 这是我创建 COM 对象的方法。

public string ProcessOC(OcFile oc) {
    Application app = new Application();
    Workbook workbook = app.Workbooks.Add(1);
    Worksheet plan = (Worksheet)workbook.Sheets[1];
    plan.Name = oc.Name; 
    bool rightSize = false;
    bool haveMoreDocuments = false;
    int indexLine = 1, indexColumn = 1;
    int lin = 1, col = 0;
    string columnLetter = String.Empty;
    string ajusteTextoNum = String.Empty;

    try {
        List<string> validLines = GetValidContent(oc.Lines);

        foreach (string line in validLines) {
            //get the txt lines and put all of them im the worksheet
        }

        // format the worksheet 

        return ExportOC(app, oc, false);

    } catch (WrongPrinterException) {
        return InvalidOC(oc, Modelos.Constants.CHECK_NO_PRINTER); //doesn't save
    } catch (MissingFileException) {
        return InvalidOC(oc, Modelos.Constants.CHECK_MISS_SOURCE_FILE); //doesn't save
    } catch (Exception) {
        return InvalidOC(oc, Modelos.Constants.CHECK_NO_SAVED); //doesn't save
    } finally {
        ClearCOM(app);
    }
}

以及问题本身。

抱歉省略了一些价值观,这是公司政治。 这一次,我在程序外打开,那些数据,并不是真正的垃圾,它是另一个格式不同的报告,操作员可能之前关闭了。

可能 Excel 正在尝试恢复之前的会话。

我将尝试清理其他 COM 对象并也使用 Marshal.ReleaseComObject。

编辑 2

我尝试清除 COM 对象,但仍然一次打开 2 个电子表格。

这里是清除 COM 的代码

protected void ClearCOM(Application app, Workbook workbook, Worksheet worksheet) {
    try {
        app.DisplayAlerts = false;
        app.ActiveWorkbook.Close(0);
        Marshal.ReleaseComObject(workbook);
        Marshal.ReleaseComObject(worksheet);
        app.Quit();
        Marshal.ReleaseComObject(app);
    } catch {
        return;
    }
}

编辑 3

我已经清理了 XLSTART 文件夹,还是没有

对于仍然有此问题的任何人。我通过使用 Workbooks.Add 方法创建一个 Workbook 而没有给它任何参数来解决它。 所以在 OPs 问题中,改变这个:

Application app = new Application();
Workbook workbook = app.Workbooks.Add(1);

为此:

Application app = new Application();
Workbook workbook = app.Workbooks.Add(); // No parameters

Add 方法有一个可选的 Template 参数,可以是 XlWBATemplate 类型。 OP 使用 1 作为此参数的值,在这种情况下这不是有效值。

这是文档中关于忽略参数的内容:

If this argument is omitted, Microsoft Excel creates a new workbook with a number of blank sheets (the number of sheets is set by the SheetsInNewWorkbook property).