亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

通用的高度可擴展的Excel導入實現(附Demo)

2019-11-17 01:27:42
字體:
來源:轉載
供稿:網友

通用的高度可擴展的Excel導入實現(附Demo)

Demo源碼

背景

  通過程序將excel導入到數據庫中是一項非常常見的功能。通常的做法是:先將excel轉成DataTable,然后將DataTable轉換成List<T>,最終通過List<T>導入進數據庫。

  同時,一般的ExcelUtil基類也會提供類似List<T> GetEntityListFromFile<T>(string fileName)的實現,但是這些實現一般都是機械化地對應,缺少一些自定義的操作。

問題

  在我的開發過程中,就導入excel這一塊就碰到了以下的一些問題:

  1.   excel中的列名可能不止一個(客戶可能沒有下載模板或者模板的版本不對,導致同一列可能有多個列名,例如【ID】和【編號】可能都對應實體類中的【ID】列)
  2.   excel中的列可能對應著實體類中的多個列(例如實體類中有【ID】、【Name】兩個字段,而excel模板中只有【ID】,我們需要通過excel中的【ID】從數據庫中找到Name值去填充實體類的【Name】)
  3.   需要對excel中某些數據的有效性做驗證,包括但不限于“數據類型有效”,“數據在數據庫中的存在性”,“數據在數據庫中的狀態有效”等等
  4.   需要對excel中的某些列進行自定義的映射(例如實體類和excel中都有【Status】,我們需要將excel中的【Status】寫“1”和寫“激活”的都填充實體類的【Status】為“1”)

  以上這些問題,僅僅通過基類提供的方法是無法實現的,所以本篇文章提供一種高度自定義的Excel導入通過模塊的實現,期以解決以上問題。

Demo程序結構概覽

  

  

ps:要下班了,今日就先發這么多,

  大家可以先下Demo看一下,功能都實現了,有問題可以大家一起交流,

  如果大家想知道具體流程,我就再添加。

實現思路

  首先,需要明確的是我們的需求:

  1. 使用c#技術,將excel導入到程序中,并以List<Entity>的形式進行存在
  2. 可以自定義excel的列名和Entity中屬性的對應關系,支持excel中多個列名對應Entity中同一個屬性,也支持Entity中的多個屬性對應excel中的一個列名
  3. 可以自定義excel中列的值轉換函數,假設excel中有“狀態”列對應到Entity中的Status屬性,在excel中的“狀態”列中寫【激活】或者【1】,最終都對應到Status的【true】
  4. 可以自定義excel中列的值有效性驗證函數

  接下來,就簡要講述一下以上功能的實現:

  • 類【public class ImportUtil<Entity> where Entity : new()】實現了excel的導入功能,Entity為實體類類型
    /// <summary>    /// 高度可擴展的excel導入 By Dean 20140320    /// 應用場景:1 需要支持實體類屬性和excel中列的一對多關系 如excel中的列名是JHB、聚好幣、PV時候,均認為映射到實體中的JHB字段    ///2 需要支持實體類屬性和excel中列的多對一關系 如excel中只包含“名稱”列,有同時填充實體類的Code & Name屬性時,可以將Code屬性也對應到“名稱”列,然后寫一個轉換函數,通過“名稱”從DB中取出Code再映射    /// 功    能:1 可以自動剔除全部為空的行    ///           2 能夠自定義地設置將excel中的列映射到實體類上的哪個字段,以及映射的方法    ///           3 能夠對excel中的數據的有效性進行自定義的檢查    /// </summary>    /// <typeparam name="Entity"></typeparam>    public class ImportUtil<Entity> where Entity : new()
  • ImportUtil類中有唯一的構造函數【public ImportUtil(Dictionary<string, string> allColumns)】
  public ImportUtil(Dictionary<string, string> allColumns)   {        AllColumns = allColumns;   }
       //實體類列和excel列的對應關系            Dictionary<string, string> allColumns = new Dictionary<string, string>            {                {"ID","編號"},                {"StudentID","學生編號|學生ID"},{"StudentName","學生編號|學生ID"},                {"Disc

  該構造函數傳入參數allColumns,是一個Dictionary<string,string>類型的,該參數實現了需求2,字典的Key是實體類Entity中的【屬性名稱】,字典的Value是excel中的【列名稱】,使用|來支持excel的多列名。

  • ImportUtil類中有唯一的對外公開的方法【public List<Entity> GetEntityList】
        /// <summary>        /// 根據excel文件名獲取實體類列表 《唯一向外部公開的接口》        /// </summary>        /// <param name="fileName">excel文件名</param>        /// <param name="errorInfo">導入過程中的任何錯誤信息都會放到這里面</param>        /// <param name="converterFields">需要進行預定義類型轉換的列</param>        /// <param name="customConverts">需要進行自定義類型轉換(key是實體類對應的列,value是包含excel中對應列的值和操作后的返回值的Func)</param>        /// <param name="dataValidateChecks">在進行excel列映射到實體類之前,對excel列中的值進行的預檢查</param>        /// <returns>實體類列表</returns>        public List<Entity> GetEntityList(string fileName,                                          List<string> errorInfo,                                          Dictionary<KnownDataType, List<string>> converterFields = null,                                          Dictionary<string, Func<object, object>> customConverts = null,                                          Dictionary<string, Func<object, string>> dataValidateChecks = null)

  該方法有5個輸入參數,其中fileName和errorInfo是必輸的,方法最終返回的就是我們所需要的List<Entity>,方法的執行過程就是先通過excel的地址將excel導入稱為DataTable,然后將DataTable轉換成List<T>,在轉換的過程中進行數據的有效性驗證和數據值的類型轉換。

