C# DataGridView导出Excel多Office版本不兼容 求适配修改方案
问题根源
- 你使用的
Microsoft.Office.Interop.Excel依赖对应版本的Office主互操作程序集(PIA),不同Office版本的PIA接口定义存在差异,32/64位Office运行环境不匹配也会触发此类报错 - 代码中直接通过
"Sheet1"名称获取工作表的写法不兼容非英文默认语言的Office版本,部分本地化Office默认工作表为对应语言命名(如中文环境下默认是「工作表1」),会直接抛出找不到对象的异常 SaveAs方法不同Office版本要求的参数数量不同,你当前仅传入文件名的写法在低版本Office中会报错
方案1:修改现有Interop代码兼容多版本Office
仅调整现有代码,仍需要目标设备安装Office,修改后的代码如下:
try { Microsoft.Office.Interop.Excel._Application app = new Microsoft.Office.Interop.Excel.Application(); Microsoft.Office.Interop.Excel._Workbook workbook = app.Workbooks.Add(Type.Missing); Microsoft.Office.Interop.Excel._Worksheet worksheet = null; app.Visible = true; // 直接通过索引获取第一个工作表,避免名称不兼容问题 worksheet = (Microsoft.Office.Interop.Excel._Worksheet)workbook.Sheets[1]; worksheet.Name = "Records"; try { for (int i = 0; i < dataGridView2.Columns.Count; i++) { worksheet.Cells[1, i + 1] = dataGridView2.Columns[i].HeaderText; } for (int i = 0; i < dataGridView2.Rows.Count; i++) { for (int j = 0; j < dataGridView2.Columns.Count; j++) { if (dataGridView2.Rows[i].Cells[j].Value != null) { worksheet.Cells[i + 2, j + 1] = dataGridView2.Rows[i].Cells[j].Value.ToString(); } else { worksheet.Cells[i + 2, j + 1] = ""; } } } SaveFileDialog saveDialog = new SaveFileDialog(); saveDialog.Filter = "Excel files (*.xlsx)|*.xlsx|All files (*.*)|*.*"; saveDialog.FilterIndex = 1; if (saveDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { // 补全SaveAs所有可选参数,兼容不同Office版本 workbook.SaveAs(saveDialog.FileName, Microsoft.Office.Interop.Excel.XlFileFormat.xlOpenXMLWorkbook, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); MessageBox.Show("Export Successful", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information); } } catch (System.Exception ex) { MessageBox.Show(ex.Message); } finally { // 释放COM对象,避免Excel进程残留 if (worksheet != null) System.Runtime.InteropServices.Marshal.ReleaseComObject(worksheet); if (workbook != null) { workbook.Close(); System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook); } if (app != null) { app.Quit(); System.Runtime.InteropServices.Marshal.ReleaseComObject(app); } worksheet = null; workbook = null; app = null; GC.Collect(); GC.WaitForPendingFinalizers(); } } catch (Exception ex) { MessageBox.Show(ex.Message.ToString()); }
方案2:使用无Office依赖的第三方库(更推荐)
直接抛弃Interop,使用EPPlus库实现导出,不需要目标设备安装任何版本的Office,兼容性更强,性能也更高。
你可以通过NuGet安装EPPlus 4.x版本(该版本为MIT协议可免费商用,5.x以上版本商用需要授权),实现代码如下:
using OfficeOpenXml; using System.IO; // 导出逻辑 try { ExcelPackage.LicenseContext = LicenseContext.NonCommercial; // 非商业使用声明,商用可改为Commercial并遵守对应协议 using (ExcelPackage package = new ExcelPackage()) { ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("Records"); // 写入表头 for (int i = 0; i < dataGridView2.Columns.Count; i++) { worksheet.Cells[1, i + 1].Value = dataGridView2.Columns[i].HeaderText; } // 写入行数据 for (int i = 0; i < dataGridView2.Rows.Count; i++) { for (int j = 0; j < dataGridView2.Columns.Count; j++) { worksheet.Cells[i + 2, j + 1].Value = dataGridView2.Rows[i].Cells[j].Value?.ToString() ?? ""; } } SaveFileDialog saveDialog = new SaveFileDialog(); saveDialog.Filter = "Excel files (*.xlsx)|*.xlsx|All files (*.*)|*.*"; saveDialog.FilterIndex = 1; if (saveDialog.ShowDialog() == DialogResult.OK) { FileInfo fi = new FileInfo(saveDialog.FileName); package.SaveAs(fi); MessageBox.Show("导出成功", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information); } } } catch (Exception ex) { MessageBox.Show(ex.Message); }
内容的提问来源于stack exchange,提问作者Adamszsz
相关产品推荐
相关产品推荐

