【问题标题】:I'm having trouble transferring datagridview to Excel我在将 datagridview 传输到 Excel 时遇到问题
【发布时间】:2020-03-12 23:23:53
【问题描述】:

我在下面的 datagridview 中收到错误的原因是什么?

System.InvalidCastException:“Microsoft.Office.Interop.Excel.ApplicationClass”类型的 COM 对象无法分配给接口类型“Microsoft.Office.Interop.Excel._Application”。此操作失败,因为 IID 为“{000208D5-0000-0000-C000-000000000046}”的接口的 COM 组件中的 QueryInterface 调用失败并出现以下错误:加载类型库/DLL 时出错。 (返回 HRESULT 异常:0x80029C4A (TYPE_E_CANTLOADLIBRARY))。 '

我写的代码是:

saveFileDialog.InitialDirectory = "C:";
saveFileDialog.Title = "Save as Excel File";
saveFileDialog.FileName = "Data";
saveFileDialog.Filter = "Excel Files(2003)|*.xls|Excel Files(2007)|*.xlsx";

if (saveFileDialog.ShowDialog() != DialogResult.Cancel)
{
    Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
    excelApp.Application.Workbooks.Add(Type.Missing);

    excelApp.Columns.ColumnWidth = 20;

    for (int i = 1; i < dgwReport.Columns.Count + 1; i++)
    {
        excelApp.Cells[1, i] = dgwReport.Columns[i - 1].HeaderText;
    }

    for (int i = 0; i < dgwReport.Rows.Count; i++)
    {
        for (int j = 0; j < dgwReport.Columns.Count; j++)
        {
            excelApp.Cells[i + 2, j + 1] = dgwReport.Rows[i].Cells[j].Value;
        }
    }

    excelApp.ActiveWorkbook.SaveCopyAs(saveFileDialog.FileName.ToString());
    excelApp.ActiveWorkbook.Saved = true;
    excelApp.Quit();
}

【问题讨论】:

  • 哪一行抛出异常?你有安装 Excel 吗?
  • 是的,excel installed.speak错误接收行错误接收行;excelApp.Application.Workbooks.Add(Type.Missing);
  • 我无法修复错误
  • 我不是 Excel 互操作方面的专家,但将 Type.Missing 传递给 Workbooks.Add() 看起来行不通。
  • 是的,这段代码已经在其他应用程序中使用过,但应该可以正常工作。我不明白问题出在哪里。 :(

标签: c# winforms


【解决方案1】:

使用发布的代码,我没有收到您描述的错误......

excelApp.Application.Workbooks.Add(Type.Missing);

这在创建新工作簿时似乎是正确的。但是,在将数据写入工作簿时,它似乎存在问题。问题是代码正在将数据写入excelApp,这是不正确的。 excelApp 可以打开多个工作簿,每个工作簿可以有多个“工作表”。您需要指定要写入的“位置”(哪个工作簿中的哪个工作表)。

由于您正在创建一个新工作簿,您需要“添加”一个新工作表并写入该工作表而不是 excelApp.

我测试了下面的代码,它将数据正确写入新工作簿中的新工作表。

saveFileDialog.InitialDirectory = "C:";
saveFileDialog.Title = "Save as Excel File";
saveFileDialog.FileName = "Data";
saveFileDialog.Filter = "Excel Files(2003)|*.xls|Excel Files(2007)|*.xlsx";

Microsoft.Office.Interop.Excel.Application excelApp = null;
Microsoft.Office.Interop.Excel.Workbook workbook = null;
Microsoft.Office.Interop.Excel.Worksheet worksheet = null;

try {
   if (saveFileDialog.ShowDialog() != DialogResult.Cancel) {
    excelApp = new Microsoft.Office.Interop.Excel.Application();
    workbook = excelApp.Application.Workbooks.Add(Type.Missing);
    worksheet = workbook.ActiveSheet;
    excelApp.Columns.ColumnWidth = 20;
    for (int i = 1; i < dgwReport.Columns.Count + 1; i++) {
      worksheet.Cells[1, i] = dgwReport.Columns[i - 1].HeaderText;
    }
    for (int i = 0; i < dgwReport.Rows.Count; i++) {
      for (int j = 0; j < dgwReport.Columns.Count; j++) {
        worksheet.Cells[i + 2, j + 1] = dgwReport.Rows[i].Cells[j].Value;
      }
    }
    excelApp.ActiveWorkbook.SaveCopyAs(saveFileDialog.FileName.ToString());
    excelApp.ActiveWorkbook.Saved = true;
    workbook.Close();
    excelApp.Quit();
  }
}
catch (Exception ex) {
  MessageBox.Show("Excel write error: " + ex.Message);
}
finally {
  // release the excel objects to prevent leaking the unused resource
  if (worksheet != null)
    Marshal.ReleaseComObject(worksheet);
  if (workbook != null)
    Marshal.ReleaseComObject(workbook);
  if (excelApp != null)
    Marshal.ReleaseComObject(excelApp);
}

【讨论】:

  • 非常感谢。我测试了代码。但是我又遇到了同样的错误。 Microsoft.Excel.Interop.Excel 也安装在引用中。我不明白问题是什么。 :(
  • 在这里伸手可及,但是,根据您的评论... “此代码已在其他应用程序中使用过” ...让我想知道 Excel 库是否(在代码中)匹配目标机器。例如,如果您从另一台使用“不同”版本的 Excel 库的机器获取代码,则可能会导致此错误。我认为此时“任何”互操作命令都会失败,但是,我确实知道,如果您将使用 MS Excel 14.0 对象库的代码并在使用 MS Excel 12.0 对象库的机器上运行它,那么您可能存在一些兼容性问题。
  • 幸运的是,您应该能够简单地“转储”当前版本并重新添加针对本地计算机的 Excel 引用。 IE。 ... 右键单击​​项目“References”然后删除 Excel Lib,然后重新添加它。这至少可以确保代码库引用与该机器上使用的相同。
  • 如果这不起作用,那么还有另一种可能性,如果当前机器在某个更早的时间拥有比当前版本“更新”的 Excel 版本,那么,我的理解是注册表项可能从以前的版本挥之不去,需要删除该条目。检查这个 SO 答案…unable to cast COM object of type 'microsoft.Office.Interop.Excel.ApplicationClass' to 'microsoft.Office.Interop.Excel.Application'"
  • 关于使用互操作对象的另一点。在当前代码中,您会注意到,即使我们正在关闭工作簿并退出 excelApp...,“com”对象仍将保留。您可以通过运行代码完成并打开任务管理器来查看这一点。您会注意到有一个后台“Excel”应用程序仍在运行。重点是,重要的是要“释放”代码创建的那些挥之不去的“com”对象,以避免泄漏资源。我将此代码添加到我的答案中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-25
  • 1970-01-01
  • 1970-01-01
  • 2020-11-19
  • 2012-08-29
相关资源
最近更新 更多