【问题标题】:How to fix 0x800A03EC error when exporting a Datatable to Excel将数据表导出到 Excel 时如何修复 0x800A03EC 错误
【发布时间】:2021-11-17 02:16:09
【问题描述】:

我正在尝试将数据表导出到 Excel 并在运行 wb.SaveAs(path) 时收到以下异常:

Exception from HRESULT: 0x800A03EC

最初我在设置工作表范围时遇到此错误。我通过使其非零索引来解决此问题。但是,数据表数组仍然是零索引的。

很遗憾,没有提供有关错误的其他详细信息。

代码:

        Dim app As New Excel.Application
        Dim wb As Excel.Workbook = app.Workbooks.Add()
        Dim ws As Excel.Worksheet
        Dim strFN As String = "MyFileName.xlsx"   
        Dim dt As New DataTable

        Using da As New DataAdapter(dif)
            da.SetSelectCommand(SQL)
            da.Fill(dt)
        End Using

        ws = wb.Sheets.Add(After:=wb.Sheets(wb.Sheets.Count))
        DataTableToExcel(dt, ws, "TableName")

        wb.SaveAs(path)
        wb.Close()

Private Sub DataTableToExcel(dt As DataTable, ws As Excel.Worksheet, TabName As String)
    Dim arr(dt.Rows.Count, dt.Columns.Count) As Object
    Dim r As Int32, c As Int32

    For r = 0 To dt.Rows.Count - 1
        For c = 0 To dt.Columns.Count - 1
            arr(r, c) = dt.Rows(r).Item(c)
        Next
    Next

    ws.Name = TabName   
    c = 0

    For Each column As DataColumn In dt.Columns
        If column.ColumnName.Length > 4 Then
            If column.ColumnName.Substring(column.ColumnName.Length - 4, 4) = "_ID" Then
                ws.Cells(1, c + 1) = column.ColumnName.Replace("_", " ").Substring(0, column.ColumnName.Length - 4)
            Else
                ws.Cells(1, c + 1) = column.ColumnName.Replace("_", " ")
            End If
        Else
            ws.Cells(1, c + 1) = column.ColumnName.Replace("_", " ")
        End If

        c += 1
    Next

    ws.Range(ws.Cells(2, 1), ws.Cells(dt.Rows.Count, dt.Columns.Count))(1).Value = arr
End Sub

更新:

我已经设法通过将 SaveAs() 更改为 SaveCopyAs() 来阻止错误的发生。

文件现在导出,但是当我打开它时,只有列名,只有第一列/行的第一个值。

【问题讨论】:

  • 请使用try/catch 并捕获完整的异常。另外,尝试使用此代码导出更少的数据;可能是数据表的内容有问题……你能分享一下数据表的结构和一些示例数据吗?
  • 您的网站是以 x32 还是 x64 位运行的?该错误消息看起来像不匹配位大小。如果您的网站和项目以 x64 位运行,那么您必须安装 x64 位版本的 Excel 才能正常工作。您也许可以进行测试以将您的项目设置为 x86 并尝试一下。但这可能会成为一个问题,因为大多数 Web 服务器现在都以 x64 位运行。但是,尝试将您的项目从“任何 cpu”设置为以 x86 运行的项目。或者您可以/可以尝试安装 x64 位版本的 Excel
  • @MarcoAurelioFernandezReyes,该函数已经在 try/catch 中,这是完整的错误消息。不幸的是,我无法共享数据,因为这是我无权共享的数据。我曾尝试导出多个不同的表,有时会过滤到只有一两条记录。我每次都会遇到同样的错误。
  • @AlbertD.Kallal,网站以 x64 运行,excel 版本也是 x64。我尝试将网站作为 x86 运行并得到相同的错误。
  • 除了使用 Excel 和互操作之外,您还可以使用生成真实 Excel 文件而不使用 Excel 的众多库之一,例如 Epplus、NPOI 或 ClosedXML。例如,使用 Epplus,您可以编写 ws.Cells.LoadFromDataTable(table)LoadFromCollection(someList)LoadFromDataReader() 来填充 DataTable、IEnumerable<T>IDbDataReader 中的工作表

标签: asp.net excel vb.net export-to-excel excel-interop


【解决方案1】:

启动 Excel 只是为了将数据导出到 Excel 文件是多余的。对于网站来说,这是完全不切实际的,原因如下:

  • 站点每个用户都需要一个许可证。那可是一大笔钱。
  • 让 Excel 保持打开状态太容易了,慢慢消耗服务器的 RAM 和 CPU。
  • 就是太慢了

xlsx 是一个包含定义明确的 XML 文件的 ZIP 包,因此可以直接创建它们,使用 Open XML SDK 或使这更容易的许多开源库之一,如 Epplus、NPOI 或 ClosedXML .

例如,Epplus 允许通过一次调用从 DataTable、IEnumerable 或 IDbDataReader 填充 Excel 工作表:

Dim dt As DataTable = ...

Dim fi New FileInfo(SomePath)
Using p As New ExcelPackage(fi)
    Dim ws = p.Workbook.Worksheets.Add(sheetName)
    ws.Cells("A1").LoadFromDataTable(dt, PrintHeaders:=True)
    p.Save()
End Using

您也可以使用LoadFromDataReader,避免将所有数据加载到内存中:

Using cmd As New SqlCommand(sql,connection)
    connection.Open()
    Using reader As SqlDataReader = cmd.ExecuteReader()
        Dim fi New FileInfo(SomePath)
        Using p As New ExcelPackage(fi)
            Dim ws = p.Workbook.Worksheets.Add(sheetName)
            ws.Cells("A1").LoadFromDataReader(reader, PrintHeaders:=True)
            p.Save()
        End Using
    End Using
End Using

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-01
    • 2018-09-12
    • 1970-01-01
    • 1970-01-01
    • 2012-09-14
    • 2012-06-14
    • 1970-01-01
    相关资源
    最近更新 更多