zoukankan      html  css  js  c++  java
  • 时隔两年再次操刀NPOI合并单元格

      一:前言

        时隔两年再次操刀对象NPOI的合并单元格。廉颇老矣尚能饭否,NPOI小小插件大大能量,黄口小儿,唧唧呱呱。

        NPOI相对与以前来说两年有了一点儿小的进步,去识别泛型。更简易的代码书写方式,更多的去思考,去实践。想两年前,初出江湖。大山一座座。连最基本的api都不能看懂,一波三折,觉得其难之又难。

      二:反射和泛型实现ListToDataTable和获取特性定义的文字做列头,废话少说点,上代码

      由于本人是写的Demo就用的类库,所以这里的特性继承的是FlagsAttribute(其实他也是继承自Attribute),这是一个简单的列名的特性,方便数据填充

     [AttributeUsage(AttributeTargets.Property, Inherited = true)]
        public class EnitityAttribute: FlagsAttribute
        {
    
            private string columnName;
            /// <summary>
            /// 列名
            /// </summary>
            public string ColumnName
            {
                get { return columnName; }
                set { columnName = value; }
            }
        }
    View Code

      三:ListToDataTable(感觉Table才是NPOI的绝配吧)

        /// <summary>
            /// 讲list集合转换成datatable
            /// </summary>
            /// <param name="list"></param>
            /// <returns></returns>
            public static DataTable ListToDataTable(IList list)
            {
                DataTable result = new System.Data.DataTable();
                if (list.Count > 0)
                {
                    PropertyInfo[] propertys = list[0].GetType().GetProperties();
                    foreach (PropertyInfo pi in propertys)
                    {
                        //获取类型
                        Type colType = pi.PropertyType;
                        //当类型为Nullable<>时
                        if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>)))
                        {
                            colType = colType.GetGenericArguments()[0];
                        }
                        //判断是否含有EnitityAttribute
                        if (pi.IsDefined(typeof(EnitityAttribute),true))
                        {
                            //获取EnitityAttribute所对应的ColumnName值
                            var objecet = pi.GetCustomAttribute(typeof(EnitityAttribute), true);
                            EnitityAttribute attr = objecet as EnitityAttribute;
                            result.Columns.Add(attr.ColumnName, colType);
                        }
                        else
                        {
                            result.Columns.Add(pi.Name, colType);
                        }
    
                      
                    }
                    for (int i = 0; i < list.Count; i++)
                    {
                        ArrayList tempList = new ArrayList();
                        foreach (PropertyInfo pi in propertys)
                        {
                            object obj = pi.GetValue(list[i], null);
                            tempList.Add(obj);
                        }
                        object[] array = tempList.ToArray();
                        result.LoadDataRow(array, true);
                    }
                }
                return result;
            }
    View Code

      四:去实现单元格的合并

      

                HSSFWorkbook book = new HSSFWorkbook();
                NPOI.SS.UserModel.ISheet sheet = book.CreateSheet("Sheet1");
                NPOI.SS.UserModel.IRow headerrow = sheet.CreateRow(0);
                ICellStyle style = book.CreateCellStyle();
                style.Alignment = HorizontalAlignment.Center;
                style.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.DarkTeal.Index;
                var font = book.CreateFont();
                font.FontHeightInPoints = 10;
                font.IsBold = true;
                style.SetFont(font);
                //添加列名
                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    ICell cell = headerrow.CreateCell(i);
                    
                    cell.SetCellValue(dt.Columns[i].ColumnName);
                    cell.CellStyle = style;
    
                }
    
    
    
                //添加第一行数据
                IRow row = sheet.CreateRow(1);
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    string cellText = dt.Rows[0][j].ToString();
                    if (!string.IsNullOrWhiteSpace(cellText))
                        row.CreateCell(j).SetCellValue(cellText);
                    else row.CreateCell(j).SetCellValue("-");
    
    
                }
                //从第二行开始循环,和上一行进行判断,如果相同,则合并
                for (int i = 1; i < dt.Rows.Count; i++)
                {
                    row = sheet.CreateRow(i + 1);
                    for (int j = 0; j < dt.Columns.Count; j++)
                    {
                        string cellText = dt.Rows[i][j].ToString();
                        if (!string.IsNullOrWhiteSpace(cellText))
                            row.CreateCell(j).SetCellValue(cellText);
                        else row.CreateCell(j).SetCellValue("-");
                    }
                }
    
    
                //合并单元格样式
                ICellStyle cellstyle = book.CreateCellStyle();
                cellstyle.VerticalAlignment = VerticalAlignment.Center;
                cellstyle.Alignment = HorizontalAlignment.Center;
    
    
                //合并行
                //总计单元行数
                int count = dt.Rows.Count+1;
                for (int k = 0; k < dt.Columns.Count; k++)
                {
                    for (int i = 1; i < count; i++)
                    {
                        //获取当前行第0列
                        string value = sheet.GetRow(i).GetCell(k).StringCellValue;
    
                        int end = i;
                        //找到结束为止
                        for (int j = i + 1; j < count; j++)
                        {
                            //获取下一行行第0列
                            string value1 = sheet.GetRow(j).GetCell(k).StringCellValue;
    
                            if (value != value1)
                            {
                                end = j - 1;
                                break;
                            }
                            else if (value == value1 || j == dt.Rows.Count)
                            {
                                if (!string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(value1) && !value.Equals("-") && !value1.Equals("-"))
                                {
                                    end = j;
                                }
                            }
                        }
                        if (i != end)
                        {
                            sheet.AddMergedRegion(new CellRangeAddress(i, end, k, k));//和并单元格
                        }
                        var cell = sheet.GetRow(i).GetCell(k);
                        cell.CellStyle = cellstyle;
                        i = end;
                    }
                }
    
                style.Alignment = HorizontalAlignment.Center;
                style.VerticalAlignment = VerticalAlignment.Center;
                FileStream fileStream = new FileStream($"D:\{title}.xls", FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite);
    
                book.Write(fileStream);
              
                fileStream.Close();
    View Code

    基本上照着抄就应该可以实现了。少Copy多写代码

  • 相关阅读:
    net事件丢失解决方法
    Google排名经验谈
    动力漏洞
    Understand简明参考
    修复iReaper
    Bootstrap源码分析
    UTF8编码字节流错误小析
    OAuth2学习及DotNetOpenAuth部分源码研究
    DynamicModuleUtility对象在.net不同版本下的兼容性问题
    MediaWiKi简明安装与配置笔记
  • 原文地址:https://www.cnblogs.com/geekX/p/15061237.html
Copyright © 2011-2022 走看看