下面簡單介紹一下這5個參數:

  1. fileName,string,需要導入的excel的地址;
  2. errorInfo,List<string>,導入過程中所發生的錯誤信息;
  3. convertFields,Dictionary<KnownDataType,List<string>>,預定義的類型轉換;excel中的列都是object類型的,而Entity中的屬性卻是強類型的,對于Int,Decimal,Double,DateTime已經定義好了相關的轉換函數,僅需將Entity屬性名稱傳入,在進行DataTable轉List<Entity>時就能夠將對應Column的值進行預定義的類型轉換
               //預定義類型轉換            Dictionary<KnownDataType, List<string>> convertFields = new Dictionary<KnownDataType, List<string>>            {                {KnownDataType.Int, new List<string> {"ID", "StudentID", "DisciplineID"}},                {KnownDataType.Double, new List<string> {"Score"}}            };
  4. customConverts,Dictionary<string,Func<object,object>>,自定義的類型轉換;預定義的類型轉換通常只是將excel中的列轉成對應的類型或者給個默認值,是通用的操作,但是我們常常需要對excel中的列進行自定義的轉換,例如:excel中有“編號”列,設置同時對應到Entity的“ID”、“Name”屬性,而“ID”屬性可以直接使用預定義轉換完成,“Name”列則需要通過“編號”從數據庫中找到“Name”再賦值給“Name”。因此,這時候我們需要自定義的轉換。寫法如下:
                //自定義類型轉換            Dictionary<string, Func<object, object>> customConverts = new Dictionary<string, Func<object, object>>            {                {                    "StudentName", currColumn =>                    {                        int studentID;                        if (currColumn != null && int.TryParse(currColumn.ToString(), out studentID))                        {                            var r = DataPool.EntireStudents.Find(c => c.ID == studentID);                            if (r != null)                            {                                return r.Name;                            }                        }                        return string.Empty;                    }                },                {                    "MakeUpExamTime", currColumn =>                    {                        DateTime colDateTime;                        if (currColumn != null && DateTime.TryParse(currColumn.ToString(), out colDateTime))                        {                            return colDateTime;                        }                        return null;                    }                }            };
  5. dataValidateChecks,Dictionary<string,Func<object,string>>,excel列的數據有效性驗證,在Entity的每個屬性的賦值之前都會先驗證一下excel的數據是否有效,Key是要驗證的屬性的名字,Value是一個Func,輸入參數就是excel的列值,返回的是string,驗證通過時是string.Empty,驗證不通過返回的是錯誤信息。寫法如下:
                //excel列的數據有效性驗證 以下完成了對excel中編號列的值必須為整數且不為空的驗證的設定            Dictionary<string,Func<object,string>> dataValidateChecks = new Dictionary<string, Func<object, string>>            {                {                    "ID", currColumn =>                    {                        int idInt;                        if (currColumn!=null&&int.TryParse(currColumn.ToString(),out idInt))                        {                            return string.Empty;                        }                        return "ID不能為空且必須為整數";                    }                }            };
                //執行excel導入            var res = importUtil.GetEntityList(excelPath, errors, convertFields, customConverts, dataValidateChecks);

總結

  以上就完成了一個excel的自定義導入的功能,謝謝。

