C# WinForms导入Excel数据后DataGridView为空问题求助
问题解决与功能实现
一、DataGridView导入为空的修复方案
原代码核心问题:
- 读取Excel数据的
for循环被注释,且存在无操作的foreach循环,未向DataGridView添加任何数据 - ColumnCount设置冲突,先根据Excel范围设置后又强制改为6,易与实际数据列数不匹配
- Excel Interop对象未正确释放,存在内存泄漏风险
修复后的完整导入代码:
using System; using System.Windows.Forms; using Microsoft.Office.Interop.Excel; using System.Runtime.InteropServices; namespace WinFormsApp4 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Load_Click(object sender, EventArgs e) { using (OpenFileDialog ofd = new OpenFileDialog()) { ofd.Filter = "Excel Files | *.xlsx; *.xls; *.csv"; ofd.Title = "选择文件"; if (ofd.ShowDialog() == DialogResult.OK) label1.Text = ofd.FileName; } } private void Import_Click_1(object sender, EventArgs e) { Application xlapp = null; Workbook xlworkbook = null; Worksheet xlworksheet = null; Range xlrange = null; try { // 初始化Excel对象 xlapp = new Application(); xlworkbook = xlapp.Workbooks.Open(label1.Text); // 若为CSV文件,默认工作表是第一个,可改为xlworkbook.Worksheets[1] xlworksheet = xlworkbook.Worksheets["List1"]; xlrange = xlworksheet.UsedRange; // 清空DataGridView现有内容 DataMore.Rows.Clear(); DataMore.Columns.Clear(); // 设置列头与列数 DataMore.ColumnCount = 6; DataMore.Columns[0].HeaderText = "Datum"; DataMore.Columns[1].HeaderText = "Energia"; DataMore.Columns[2].HeaderText = "AC výkon"; DataMore.Columns[3].HeaderText = "napetie siete"; DataMore.Columns[4].HeaderText = "AC prud"; DataMore.Columns[5].HeaderText = "DC napetie"; // 遍历Excel行,添加到DataGridView for (int xlrow = 1; xlrow <= xlrange.Rows.Count; xlrow++) { object[] rowData = new object[6]; // 读取当前行的单元格值,最多取6列 for (int xlcol = 1; xlcol <= Math.Min(xlrange.Columns.Count, 6); xlcol++) { rowData[xlcol - 1] = xlrange.Cells[xlrow, xlcol].Value ?? string.Empty; } DataMore.Rows.Add(rowData); } } catch (Exception ex) { MessageBox.Show($"导入失败:{ex.Message}"); } finally { // 释放Excel资源,避免内存泄漏 if (xlworkbook != null) { xlworkbook.Close(false); Marshal.ReleaseComObject(xlworkbook); } if (xlapp != null) { xlapp.Quit(); Marshal.ReleaseComObject(xlapp); } xlworksheet = null; xlrange = null; } }
二、删除数据中的0值功能
添加按钮并绑定以下方法,提供两种实现方案:
方案1:清空所有值为0的单元格
private void btnClearZeros_Click(object sender, EventArgs e) { foreach (DataGridViewRow row in DataMore.Rows) { if (!row.IsNewRow) { foreach (DataGridViewCell cell in row.Cells) { if (cell.Value != null && cell.Value.ToString().Trim() == "0") { cell.Value = string.Empty; } } } } }
方案2:删除包含0值的整行
private void btnDeleteZeroRows_Click(object sender, EventArgs e) { // 从后往前遍历,避免索引错乱 for (int i = DataMore.Rows.Count - 1; i >= 0; i--) { DataGridViewRow row = DataMore.Rows[i]; if (!row.IsNewRow) { bool hasZero = false; foreach (DataGridViewCell cell in row.Cells) { if (cell.Value != null && cell.Value.ToString().Trim() == "0") { hasZero = true; break; } } if (hasZero) DataMore.Rows.RemoveAt(i); } } }
三、生成图表功能
先在窗体添加Chart控件(命名为chart1),然后添加按钮绑定以下方法:
using System.Windows.Forms.DataVisualization.Charting; private void btnGenerateChart_Click(object sender, EventArgs e) { if (DataMore.Rows.Count == 0) { MessageBox.Show("请先导入数据"); return; } // 清空图表现有内容 chart1.Series.Clear(); chart1.Titles.Clear(); // 创建折线图系列 Series energySeries = new Series("Energia 趋势"); energySeries.ChartType = SeriesChartType.Line; chart1.Series.Add(energySeries); // 添加数据点 foreach (DataGridViewRow row in DataMore.Rows) { if (!row.IsNewRow) { string xLabel = row.Cells[0].Value?.ToString(); if (double.TryParse(row.Cells[1].Value?.ToString(), out double yValue)) { energySeries.Points.AddXY(xLabel, yValue); } } } // 设置图表样式 chart1.Titles.Add("数据趋势图"); chart1.ChartAreas[0].AxisX.Title = "Datum"; chart1.ChartAreas[0].AxisY.Title = "Energia"; }
额外优化建议
若你的文件是逗号分隔的CSV,可直接用文件读取替代Excel Interop,无需依赖Office安装:
private void ImportCSV_Click(object sender, EventArgs e) { try { string[] lines = System.IO.File.ReadAllLines(label1.Text); DataMore.Rows.Clear(); DataMore.Columns.Clear(); DataMore.ColumnCount = 6; // 设置列头(同之前的代码) DataMore.Columns[0].HeaderText = "Datum"; // ...其他列头设置 foreach (string line in lines) { string[] values = line.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); object[] rowData = new object[6]; Array.Copy(values, rowData, Math.Min(values.Length, 6)); DataMore.Rows.Add(rowData); } } catch (Exception ex) { MessageBox.Show($"导入失败:{ex.Message}"); } }
内容的提问来源于stack exchange,提问作者Pavol Trimay
相关产品推荐
相关产品推荐

