将数据表导出到 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
我正在尝试将数据表导出到 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