关于c#读取Excel,目前为止,我一共发现三种方式
oledb,com组件、第三方类库
三种方式各有优缺点。本文介绍使用oledb读取excel的最佳做法。
首先说一下为什么不使用其他两种方式:
com组件,使用起来比较麻烦。
第三方类库,我只用过ExcelLibrary这个类库,很不错,只是,它以gpl授权发布,我可不想受它的感染。
所以我采用oledb的方式,方便,无限制。
当然oledb也有它的问题,默认情况下,他检查表中数据行的前8行,来决定列的类型,
此时,就会面临一个问题,如果一个表的前8行是数字,而到了第9行,是字母或是汉字什么的,无法转换成数字格式,就没法读取数据了。
解决此问题的方法是,在连接字符串中设置HDR=no,不把第一行认为是列名,而直接把第一行认为是普通数据,
这样,在读取到dataTable里,oledb会自动生成列名,f1、f2、f3之类,这样的话,我只需要保证列名不是纯数字,然后根据第一行的数据,
改一下列名,再把第一行数据删除,就得到我们想要的DataTable了。
以下代码出自我的开源项目,都是平时的积累,还有一些其他的东西,以后会慢慢介绍给大家:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; using System.Text.RegularExpressions; namespace Lm.Common.Excel { public class ExcelReader { public DataTable Read(string file) { string ConnectionString = @"Provider=Microsoft.Jet.OleDb.4.0;Data Source=" + file + ";" + "Extended Properties='Excel 8.0;HDR=no;IMEX=1';"; var con = new System.Data.OleDb.OleDbConnection(ConnectionString); try { con.Open(); var tables = con.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, new object[] { }); con.Close(); if (tables.Rows.Count == 0) { throw new Exception("Excel必须包含一个表"); } var firstTableName = tables.Rows[0]["TABLE_NAME"].ToString(); System.Data.OleDb.OleDbCommand cmd = new System.Data.OleDb.OleDbCommand("select * from [" + firstTableName + "] ", con); System.Data.OleDb.OleDbDataAdapter apt = new System.Data.OleDb.OleDbDataAdapter(cmd); var dt = new System.Data.DataTable(); apt.Fill(dt); if (dt.Rows.Count < 2) { throw new Exception("表必须包含数据"); } var headRow = dt.Rows[0]; foreach (DataColumn c in dt.Columns) { var headValue = (headRow[c.ColumnName] == DBNull.Value || headRow[c.ColumnName] == null) ? "" : headRow[c.ColumnName].ToString().Trim(); if (headValue.Length == 0) { throw new Exception("必须输入列标题"); } if (Regex.IsMatch(headValue, "^[\u4e00-\u9fa5,a-z,A-Z]{0,}$") == false) { throw new Exception("列标题只能输入汉字或英文字母:" + headValue); } if (dt.Columns.Contains(headValue)) { throw new Exception("不能用重复的列标题:" + headValue); } c.ColumnName = headValue; } dt.Rows.RemoveAt(0); return dt; } catch (Exception ee) { throw ee; } finally { con.Close(); } } } }
============================================
我的开源项目,都是平时的积累,对提高开发效率很有帮助。
http://lmcommon.codeplex.com/
我的开源项目,都是平时的积累,对提高开发效率很有帮助。
http://lmcommon.codeplex.com/