来自HRESULT的COM异常:Excel保存文件中的0x800A03EC

时间:2018-01-15 05:32:42

标签: c# excel excel-interop

这一直困扰着我。我正在尝试将报告导出到程序中的excel函数。每当我导出报告并提示我命名并保存文件时,都会抛出此错误:

COM Exception from HRESULT: 0x800A03EC

我知道很多论坛都会提到这个问题,但这些解决方案对我来说根本不起作用。我尝试重新启动VS,以管理员身份运行VS,更改列行数等。没有运气。问题是,我在程序中有10个不同的功能,其中4-5个允许我成功保存并导出到Excel,但其他功能会抛出此错误。

这是抛出此错误的代码的一部分:

private void ExportExcel(SqlDataReader dr) {
  try {
    DataTable dt = new DataTable();
    dt.Load(dr);
    SaveFileDialog saveFileDialog1 = new SaveFileDialog();
    saveFileDialog1.Filter = "Microsoft Office Excel Workbook (*.xls)|*.xls|All Files (*.*)|*.*";
    saveFileDialog1.FilterIndex = 1;
    saveFileDialog1.RestoreDirectory = true;

    if (saveFileDialog1.ShowDialog() == DialogResult.OK) {
      // Create an Excel object and add workbook...
      Excel.ApplicationClass excel = new Excel.ApplicationClass();
      Excel.Workbook workbook = excel.Application.Workbooks.Add(true); // true for object template???

      // Add column headings...
      int iCol = 0;
      int iVisibleColumnCount = 0;
      foreach (DataColumn c in dt.Columns) {
        iCol++;
        // counting visible columns
        if (c.ColumnMapping != MappingType.Hidden)
          iVisibleColumnCount++;
        else    // hide the columns in excel is the column is hide in datatable
        {
          ((Excel.Range) excel.Cells[1, iCol]).EntireColumn.Hidden = true;
          continue;
        }
          // Set column header text to bold
          ((Excel.Range) excel.Cells[1, iCol]).Font.Bold = true;
        excel.Cells[1, iCol] = c.ColumnName;

        if (c.DataType == typeof(System.String))
          ((Excel.Range) excel.Cells[1, iCol]).EntireColumn.NumberFormat = "@";
        else if (c.DataType == typeof(System.Int16)
            || c.DataType == typeof(System.Int32)
            || c.DataType == typeof(System.Int64))
          ((Excel.Range) excel.Cells[1, iCol]).EntireColumn.NumberFormat = "#,##0";
        else if (c.DataType == typeof(System.TimeSpan))
          ((Excel.Range) excel.Cells[1, iCol]).EntireColumn.NumberFormat = @"[$-409]hh:mm:ss AM/PM;@";
        else if (c.DataType == typeof(System.DateTime))
          ((Excel.Range) excel.Cells[1, iCol]).EntireColumn.NumberFormat = "dd-MMM-yyyy";
        else if (c.DataType == typeof(System.Decimal))
          ((Excel.Range) excel.Cells[1, iCol]).EntireColumn.NumberFormat = @"#,##0.00_);[Red](#,##0.00)";
        else
          ((Excel.Range) excel.Cells[1, iCol]).EntireColumn.NumberFormat = "General";
      }
      // for each row of data...
      int iRow = 0;
      foreach (DataRow r in dt.Rows) {
        iRow++;

        // add each row's cell data...
        iCol = 0;
        foreach (DataColumn c in dt.Columns) {
          iCol++;
          if (c.ColumnMapping != MappingType.Hidden) {
            Exception thrown at this line: excel.Cells[iRow + 1, iCol] = r[c.ColumnName];
          }
        }
      }

      //                  // Global missing reference for objects we are not defining...
      //                  object missing = System.Reflection.Missing.Value;

      // If wanting to Save the workbook...
      workbook.SaveAs(saveFileDialog1.FileName, Excel.XlFileFormat.xlWorkbookNormal, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
      //                  workbook.SaveAs(saveFileDialog1.FileName,
      //                      Excel.XlFileFormat.xlXMLSpreadsheet, missing, missing,
      //                      false, false, Excel.XlSaveAsAccessMode.xlNoChange,
      //                      missing, missing, missing, missing, missing);

      // If wanting to make Excel visible and activate the worksheet...
      //excel.Visible = !bCloseAfterExport;
      Excel.Worksheet xlWorkSheet = (Excel.Worksheet) excel.ActiveSheet;
      ((Excel._Worksheet) xlWorkSheet).Activate();

      workbook.Save();
      //save the workbook

      //if (bCloseAfterExport)
      workbook.Close(false, String.Empty, false);
      //close the workbook

      // End

      // If wanting excel to shutdown...
      //if (bCloseAfterExport)
      ((Excel._Application) excel).Quit();
    }
  }
  catch (Exception ex) {
    MessageBox.Show(ex.ToString());
  }
}

错误讯息:

Picture

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:1)

我认为我的问题是我的某些数据(单元格值)以“ =”开头,这导致分配失败。一次执行几千行时很难看。将传输置于循环中并一次传输10行(也可以在try catch块中传输,以便继续进行)。

答案 1 :(得分:0)

excel.Cells[iRow + 1, iCol]是一个范围。它有一个Range类型。你不能设置这样的值。要设置范围的值,您需要设置其值或公式:

excel.Cells[iRow + 1, iCol].Value = r[c.ColumnName];