简体   繁体   English

Excel.Workbook.SaveAs()在单击“否”以在C#中进行文件替换时引发异常

[英]Excel.Workbook.SaveAs() throws exception on clicking 'No' for file replace in C#

My small console tool tries to read an excel file and create new out of that depending on set criteria. 我的小型控制台工具尝试读取excel文件并根据设置的标准从中创建新文件。

Problem: When there is a filename conflict(file already exists with same name), programme should generate the file with an unique name. 问题:当文件名冲突(文件已经存在且具有相同名称)时,程序应生成具有唯一名称的文件。 But now a message comes up with "yes/no/cancel" message box to save the file. 但是现在出现一条消息,显示“是/否/取消”消息框以保存文件。 If user clicks NO then exception thrown. 如果用户单击“否”,则会引发异常。 The message is as follows: 消息如下:

A file named 'D:\sample.xls' already exists in this location. Do you want to replace it? 

The exception: 例外:

A first chance exception of type 'System.Runtime.InteropServices.COMException' occurred in ExcelSplitter.exe

Additional information: Exception from HRESULT: 0x800A03EC

The following line thorws the exception 以下行表示异常

xlWorkBook.SaveAs(fileName, Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue); 

The code is as follows: 代码如下:

    private bool WriteToExcel(String fileName, List<RowEntity> headerRowObj, List<RowEntity> dataRowObj)
    {
        Excel.Application xlApp;
        Excel.Workbook xlWorkBook = null;
        Excel.Worksheet xlWorkSheet;
        object misValue = System.Reflection.Missing.Value;

        xlApp = new Excel.ApplicationClass();

        xlWorkBook = xlApp.Workbooks.Add(misValue);

        xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);

        int headerRowTotal = 0;

        for (int i = 0; i < headerRowObj.Count; i++)
        {
            for (int j = 0; j < headerRowObj[i].ColumnValues.Count; j++)
            {
                xlWorkSheet.Cells[i + 1, j + 1] = headerRowObj[i].ColumnValues[j].ToString();
            }
            headerRowTotal++;
        }

        for (int i = 0; i < dataRowObj.Count; i++)
        {
            for (int j = 0; j < dataRowObj[i].ColumnValues.Count; j++)
            {
                xlWorkSheet.Cells[headerRowTotal + i + 1, j + 1] = dataRowObj[i].ColumnValues[j].ToString();
            }
        }

        if (IsExcelFileOpen(xlWorkBook))
        {
            errorList.Add(Error.GetError(-7));
            return false;
        }
        else
        {
            xlWorkBook.SaveAs(fileName, Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);

        }

        xlWorkBook.Close(true, misValue, misValue);
        xlApp.Quit();

        ReleaseObject(xlWorkSheet);
        ReleaseObject(xlWorkBook);
        ReleaseObject(xlApp);

        return true;
    }

The above method is called in the following method: 在以下方法中调用上述方法:

 private int SeparateExcleFiles(int headerLines, int groupOnColumn, string outputPath, string inputFile, FileEntity fileObj, RowEntity rowObj)
    {
        List<RowEntity> headerRowObj = fileObj.RowValues.GetRange(0, headerLines);
        if (rowObj.ColumnValues.Count < groupOnColumn)
        {
            errorList.Add(Error.GetError(-6));
            return -6;
        }
        else
        {
            var dataRows = fileObj.RowValues.GetRange(headerLines, fileObj.RowValues.Count - (headerLines)).GroupBy(re => re.ColumnValues[groupOnColumn - 1]).ToList();

            for (int i = 0; i < dataRows.Count; i++)
            {
                var fileName = String.Format("{0}-{1}{2}", Path.GetFileNameWithoutExtension(inputFile), dataRows[i].Key.ToString(), Path.GetExtension(inputFile));
                var filePath = Path.Combine(outputPath, fileName);

                if (File.Exists(filePath))
                {
                    fileName = GetUniqueFilename(fileName);
                }

                if (WriteToExcel(filePath, headerRowObj, dataRows[i].ToList() as List<RowEntity>))
                {
                    System.Console.WriteLine("Wrote {0}", fileName);
                }
            }
            return 0;
        }
    }


 private bool IsExcelFileOpen(Workbook wBook)
    {
        Excel.Application exApp;
        exApp = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
        try
        {
            exApp.Workbooks.get_Item(wBook);
            return true;
        }
        catch (Exception)
        {
            return false;
        }

    }    

Where exactly am I doing it wrong? 我到底在哪里做错了?

Could you try this on the saveas part. 您可以在saveas部分尝试一下吗。

try
{
    xlWorkBook.SaveAs(fileName, Excel.XlFileFormat.xlWorkbookNormal, misValue,     misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
}
catch(Exception e)
{
//BLANK (do nothing)
}

This will allow you to handle the exception, but if you don't want to do anything and just not overwrite just leave the handling process blank. 这将允许您处理异常,但是如果您不想执行任何操作并且只是不覆盖,则将处理过程留空。

Having the exception handler will let the system think that you acknowledged the event and will let the program continue. 拥有异常处理程序将使系统认为您已确认该事件,并使程序继续运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM