开心的饭桶

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

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

    }
}

 

 

posted on 2012-09-13 08:50  开心的饭桶  阅读(3898)  评论(1编辑  收藏  举报