C#新手求助:如何将Excel源文本转换为DataGridView列?
将Excel数据导入DataGridView的修正方案
嘿,刚学C#就着手Excel导入的功能,值得点赞!我看了你的需求和现有代码,发现几个可以优化调整的点,帮你顺利把Excel里的文本数据转换成DataGridView的列:
先梳理下现有代码的潜在问题
- 连接字符串仅支持旧版Excel(.xls)和32位环境,如果你用的是新版Excel(.xlsx)或者64位开发环境,会出现连接失败的情况
- Sheet名硬编码为
[Inwestycje$],如果你的Excel文件里的工作表名称不是这个,会直接报错 - 异常处理过于笼统,出现问题时无法得知具体错误原因,不利于调试
- 你的Excel第一列是
NO BRAND NAME(包含序号、品牌、名称),如果需要拆分这一列成多个DataGridView列,现有代码没做处理
修正后的完整代码
using System; using System.Data; using System.Data.OleDb; using System.Linq; using System.Windows.Forms; namespace ExceltoDGV { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { try { OpenFileDialog openfile1 = new OpenFileDialog(); // 限制选择Excel文件类型,避免选错 openfile1.Filter = "Excel 文件 (*.xls;*.xlsx)|*.xls;*.xlsx|所有文件 (*.*)|*.*"; if (openfile1.ShowDialog() == DialogResult.OK) { this.textBox1.Text = openfile1.FileName; string path = openfile1.FileName; string connectionString = string.Empty; // 根据文件后缀选择对应的连接字符串 if (path.EndsWith(".xls")) { // 旧版Excel(.xls)连接字符串 connectionString = $"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={path};Extended Properties=\"Excel 8.0;HDR=YES;IMEX=1;\""; } else if (path.EndsWith(".xlsx")) { // 新版Excel(.xlsx)连接字符串 connectionString = $"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={path};Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1;\""; } using (OleDbConnection conn = new OleDbConnection(connectionString)) { conn.Open(); // 获取Excel里的所有工作表名称,避免硬编码出错 DataTable sheetsTable = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null); if (sheetsTable.Rows.Count == 0) { MessageBox.Show("Excel文件中未找到工作表!"); return; } // 取第一个工作表名称(如果有多个可以做选择) string sheetName = sheetsTable.Rows[0]["TABLE_NAME"].ToString(); // 查询工作表数据 OleDbDataAdapter myDataAdapter = new OleDbDataAdapter($"SELECT * FROM [{sheetName}]", conn); DataTable dt = new DataTable(); myDataAdapter.Fill(dt); // 可选:如果需要拆分第一列(NO BRAND NAME)为序号、品牌、名称三列 // 先添加新列 dt.Columns.Add("序号", typeof(int)); dt.Columns.Add("品牌", typeof(string)); dt.Columns.Add("名称", typeof(string)); // 遍历行拆分数据 foreach (DataRow row in dt.Rows) { string firstColumnValue = row["NO BRAND NAME"].ToString().Trim(); if (!string.IsNullOrEmpty(firstColumnValue)) { // 按空格拆分,注意处理可能的多余空格 string[] parts = firstColumnValue.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length >= 3) { row["序号"] = int.Parse(parts[0]); row["品牌"] = parts[1]; row["名称"] = string.Join(" ", parts.Skip(2)); } } } // 绑定到DataGridView dataGridView1.DataSource = dt; } } } catch (Exception ex) { // 显示具体错误信息,方便调试 MessageBox.Show($"导入失败:{ex.Message}"); } } } }
关键改动说明
- 适配不同Excel版本:根据文件后缀(.xls/.xlsx)选择对应的OLEDB驱动,
Microsoft.ACE.OLEDB.12.0支持新版Excel和64位环境(需要确保安装了对应驱动) - 动态获取工作表名称:不再硬编码Sheet名,通过
GetOleDbSchemaTable获取所有工作表,避免因Sheet名不符报错 - 完善异常处理:捕获具体异常并显示错误信息,方便排查问题
- 可选列拆分:如果需要把
NO BRAND NAME列拆分成序号、品牌、名称三个列,代码里已经加入了对应的处理逻辑,不需要的话可以直接删掉这部分
额外注意事项
- 确保你的项目平台目标和OLEDB驱动版本匹配(32位/64位),如果遇到“找不到驱动”的错误,可以在项目属性里设置为
x86平台 IMEX=1参数可以让驱动把混合数据类型的列当作文本处理,避免数据丢失
内容的提问来源于stack exchange,提问作者PYJTER
相关产品推荐
相关产品推荐

