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

     

    希望对您有所帮助。如有写的不对不好的地方,请指出,一定虚心请假...

     

    原创文章,代码都是从自己项目里贴出来的。转载请注明出处哦,亲~~~

  • 相关阅读:
    软件项目技术点(2)——Canvas之坐标系转换
    软件项目技术点(2)——Canvas之平移translate、旋转rotate、缩放scale
    用html5的canvas和JavaScript创建一个绘图程序
    javascript学习之BOM
    HTML5 之拖放(drag与drop)
    fluent-ffmpeg 常用函数
    ffmpeg用法及如何使用fluent-ffmpeg
    解决js动态改变dom元素属性后页面及时渲染问题
    软件项目技术点(8)—— canvas调用drawImage绘制图片
    Oracle数据库rownum用法集锦
  • 原文地址:https://www.cnblogs.com/csqb-511612371/p/4912002.html
Copyright © 2020-2023  润新知