资讯详情

资讯详情

C# 读取 CSV 与 Excel 实战:连接字符串、IMEX 与 DataGridView 绑定避坑指南

简介这份资源面向具备一定C#基础的开发者聚焦于使用C#读取CSV与Excel文件这一常见数据处理需求帮助解决日常开发中表格数据导入、解析与展示的问题。资源包内含1个doc文档压缩包大小约34KB以文档形式系统梳理了相关实现思路与代码示例。文档围绕OleDbConnection与OleDbDataAdapter两类核心对象展开讲解了CSV文件连接字符串的构造方式包括Provider、Data Source与Extended Properties等关键参数的设置并说明了HDR与FMT属性的作用同时介绍了如何通过OleDbDataAdapter的Fill方法将数据填充至DataTable再借助DataGridView控件完成数据的自动列生成与界面展示。针对Excel文件文档也给出了不同的连接字符串与提供程序配置方案。目前已有260人学习该资源适合需要快速掌握C#表格文件读取技巧、对照代码理解连接与适配器用法的开发者参考。1. 从一段“能跑但不敢改”的代码说起C# 读取 CSV 与 EXCEL 的真实分界线很多人第一次在 C# 里读表格文件都是从一段类似OleDbConnection的代码开始的。它短、能跑、直接往DataGridView里灌数据看起来像捡到了宝。但真正放到项目里问题立刻冒出来CSV 和 EXCEL 到底该不该走同一套连接字符串HDRYES和IMEX1同时出现时谁说了算为什么本地跑得好好的换台机器就报“未注册提供程序”这篇笔记就围绕一份典型的 C# 读取 CSV/EXCEL 源码把连接字符串、SQL 语句、DataTable 填充和 DataGridView 绑定这几条线拆开讲。适合手里已经有一份类似代码、想把它改稳、改到能进生产环境的 C# 开发者也适合刚接触 ADO.NET 读写表格文件、不想在玄学报错里反复翻车的新手。2. 连接字符串拆解Jet 与 ACE 的选型、HDR 与 IMEX 的真实作用2.1 为什么 CSV 和 EXCEL 的连接字符串长得不一样先看 CSV 分支里那行关键代码string connStr ProviderMicrosoft.Jet.OLEDB.4.0;Data Source filePath ;Extended Propertiestext;HDRYES;FMTDelimited;;这里Provider用的是Microsoft.Jet.OLEDB.4.0它是 32 位时代的 OLE DB 提供程序对纯文本目录的支持非常直接。注意Data Source给的是目录不是单个 CSV 文件。这是很多人第一次踩坑的地方CSV 被当成一个“文本数据库”目录是库文件是表。所以后面commandText才写成select * from test1.csv这种形式而不是直接指向文件路径。EXCEL 分支则不同string connStr ProviderMicrosoft.Jet.OLEDB.4.0;Data Source csvDir ;Extended PropertiesExcel 8.0;HDRYES;IMEX1;;Data Source这里给的是具体文件Extended Properties里写的是Excel 8.0。Excel 8.0对应的是较老的 .xls 格式如果你拿它去读 .xlsx常见结果就是“外部表不是预期的格式”。所以选型上要记住一条硬边界Jet 提供程序对 .xls 友好ACE 提供程序对 .xlsx 友好。原文里 EXCEL 分支用的是 Jet如果你的文件是 .xlsx要么换 ACE要么先另存为 .xls别硬扛。2.2 HDR 和 IMEX 到底在控制什么HDRYES表示第一行是列名读进来之后 DataTable 的列名就是表头HDRNO则会把第一行也当数据列名变成 F1、F2 这种系统名。原文注释里写得很清楚有列名用 YES没列名用 NO。但真正容易翻车的是IMEX1。IMEX是 ImportMixedTypes 的缩写IMEX1告诉提供程序当某一列里混着数字、日期、字符串时按文本处理。不加它Excel 驱动会自己“猜”类型前 8 行如果是数字后面突然来个“暂无”那一格就可能变成空值。这个行为在数据量小的时候看不出来数据一多就是血泪经验。所以读 EXCEL 时只要列里可能混类型IMEX1基本是必加项。CSV 分支里FMTDelimited表示按分隔符解析默认是逗号。如果你的 CSV 是分号或竖线分隔需要额外加FMTDelimited(;)这类写法否则整行会被当成一列。原文注释里提到“FMTDelimited 是否有分隔符如|”说的就是这个点。提示CSV 的Data Source是目录EXCEL 的Data Source是文件这两者写反了报错信息通常不会直接告诉你原因。2.3 路径拼接与 SQL 语句的隐藏依赖原文里有一段路径处理int ipos csvDir.LastIndexOf(\\); string filePath csvDir.Substring(0, ipos 1); string commandText select * from csvDir.Replace(filePath, );逻辑是从完整路径里截出目录部分再用Replace把目录去掉剩下的就是文件名拼成select * from 文件名。这段代码能跑但依赖两个前提路径里用的是反斜杠且文件名不重复出现在目录名里。如果目录叫C:\csv\csv\Replace会把目录里的csv也替掉SQL 就废了。更稳的写法是用Path.GetDirectoryName和Path.GetFileName这也是我后来改这类代码时的固定动作。3. 从 OleDbDataAdapter 到 DataGridView填充、绑定与列名处理3.1 DataTable 填充的完整链路连接对象打开之后核心就三行OleDbDataAdapter odp new OleDbDataAdapter(commandText, olconn); DataTable dt new DataTable(); odp.Fill(dt);OleDbDataAdapter在这里扮演的是“查询执行 结果搬运”的角色。Fill方法会把结果集写进DataTable同时根据结果集的元数据自动建列。这里有个细节Fill内部会自己打开和关闭连接如果你已经手动Open了它不会重复打开但用完不会帮你关。所以olconn最好放在using里或者至少在Fill之后显式Close。原文没有写关闭短时间跑一次没事循环读多个文件时连接池会被占满。参数上commandText就是那条select * from ...olconn是已经配置好连接字符串的连接对象。如果 CSV 没有列名HDRNO时 DataTable 的列名会是 F1、F2这时候绑定到 DataGridView 会显示成系统列名需要手动改HeaderText原文注释里也给了对应写法。3.2 DataGridView 绑定的两种姿势有列名时原文用的是dataGridView1.AutoGenerateColumns true; dataGridView1.DataSource dt.DefaultView;AutoGenerateColumns true让控件根据 DataTable 的列自动生成列省事但列的顺序、宽度、标题都不可控。没有列名时原文注释里换成了手动指定dataGridView2.DataSource dt.DefaultView; dataGridView2.Columns[0].SortMode DataGridViewColumnSortMode.NotSortable; dataGridView2.Columns[0].HeaderText 编号; dataGridView2.Columns[1].HeaderText 高度; dataGridView2.Columns[2].HeaderText 宽度;这里SortMode设成NotSortable是为了防止用户点击列头排序时DataTable 的默认视图和绑定源不同步导致数据错位。手动改HeaderText则是因为HDRNO时列名没有业务含义。两种姿势没有绝对优劣有表头就用自动没表头就手动关键是别在自动生成之后再逐列去改那样容易和自动生成的列索引对不上。3.3 一个容易忽略的边界空值和类型推断CSV 里空单元格读进来通常是DBNull.Value绑定到 DataGridView 显示为空这没问题。但如果后续要拿 DataTable 做计算直接Convert.ToDouble就会炸。常见做法是在Fill之后遍历一遍把关键列的空值替换成默认值或者用dt.Columns[高度].DataType先看驱动推断成了什么类型。EXCEL 那边因为IMEX1的存在混类型列会被当成字符串取数时统一按字符串处理再转换反而比依赖驱动推断更稳。4. 避坑与排查连接字符串、驱动版本和路径的五个真实翻车点4.1 现象报“未在本地计算机上注册 Microsoft.Jet.OLEDB.4.0 提供程序”原因项目编译成了 64 位而 Jet 提供程序只有 32 位版本。这是最经典的翻车点代码本身没错平台目标错了。解决在项目属性里把目标平台改成 x86或者改用Microsoft.ACE.OLEDB.12.0并安装对应位数的驱动。改平台比换驱动快但换驱动能顺带支持 .xlsx。4.2 现象读 .xlsx 时报“外部表不是预期的格式”原因连接字符串里写的是Excel 8.0这是给 .xls 用的.xlsx 需要Excel 12.0或更高并且提供程序要换成 ACE。解决把Extended Properties改成Excel 12.0;HDRYES;IMEX1;Provider改成Microsoft.ACE.OLEDB.12.0。如果机器上没装 ACE 驱动这一步会继续报“未注册”需要先补驱动。4.3 现象CSV 读进来只有一列整行挤在一起原因FMTDelimited默认按逗号分隔但文件实际用的是分号、制表符或竖线。解决在FMT里显式指定分隔符比如FMTDelimited(;)。另外要确认Data Source给的是目录而不是文件给成文件时驱动可能直接报错或返回空结果。4.4 现象EXCEL 里明明是数字读进来变成空或字符串原因IMEX没设或设成了 0驱动按前几行猜类型后面类型不一致的单元格被置空。解决连接字符串里加IMEX1让混类型列统一按文本处理。代价是数字列也会变成字符串取数时自己做类型转换。4.5 现象SQL 语句里的表名不对报“找不到表”原因CSV 的表名是文件名EXCEL 的表名是工作表名加$比如[test1$]。工作表名里有空格或特殊字符时还需要用方括号包起来。解决CSV 用Path.GetFileName拿文件名拼 SQLEXCEL 先确认工作表名写成[工作表名$]。如果工作表名不确定可以先查GetOleDbSchemaTable拿到所有表名再拼。5. 进阶技巧把这段代码改成能进项目的读取工具5.1 用 Path API 替换字符串截取原文用LastIndexOf和Substring拼路径能跑但脆。改成下面这样目录和文件名各归各的不再依赖Replacestring fullPath C:\test1.xls; string dir Path.GetDirectoryName(fullPath); // C:\ string fileName Path.GetFileName(fullPath); // test1.xls string ext Path.GetExtension(fullPath).ToUpper(); // .XLSPath.GetDirectoryName返回不带末尾反斜杠的目录拼连接字符串时自己补一个\。Path.GetExtension拿到的扩展名带点统一转大写再判断比EndsWith(CSV)更不容易被大小写和空格干扰。5.2 把连接字符串抽成配置方法CSV 和 EXCEL 各写一个方法返回连接字符串调用处只传路径string BuildCsvConnStr(string dir) { return ProviderMicrosoft.Jet.OLEDB.4.0;Data Source dir ;Extended Propertiestext;HDRYES;FMTDelimited;; } string BuildExcelConnStr(string file) { return ProviderMicrosoft.ACE.OLEDB.12.0;Data Source file ;Extended PropertiesExcel 12.0;HDRYES;IMEX1;; }这样改分隔符、换提供程序、调 IMEX 都只动一个地方。方法里不要拼 SQLSQL 由调用方根据文件类型单独构造职责分开。5.3 读取结果做一次列名和空值清洗不管 CSV 还是 EXCELFill之后统一走一遍清洗foreach (DataColumn col in dt.Columns) { if (string.IsNullOrWhiteSpace(col.Caption)) col.Caption col.ColumnName; } foreach (DataRow row in dt.Rows) { for (int i 0; i dt.Columns.Count; i) { if (row[i] DBNull.Value) row[i] string.Empty; } }Caption是显示名ColumnName是内部名绑定到 DataGridView 时优先显示Caption。把空值统一成空字符串后续做字符串拼接或导出时不用到处判DBNull。这一步看起来多余但真正进项目后能省掉大量“为什么这里显示空白”的排查时间。5.4 验证读取是否完整的三个检查点第一看dt.Rows.Count和源文件行数是否对得上CSV 有表头时源文件行数减一。第二看dt.Columns.Count和预期列数是否一致少列通常是分隔符或HDR设错。第三抽一行混类型的数据确认IMEX1生效后该列是字符串而不是空。这三个检查点跑一遍基本能覆盖八成读取异常。从那以后我每次接这类表格读取需求都强制先跑一遍路径解析和连接字符串构造再拿三行测试数据验证列数和空值最后才往 DataGridView 上绑。希望帮到你。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →