使用EPPlus将内连接绑定的DataGridView导出为Excel的方法咨询
问题根因
你代码报错的核心原因有两个:
- 你在
Form1_Load中查询返回的是匿名类集合,匿名类型的作用域仅在当前方法,无法在导出按钮的点击事件中直接做强类型转换 LoadFromCollection<T>()是泛型方法,必须指定明确的泛型参数,不能留空<>
方案1:定义强类型模型(推荐,性能和稳定性最好)
第一步:先定义和查询字段匹配的实体类
// 放在窗体类所属的同一命名空间下即可 public class PExportModel { public int P_Id { get; set; } public string Case_number { get; set; } public string Client { get; set; } public string Model { get; set; } public int Details_Id { get; set; } }
第二步:修改Form_Load的绑定逻辑,返回强类型集合
private void Form1_Load(object sender, EventArgs e) { using (DBEntities1 db = new DBEntities1()) { var query = from p in db.P_DB join d in db.P_Details on p.P_Id equals d.P_Id select new PExportModel // 不再使用匿名类,替换为刚定义的实体类 { P_Id = p.P_Id, Case_number = p.Case_number, Client = p.Client, Model = p.Model, Details_Id = d.Details_Id }; dataGridView4.DataSource = query.ToList(); } }
第三步:修改导出按钮的对应代码
using (var package = new ExcelPackage(fileInfo)) { ExcelWorksheet excelWorksheet1 = package.Workbook.Worksheets.Add("P_Details"); // 替换你原来报错的行 excelWorksheet1.Cells.LoadFromCollection(dataGridView4.DataSource as List<PExportModel>, true); // 你原来漏了保存操作,必须加这行才能把内存数据写入文件 package.Save(); }
方案2:无需修改原有绑定逻辑,直接遍历DataGridView导出
如果你不想新增实体类,也可以直接读取DataGridView的单元格内容写入Excel,不依赖DataSource的类型:
using (var package = new ExcelPackage(fileInfo)) { ExcelWorksheet excelWorksheet1 = package.Workbook.Worksheets.Add("P_Details"); // 写入表头 for (int i = 0; i < dataGridView4.ColumnCount; i++) { excelWorksheet1.Cells[1, i + 1].Value = dataGridView4.Columns[i].HeaderText; } // 写入行数据 for (int i = 0; i < dataGridView4.RowCount; i++) { for (int j = 0; j < dataGridView4.ColumnCount; j++) { excelWorksheet1.Cells[i + 2, j + 1].Value = dataGridView4.Rows[i].Cells[j].Value?.ToString(); } } package.Save(); }
注意事项
如果你使用的是EPPlus 5.x及以上版本,需要在程序启动时(比如窗体构造函数中)添加许可声明,否则会抛出权限异常:
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
内容的提问来源于stack exchange,提问作者sylviaaaaa
相关产品推荐
相关产品推荐

