NPOI操作EXCEL(六)——矩陣類表頭EXCEL模板的解析


哈哈~~~很高興還活着。總算加班加點的把最后一類EXCEL模板的解析做完了...

 

前面幾篇文章介紹了博主最近項目中對於復雜excel表頭的解析,寫得不好,感謝園友們的支持~~~

 

今天再簡單講訴一下另一種“變異”EXCEL表頭模板——矩陣表頭模板的解析(博主感覺這種模板雖說怪異,但是偶爾也能遇到,的確是有一定的實用性),我們用一個流量流向的excel作為例子來講解:

 

先來解釋一下這個表頭:

1、“上表頭”看似復雜,按我們前幾篇文章說到的XML配置規則集的方法,輕易就能解析

2、這個表頭“上表頭”、“左表頭”內容不定,行列數不定

 

我相信這種表頭還是有一定價值的,值得做一個了解。

由於“上表頭”列不定,我們就不能按常規的思想,以列為數據庫字段來建表存儲。在建實體類時,博主偶然聯想到了大一高數(也不枉我考了90分)學到的矩陣,總感覺很神似,於是乎就以“矩陣類EXCEL模板”命名之。

然后取變化的“上表頭”、“左表頭”為屬性字段,最終新建實體類如下:

 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解析思想。

 

希望對您有所幫助。如有寫的不對不好的地方,請指出,一定虛心請假...

 

原創文章,代碼都是從自己項目里貼出來的。轉載請注明出處哦,親~~~


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com