C# WinForm实现DataGridView数据导出至本地Excel(含仅表头选项)
C# WinForm DataGridView 导出Excel(支持仅表头/含数据模式)
实现方案(推荐EPPlus,无需安装Office)
1. 安装EPPlus NuGet包
在NuGet包管理器中搜索并安装EPPlus,或通过Package Manager Console执行:
Install-Package EPPlus
注意:EPPlus 5.x及以上版本必须设置LicenseContext,否则会触发许可证报错。
2. 编写导出逻辑
假设你有以下控件:
DataGridView(命名为dataGridView1)- 导出按钮(命名为
btnExport) - 两个单选框:
radioHeaderOnly(仅导出表头)、radioWithData(导出表头+数据)
在按钮的点击事件中添加以下代码:
using OfficeOpenXml; using System.IO; using System.Windows.Forms; private void btnExport_Click(object sender, EventArgs e) { if (dataGridView1.Columns.Count == 0) { MessageBox.Show("没有可导出的列数据"); return; } using (SaveFileDialog saveFileDialog = new SaveFileDialog()) { saveFileDialog.Filter = "Excel文件 (*.xlsx)|*.xlsx"; saveFileDialog.Title = "保存Excel文件"; saveFileDialog.FileName = $"导出数据_{DateTime.Now:yyyyMMddHHmmss}"; if (saveFileDialog.ShowDialog() == DialogResult.OK) { // 设置EPPlus非商用许可证上下文 ExcelPackage.LicenseContext = LicenseContext.NonCommercial; using (ExcelPackage package = new ExcelPackage()) { ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("导出数据"); // 写入表头 for (int col = 0; col < dataGridView1.Columns.Count; col++) { worksheet.Cells[1, col + 1].Value = dataGridView1.Columns[col].HeaderText; // 表头加粗(可选样式优化) worksheet.Cells[1, col + 1].Style.Font.Bold = true; } // 根据选择模式写入数据 if (radioWithData.Checked) { for (int row = 0; row < dataGridView1.Rows.Count; row++) { // 跳过DataGridView自动生成的空新行 if (dataGridView1.Rows[row].IsNewRow) continue; for (int col = 0; col < dataGridView1.Columns.Count; col++) { var cellValue = dataGridView1.Rows[row].Cells[col].Value; worksheet.Cells[row + 2, col + 1].Value = cellValue ?? string.Empty; } } // 自动调整列宽(可选) worksheet.Cells.AutoFitColumns(); } package.SaveAs(new FileInfo(saveFileDialog.FileName)); MessageBox.Show("导出成功!"); } } } }
3. 关键细节说明
- 许可证设置:商用场景需购买EPPlus官方许可证,并将
LicenseContext设置为LicenseContext.Commercial。 - 空行处理:若
DataGridView.AllowUserToAddRows = true,必须通过IsNewRow跳过自动生成的空行。 - 数据类型兼容:EPPlus会自动识别数字、日期等常见类型,无需额外格式转换。
备选方案(原生OleDb,需安装Office)
如果必须依赖系统原生组件(不使用第三方库),可通过OleDb连接Excel,但要求目标机器安装Office及对应驱动:
using System.Data.OleDb; using System.IO; private void ExportWithOleDb(bool includeData) { if (dataGridView1.Columns.Count == 0) { MessageBox.Show("没有可导出的列数据"); return; } using (SaveFileDialog saveFileDialog = new SaveFileDialog()) { saveFileDialog.Filter = "Excel 97-2003文件 (*.xls)|*.xls"; saveFileDialog.FileName = $"导出数据_{DateTime.Now:yyyyMMddHHmmss}"; if (saveFileDialog.ShowDialog() == DialogResult.OK) { string filePath = saveFileDialog.FileName; if (File.Exists(filePath)) File.Delete(filePath); // 构建OleDb连接字符串 string connString = $"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={filePath};Extended Properties='Excel 8.0;HDR=Yes;'"; using (OleDbConnection conn = new OleDbConnection(connString)) { conn.Open(); // 创建表结构(表头) string createTableSql = "CREATE TABLE 导出数据 ("; for (int i = 0; i < dataGridView1.Columns.Count; i++) { string colName = dataGridView1.Columns[i].HeaderText.Replace(" ", "_"); createTableSql += $"[{colName}] TEXT"; if (i < dataGridView1.Columns.Count - 1) createTableSql += ","; } createTableSql += ")"; using (OleDbCommand cmd = new OleDbCommand(createTableSql, conn)) { cmd.ExecuteNonQuery(); } // 写入数据(若选择包含数据) if (includeData) { foreach (DataGridViewRow row in dataGridView1.Rows) { if (row.IsNewRow) continue; string insertSql = "INSERT INTO 导出数据 VALUES ("; for (int i = 0; i < dataGridView1.Columns.Count; i++) { string value = row.Cells[i].Value?.ToString() ?? string.Empty; insertSql += $"'{value.Replace("'", "''")}'"; // 转义单引号避免SQL语法错误 if (i < dataGridView1.Columns.Count - 1) insertSql += ","; } insertSql += ")"; using (OleDbCommand cmd = new OleDbCommand(insertSql, conn)) { cmd.ExecuteNonQuery(); } } } conn.Close(); MessageBox.Show("导出成功!"); } } } }
备选方案注意事项
- 64位系统需安装
Access Database Engine驱动才能使用OleDb连接Excel。 - 字符串中的单引号必须转义,否则会触发SQL语法错误。
- 仅支持有限的数据类型,日期、数字等需额外处理格式。
内容的提问来源于stack exchange,提问作者arbabu
相关产品推荐
相关产品推荐

