Как исправить ошибку 0x800A03EC при экспорте данных в Excel

#asp.net #excel #vb.net #export-to-excel #excel-interop

Вопрос:

Я пытаюсь экспортировать данные в Excel и получаю следующее исключение при запуске wb.SaveAs(путь):

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().

Теперь файл экспортируется, но когда я его открываю, там есть только имена столбцов и только первое значение первого столбца/строки.

Комментарии:

1. Пожалуйста, используйте try/catch и зафиксируйте полное исключение. Кроме того, попробуйте экспортировать меньше данных с помощью этого кода; возможно, произошла ошибка с содержимым таблицы данных…вы можете поделиться структурой таблицы данных и некоторыми образцами данных?

2. Ваш веб-сайт работает как x32 или 64-разрядный? Это сообщение об ошибке выглядит как пропущенный размер бита. Если ваш веб-сайт и проект работают как 64-разрядные, то для этого вам необходимо установить 64-разрядную версию Excel. возможно, вы сможете для тестирования установить свой проект на x86 и попробовать это. Но это может стать проблемой в будущем, так как большинство веб-серверов теперь работают как 64-разрядные. Но попробуйте настроить свой проект с «любого процессора» на проект, работающий под управлением x86. Или вы можете/могли бы попробовать установить 64-разрядную версию Excel

3. @MarcoAurelioFernandezReyes, функция уже находится в состоянии try/catch, то есть полное сообщение об ошибке. К сожалению, я не могу поделиться этими данными, поскольку это данные, которыми я не вправе делиться. Я пробовал экспортировать несколько разных таблиц, иногда отфильтрованных только до одной или двух записей. Я каждый раз получаю одну и ту же ошибку.

4. @AlbertD.Kallal, веб-сайт работает как x64, и версия excel также x64. Я пытался запустить веб-сайт как x86 и получил ту же ошибку.

5. Вместо использования Excel и взаимодействия вы можете использовать одну из многих библиотек, которые генерируют реальные файлы Excel без использования Excel, например Epplus, NPOI или ClosedXML. С помощью, например , Epplus вы можете написать ws.Cells.LoadFromDataTable(table) или LoadFromCollection(someList) LoadFromDataReader() заполнить лист из таблицы данных, IEnumerable<T> или IDbDataReader

Ответ №1:

Запуск Excel только для экспорта данных в файл Excel является излишним. Для веб-сайтов это совершенно непрактично по нескольким причинам:

  • Вам нужна лицензия для каждого пользователя сайта. Это большие деньги.
  • Слишком легко оставить Excel открытым, медленно поглощая оперативную память и процессор сервера.
  • Это просто слишком медленно

xlsx это ZIP-пакет, содержащий четко определенные XML-файлы, поэтому их можно создавать напрямую, используя SDK Open XML или одну из многих библиотек с открытым исходным кодом, которые значительно упрощают это, например Epplus, NPOI или ClosedXML.

Например, Epplus позволяет заполнять лист Excel из DataTable, IEnumerable или IDbDataReader одним вызовом:

 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