VB.NET使用EPPlus导出DataGridView到Excel报item属性只读错误
VB.NET使用EPPlus导出DataGridView到Excel报错修复
问题描述
- 原有基于Microsoft.Interop的导出方案稳定运行数月后持续抛出COM错误,更换为EPPlus实现导出功能
- 导出时无法写入完整DataGridView内容,触发两类报错:
- 属性'item'为'read only'
- String类型值无法转换为'ExcelRange'
- 触发报错的原始代码如下:
With worksheetData For Each column As DataGridViewColumn In DataGridView1.Columns .Cells(1, column.Index + 1) = column.HeaderText Next For i = 1 To Me.DataGridView1.RowCount .Cells(i + 1, 1) = Me.DataGridView1.Rows(i - 1).Cells("EENo").Value For j = 1 To DataGridView1.Columns.Count - 1 .Cells(i + 1, j + 1) = DataGridView1.Rows(i - 1).Cells(j).Value Next Next End With
- 报错触发位置为上述代码中直接给
.Cells()返回值赋值的3行代码。
报错根因
EPPlus中Worksheet.Cells(行索引, 列索引)是只读索引器,返回值为ExcelRange类型的单元格对象,不能直接给该对象本身赋值,所有单元格内容写入操作必须通过修改ExcelRange的Value属性实现。直接给Cells()返回值赋值时,编译器会判定为试图修改只读的item属性,同时因为赋值内容是字符串、和ExcelRange类型不匹配,就会抛出遇到的两类错误。
额外注意:如果DataGridView开启了AllowUserToAddRows属性,RowCount会包含末尾供用户新增记录的空白行,直接循环会导出多余空行,需要在循环时跳过该行。
修正后可运行代码
' 若使用EPPlus 4.5+版本,需提前在程序入口配置许可证上下文,非商业场景使用如下配置即可 ' ExcelPackage.LicenseContext = LicenseContext.NonCommercial With worksheetData ' 写入表头 For Each column As DataGridViewColumn In DataGridView1.Columns .Cells(1, column.Index + 1).Value = column.HeaderText Next ' 写入数据行,跳过末尾新增空行 Dim actualRowCount As Integer = If(DataGridView1.AllowUserToAddRows, DataGridView1.RowCount - 1, DataGridView1.RowCount) For i = 1 To actualRowCount Dim currentDgvRow As DataGridViewRow = DataGridView1.Rows(i - 1) .Cells(i + 1, 1).Value = currentDgvRow.Cells("EENo").Value For j = 1 To DataGridView1.Columns.Count - 1 .Cells(i + 1, j + 1).Value = currentDgvRow.Cells(j).Value Next Next End With
内容的提问来源于stack exchange,提问作者lowkey
相关产品推荐
相关产品推荐

