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

    }
}

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM