總體博文已遷移到博客園:http://www.cnblogs.com/csqb-511612371/p/4891492.html html
其實需求很明確,就是一大堆不同的excel,每張excel對應數據庫的一張表,咱們須要提供用戶上傳excel,咱們解析數據入庫的功能實現。node
那麼,這就涉及到一個問題:咱們能夠讀出excel的表頭,可是怎麼知道每一個表頭具體對應數據庫裏面的字段呢?數據庫
博主通過一段時間的思考與構思,想到一法:如今的狀況是咱們有excel表A,對應數據庫表B,可是A與B具體屬性字段的映射關係咱們不知。那咱們是否是能夠有一個A到B的映射文件C呢?c#
我想,說到這,你們就很明瞭了...spa
第一步:爲每張excel建立一個與數據庫表對應的映射文件(xml配置文件),咱們稱之爲規則集,固然,咱們的需求是excel的列表頭不變(順序可換---緣由請繼續往下看)設計
<?xml version="1.0" encoding="utf-8" ?> <module> <add firstHeaderRow="5" lastHeaderRow="7" sheetCount="1" Supplementary="0" /> <add headerText="年份" propertyName="Year" dataType="System.Int32"/> <add headerText="國內生產總值" propertyName="GDPValue" dataType="System.double"/> <add headerText="第一產業" propertyName="PrimaryIndustryAmount" dataType="System.double"/> <add headerText="第二產業" propertyName="SecondaryIndustry_TotalAmount" dataType="System.double"/> <add headerText="工業" propertyName="SecondaryIndustry_Industry" dataType="System.double"/> <add headerText="建築業" propertyName="SecondaryIndustry_Construction" dataType="System.double"/> <add headerText="第三產業" propertyName="ThirdIndustryAmount" dataType="System.double"/> <add headerText="人均國內生產總值(元)" propertyName="GDPPerPerson" dataType="System.double"/> </module>
固然,這個xml文件因爲是咱們本身定義的節點,因此每一個單詞的意義就不詳細解釋了。excel
附:excel原表以下:code
其中【剔除行關鍵字】在後續詳細代碼中介紹,請繼續關注微博。xml
表頭含有層級結構,具體讀取方法也在後續詳細代碼中介紹...今天之講述設計思想與部分基礎代碼。htm
第二步:新建一個讀取咱們本身定義的xml文件的類 RegularXMLReaderService.cs:
public class RegularXMLReaderService : IRegularXMLReaderService { public List<Regular> GetXMLInfo(string xmlpath) { //xmlpath爲xml的路徑名稱 var reader = new XmlTextReader(xmlpath); var doc = new XmlDocument(); //從指定的XMLReader加載XML文檔 doc.Load(reader); var headerList = new List<Regular>(); foreach (XmlNode node in doc.DocumentElement.ChildNodes) { var header = new Regular(); if (node.Attributes["firstHeaderRow"] != null) header.HeaderRegular.Add("firstHeaderRow", int.Parse(node.Attributes["firstHeaderRow"].Value)); if (node.Attributes["lastHeaderRow"] != null) header.HeaderRegular.Add("lastHeaderRow", int.Parse(node.Attributes["lastHeaderRow"].Value)); if (node.Attributes["sheetCount"] != null) header.HeaderRegular.Add("sheetCount", int.Parse(node.Attributes["sheetCount"].Value)); if (node.Attributes["ExcelType"] != null) header.HeaderRegular.Add("ExcelType", int.Parse(node.Attributes["ExcelType"].Value)); if (node.Attributes["Supplementary"] != null) header.HeaderRegular.Add("Supplementary", int.Parse(node.Attributes["Supplementary"].Value)); if (node.Attributes["headerText"] != null) header.HeaderText = node.Attributes["headerText"].Value; if (node.Attributes["propertyName"] != null) header.PropertyName = node.Attributes["propertyName"].Value; if (node.Attributes["dataType"] != null) header.DataType = node.Attributes["dataType"].Value; headerList.Add(header); } return headerList; } }
這段代碼相信你們都能看懂,不作詳細解釋。其中設計到一個規則集類Regular.cs
/// <summary> /// 模板規則類 /// </summary> public class Regular { /// <summary> /// 表頭文本 --對應excel表頭名稱 /// </summary> public string HeaderText { set; get; } /// <summary> /// 屬性名稱 --對應數據庫字段名稱 /// </summary> public string PropertyName { set; get; } /// <summary> /// 數據類型 ---對應數據庫字段類型(用做判斷excel數據是否合法用) /// </summary> public string DataType { set; get; } private Dictionary<string, int> _regular = new Dictionary<string, int>(); /// <summary> /// 表頭規則 --咱們所定義的具體規則,如咱們文中例子的起始行、結束行、表單數等等 /// </summary> public Dictionary<string, int> HeaderRegular { get { return _regular; } set { _regular = value; } } }
這個類根據具體需求可能會有所不一樣,具體隨設計而改變。
第三步:建立一個解析excel數據的類(excel越多越複雜,實現就越困難),此處先假設已建好(詳細代碼請關注後續博客)
/// <summary> /// Excel表格檢查與數據讀取接口 /// </summary> public interface IExcelImportService { /// <summary> /// 初始化Excel數據及配置文件 /// </summary> /// <param name="filePath">Excel文件</param> /// <param name="xmlPath">配置文件</param> /// <param name="nullable">能夠爲空</param> void InitDataAndConfig(string filePath, string xmlPath, bool nullable); /// <summary> /// 綜合驗證Excel表格符合性 /// </summary> /// <param name="customValidate">某單元項自定義檢驗接口</param> /// <returns></returns> UploadExcelFileResult ValidateExcel(ISpecification<KeyValuePair<string, string>> customValidate); /// <summary> /// 導入EXCEL文件 /// </summary> /// <typeparam name="TableDTO">數據對象DTO</typeparam> /// <returns>EXCEL數據集合</returns> List<TableDTO> Import<TableDTO>(); /// <summary> /// 導入EXCEL 文件------矩陣類模板 /// 19.6-長江干線貨物流量流向 /// 20.5-西江航運幹線貨物流量流向 /// </summary> /// <typeparam name="TableDTO"></typeparam> /// <returns></returns> List<TableDTO> ImportForMatrix<TableDTO>(); }
此處是已建好的解析excel接口。(具體實現請參考後續博客)
博主的設計理念是:用戶上傳一個excel後咱們後臺分三步走:
一、初始化數據(excel文件流、對應配置文件--咱們的規則集xml文件、以及一些其餘的配置參數)
二、驗證excel裏面的數據合格(經過驗證表頭能夠斷定用戶是否錯誤上傳excel文件,驗證裏面數據是否違規(格式錯誤等)等等須要驗證的方面)。驗證成功後返回基礎表頭、附加信息等數據讓用戶確認並提交;失敗後提示具體失敗緣由,準肯定位到失敗數據行列數。
三、用戶看到驗證經過的返回結果,確認無誤後點擊提交,此時讀取數據入庫。
至此,咱們整個解析讀取入庫excel的流程就完成了,重在設計規則類這個設計思想,其中涉及到不少具體實現的代碼,請參考後續博客專題。
總體博文已遷移到博客園:http://www.cnblogs.com/csqb-511612371/p/4891492.html