将数据表导出到 Excel 时如何修复 0x800A03EC 错误

How to fix 0x800A03EC error when exporting a Datatable to Excel

我正在尝试将数据表导出到 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() 来阻止错误的发生。

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

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

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

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

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

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