c#通过OleDb方式读取Excel的最佳做法,不会丢数据

关于c#读取Excel,目前为止,我一共发现三种方式

oledb,com组件、第三方类库

三种方式各有优缺点。本文介绍使用oledb读取excel的最佳做法。

首先说一下为什么不使用其他两种方式:

com组件,使用起来比较麻烦。

第三方类库,我只用过ExcelLibrary这个类库,很不错,只是,它以gpl授权发布,我可不想受它的感染。

所以我采用oledb的方式,方便,无限制。

当然oledb也有它的问题,默认情况下,他检查表中数据行的前8行,来决定列的类型,

此时,就会面临一个问题,如果一个表的前8行是数字,而到了第9行,是字母或是汉字什么的,无法转换成数字格式,就没法读取数据了。

解决此问题的方法是,在连接字符串中设置HDR=no,不把第一行认为是列名,而直接把第一行认为是普通数据,

这样,在读取到dataTable里,oledb会自动生成列名,f1、f2、f3之类,这样的话,我只需要保证列名不是纯数字,然后根据第一行的数据,

改一下列名,再把第一行数据删除,就得到我们想要的DataTable了。

以下代码出自我的开源项目,都是平时的积累,还有一些其他的东西,以后会慢慢介绍给大家:

http://lmcommon.codeplex.com/

 

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(); }

        }



    }

}

 

 

你可能感兴趣的:(Excel)