哈哈~~~很高興還活着。總算加班加點的把最後一類EXCEL模板的解析作完了...html
前面幾篇文章介紹了博主最近項目中對於複雜excel表頭的解析,寫得很差,感謝園友們的支持~~~數據庫
今天再簡單講訴一下另外一種「變異」EXCEL表頭模板——矩陣表頭模板的解析(博主感受這種模板雖然說怪異,可是偶爾也能遇到,的確是有必定的實用性),咱們用一個流量流向的excel做爲例子來說解:app
先來解釋一下這個表頭:工具
一、「上表頭」看似複雜,按咱們前幾篇文章說到的XML配置規則集的方法,輕易就能解析spa
二、這個表頭「上表頭」、「左表頭」內容不定,行列數不定excel
我相信這種表頭仍是有必定價值的,值得作一個瞭解。code
因爲「上表頭」列不定,咱們就不能按常規的思想,以列爲數據庫字段來建表存儲。在建實體類時,博主偶然聯想到了大一高數(也不枉我考了90分)學到的矩陣,總感受很神似,因而乎就以「矩陣類EXCEL模板」命名之。xml
而後取變化的「上表頭」、「左表頭」爲屬性字段,最終新建實體類以下:htm
1 /// <summary> 2 /// XX年XX月西江航運幹線貨物流量流向 3 /// PS_XJ_VolumeAndDirection 4 /// </summary> 5 public class CargoFlowVolumeAndDirectionInXjItem : DataFoundationItem 6 { 7 /// <summary> 8 /// 該表項在表格中的索引位置 9 /// </summary> 10 public int Index { get; set; } 11 12 /// <summary> 13 /// 貨物重量(或同期比) 14 /// CargoWeight 15 /// </summary> 16 public double CargoWeight { get; set; } 17 18 /// <summary> 19 /// 出發航段、支流 20 /// LeavingPort 21 /// </summary> 22 public string LeavingSegment { get; set; } 23 24 /// <summary> 25 /// 到達航段、支流 26 /// ArrivingPort 27 /// </summary> 28 public string ArrivingSegment { get; set; } 29 }
固然,這麼存也不是3/5分鐘想出來的,只是偶發奇想。對象
很明顯,此次咱們須要重構的依然只是表頭解析方法GetExcelHeaders()和解析Excel數據的方法GetExcelDatas()。
咱們先來看錶頭,之前咱們是把列所有配置到XML文件做爲規則集,咱們此次作得再像矩陣一點,在XML規則集中配置「X軸」、「Y軸」分別用來表明「上表頭」、「左表頭」,再外加一個字段配置具體的值就OK:
1 <?xml version="1.0" encoding="utf-8" ?> 2 <module> 3 <add firstHeaderRow="5" lastHeaderRow="7" /> 4 <add headerText="Y軸" propertyName="LeavingSegment" dataType="System.String"/> 5 <add headerText="X軸" propertyName="ArrivingSegment" dataType="System.String"/> 6 <add headerText="值" propertyName="CargoWeight" dataType="System.double"/> 7 </module>
哈哈,有木有很簡潔的感受。
具體解析EXCEL表頭的方法在第三篇文章GetExcelHeaders():
http://www.cnblogs.com/csqb-511612371/p/4891492.html
咱們只須要把第42行-52行,規則集的驗證幹掉,此次咱們把表頭做爲一個「X軸」數據先存起來,那麼咱們就能獲得相似下面的表頭信息:
0,出發
1,到達總計
2,同期比(%)
3,幹線合計
4,肇慶
...
接下來就來重構咱們解析excel數據的方法GetExcelDatas(),在第三篇文章第7點。
咱們注意第26/27行,之前的模板咱們都是在這兒經過表頭與規則集匹配查找到相應DTO屬性進行賦值。
可是此次咱們的規則集中並未對錶頭進行配置(由於表頭內容不定),而是隻配置了「X軸」、「Y軸」與「值」,那麼咱們重構這兩行代碼:
1 // 產生一個新的泛型對象 2 var model = Activator.CreateInstance<TableDTO>(); 3 // 獲取第i行第一列值 4 string rowItem = dataRow.GetCell(0).ToString(); 5 if (rowItem == "") 6 { 7 break; 8 } 9 //添加Y軸值到DTO對象 10 Regular YHeader = list.Find(h => h.HeaderText == "Y軸"); 11 string YProperty = YHeader.PropertyName; 12 PropertyInfo YProp = model.GetType().GetProperty(YProperty); 13 YProp.SetValue(model, rowItem, null); 14 15 16 //添加X軸值到DTO對象 17 Regular XHeader = list.Find(h => h.HeaderText == "X軸"); 18 string XProperty = XHeader.PropertyName; 19 PropertyInfo XProp = model.GetType().GetProperty(XProperty); 20 XProp.SetValue(model, dict[j], null); 21 22 23 string value = ""; 24 Regular header = list.Find(h => h.HeaderText == "值"); 25 string property = header.PropertyName; 26 PropertyInfo prop = model.GetType().GetProperty(property);
注:
1.第四行咱們一直取第一列值,做爲Y軸,當咱們在循環X軸數據時,應當不變。
2.第20行,咱們上面說到,已經把當前「上表頭」所有存入到了表頭解析數據dict字典中,因此X軸只須要按索引取出「上表頭」值便可
3.而後第24行,咱們取出對單元格具體值的配置屬性,接下來就是之前的代碼獲取單元格值,反射賦值到該屬性中便可
重構到這一步,咱們已經基本完成了對「矩陣類EXCEL模板」的數據解析。咱們能夠預料返回的DTO集合數據將是:
1423.53 總計 到達總計
111.2 總計 同期比(%)
525.24 總計 幹線合計
......
111.2 同期比(%) 到達總計
0 同期比(%) 同期比(%)
130.7 同期比(%) 幹線合計
......
咱們只須要在DTO向實體作Mapper的時候,將Index屬性按從0開始遞加賦值便可。
至此,博主想分享的EXCEL操做系列就告一段落。
雖然還有一些更加複雜的excel(玫瑰圖等),可是博主感受都很小衆化,這輩子趕上一次就算倒黴的了,就再也不作方案分享了。
寫了六篇了,才感受總體文章命名很差,其實NPOI在博主的項目中只起到了一個操做EXCEL的開源工具做用,使用其餘開源組件能夠隨意替換它。
主要想介紹用XML搭橋作規則集的一種excel解析思想。
但願對您有所幫助。若有寫的不對很差的地方,請指出,必定虛心請假...
原創文章,代碼都是從本身項目裏貼出來的。轉載請註明出處哦,親~~~