Demo源碼


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91社区国产高清| 国产欧美精品在线播放| 精品久久久久久久久久久久久| 中文字幕亚洲一区在线观看| 色综合视频一区中文字幕| 亚洲va欧美va在线观看| 国产精品综合久久久| 国产成人综合久久| 狠狠色狠狠色综合日日小说| 日本高清久久天堂| 亚洲欧洲第一视频| 国产精品一区电影| 中文字幕亚洲图片| 欧洲s码亚洲m码精品一区| 久热精品视频在线免费观看| 久久人人爽人人爽人人片av高清| 福利视频一区二区| 精品久久久久久中文字幕一区奶水| 色妞久久福利网| 亚洲精品国产福利| 国产精品人成电影| 亚洲美女福利视频网站| 97在线精品国自产拍中文| 韩国19禁主播vip福利视频| 久久精品国产清自在天天线| 日韩av123| 国产精品中文字幕在线观看| 欧美高清videos高潮hd| 国产精品女人久久久久久| 日韩成人小视频| 亚洲精品国产免费| 国产精品免费电影| 日本伊人精品一区二区三区介绍| 国产主播喷水一区二区| 国产成人精品在线播放| 大胆人体色综合| 国产精品视频不卡| 91成人天堂久久成人| 国产成人在线播放| 欧美国产一区二区三区| 国产精品久久久久一区二区| 色在人av网站天堂精品| 亚洲欧美日韩中文视频| 色综合色综合久久综合频道88| 亚洲欧美日韩精品久久奇米色影视| 久久99热精品这里久久精品| 中文字幕精品一区二区精品| 欧美又大粗又爽又黄大片视频| 亚洲va码欧洲m码| 日本一欧美一欧美一亚洲视频| 国产91热爆ts人妖在线| 国产丝袜精品第一页| 欧美日韩成人在线播放| 成人一区二区电影| 日本一区二三区好的精华液| 成人乱人伦精品视频在线观看| 久久不射热爱视频精品| 亚洲区在线播放| 国产精品美女av| 色偷偷av一区二区三区乱| 国产精品一二区| 午夜精品久久久久久久99黑人| 国产精品久久久久久久久久小说| 精品少妇一区二区30p| 国产在线拍揄自揄视频不卡99| 精品福利免费观看| 热99在线视频| 91国内免费在线视频| 国产精品久久91| 亚洲三级 欧美三级| 国产精品高精视频免费| 欧美诱惑福利视频| 欧美性猛交xxxx偷拍洗澡| 亚洲国产一区二区三区四区| 国产精品一区=区| 亚洲视频999| 亚洲国产成人久久| 国产精品9999| 97久久精品人搡人人玩| 精品久久久精品| 国产午夜精品美女视频明星a级| 成人网欧美在线视频| 久久精品成人欧美大片| 国产精品久久不能| 国产视频精品一区二区三区| 国产精品自产拍高潮在线观看| 51午夜精品视频| 久久影院模特热| 欧美电影免费观看网站| 欧美电影在线观看网站| 国语自产偷拍精品视频偷| 精品视频在线播放色网色视频| 欧美大片在线影院| 中文字幕精品网| 日韩美女毛茸茸| 亚洲国产精品99久久| 国产在线观看91精品一区| 在线精品国产成人综合| 日韩精品亚洲精品| 日韩在线中文字| 国产丝袜一区二区三区免费视频| 68精品国产免费久久久久久婷婷| 亚洲无线码在线一区观看| 亚洲精品美女免费| 日本高清久久天堂| 亚洲一区精品电影| 韩剧1988免费观看全集| 国产欧美亚洲精品| 国产精品网址在线| 亚洲第一视频在线观看| 亚洲精品99999| 91天堂在线视频| 国产在线视频不卡| 精品久久久国产| 夜夜嗨av一区二区三区四区| 午夜精品久久久久久久99热| 青青青国产精品一区二区| 国产精品久久久久久五月尺| 久久在线免费观看视频| 欧美激情精品久久久久久黑人| 日韩中文字幕视频在线| 91在线精品视频| 日本欧美中文字幕| 欧美精品久久久久久久免费观看| 欧美疯狂做受xxxx高潮| 亚洲一区二区三区乱码aⅴ蜜桃女| 国产专区精品视频| 91成人免费观看网站| 91精品久久久久久久久不口人| 精品久久久久久久中文字幕| 国产精品∨欧美精品v日韩精品| 中文欧美日本在线资源| 91精品久久久久久| 亚州欧美日韩中文视频| 亚洲国产欧美精品| 国产欧美在线视频| 91免费福利视频| 久久久999精品免费| 亚洲高清一二三区| 亚洲国产精品女人久久久| 中文字幕久热精品视频在线| 欧美区在线播放| 色一情一乱一区二区| 久久久中文字幕| 欧美国产日产韩国视频| 国产免费一区二区三区香蕉精| 精品久久久久久久久久ntr影视| 97婷婷涩涩精品一区| 欧洲亚洲在线视频| 日韩精品免费在线视频| 羞羞色国产精品| 91精品国产91久久| 欧美激情精品在线| 亚洲网在线观看| 日韩精品视频在线观看网址| 久久久国产精品视频| 亚洲第一精品久久忘忧草社区| 大伊人狠狠躁夜夜躁av一区| 亚洲欧洲国产伦综合| 亚洲国产天堂网精品网站| 欧美性xxxxhd| 色偷偷av一区二区三区| 亚洲免费一在线| www.久久色.com|