Npoi--合并单元格
一、缘由。
最近公司的一个需求,导出 Excel, 相同的数据进行合并,并且 还有 二级合并。
最终效果图如下:
哈哈哈哈哈,图表略微有些丑陋,请大家不要介意。
他的原始数据,是一条一条的,
如下图:
二、导出 处理 逻辑。
try
{
int propertyCount = getPropertyCount(typeof(T)); var hssfWorkbook = new XSSFWorkbook();
var sheet1 = hssfWorkbook.CreateSheet(sheetName); var row1 = (XSSFRow)sheet1.CreateRow();
//表头样式
var rowstyle = hssfWorkbook.CreateCellStyle();
rowstyle.Alignment = HorizontalAlignment.Center;
//rowstyle.FillBackgroundColor = HSSFColor.Grey25Percent.Index;
var font1 = hssfWorkbook.CreateFont(); font1.FontHeight = ;
//font1.Boldweight = 600;
rowstyle.SetFont(font1); font1.FontHeightInPoints = ;
font1.Boldweight = ; WriteHeader(typeof(T), row1, rowstyle); int i = ;
for (int j = ; j < listData.Count; j++)
{
int rowIndex = i;
var rowData = (XSSFRow)sheet1.CreateRow(rowIndex + );
WriteData(listData[j], typeof(T), rowData);
i++;
} setAutoColumn(sheet1, i);
//sheet1 就是 在内存中 填充好的 Excel数据。下面合并要用到 ///////
///////这里 放置 合并方法。
///////第 0 列 合并。
mergeuser(sheet1,0);
var rowfooter = (XSSFRow)sheet1.CreateRow(i + );
//NpoiMemoryStream 是 重写Npoi流方法
using (NpoiMemoryStream ms = new NpoiMemoryStream())
{
ms.AllowClose = false;
hssfWorkbook.Write(ms);
ms.Flush();
ms.Position = ;
hssfWorkbook = null;
return ms;
}
}
catch (Exception ex)
{
throw ex;
}
重写 Npoi流。
/// <summary>
/// 重写Npoi流方法
/// </summary>
public class NpoiMemoryStream : MemoryStream
{
public NpoiMemoryStream()
{
AllowClose = true;
}
public bool AllowClose { get; set; } /// <summary>
/// 关闭
/// </summary>
public override void Close()
{
if (AllowClose)
base.Close();
}
}
合并 单元格 方法。
private static void mergeuser(ISheet sheet, int columnIndex)
{
//开始 要合并的内容为空
var previous = "";
//startRow 是你Excel 数据是 第几行开始的
var startRow = ;
for (int rowNum = ; rowNum <= sheet.LastRowNum; rowNum++)
{
//获取 指定行,指定列的 数据内容
var current = sheet.GetRow(rowNum).GetCell(columnIndex).StringCellValue;
// 判断 获取到的内容是否和 上一列 相等
if (current.Equals(previous))
{continue;}
else
{
// 第一级 合并。
//将获取到的 内容 赋值到 previous
previous = current;
// 判断开始行,是否小于 循环的行数。
if (startRow < rowNum)
{
//第二级 合并
var celltext = "";
var startAM = startRow;
for (int i = startRow; i <= rowNum; i++)
{
var endtext = sheet.GetRow(i).GetCell().StringCellValue;
if (celltext.Equals(endtext))
{ continue; }
else
{
celltext = endtext;
if (startAM < i)
{
// CellRangeAddress(起始行号,终止行号, 起始列号,终止列号)
//这里 终止行号 -1 原因是:上面循环判断时 内容不一样的 才进行 合并,
//这时 行数 i 内容 已经不一样,所以 需要减去 1 进行合并 sheet.AddMergedRegion(new CellRangeAddress(startAM, i - , columnIndex + , columnIndex + ));
}
// 将 当前行数,进行赋值给 启始行数。
startAM = i;
}
}
sheet.AddMergedRegion(new CellRangeAddress(startRow, rowNum - , columnIndex, columnIndex));
}
startRow = rowNum;
}
}
}
至此 ,合并结束。
小记:
合并时 ,最好是在 添加内容 到 sheet 里面时,进行合并,这样的话,减少了 一次 循环所有数据的操作,提高了 速度问题。
以上,如果 有好的建议 欢迎 指正。
Npoi--合并单元格的更多相关文章
- NPOI操作EXCEL(五)——含合并单元格复杂表头的EXCEL解析
我们在第三篇文章中谈到了那些非常反人类的excel模板,博主为了养家糊口,也玩命做出了相应的解析方法... 我们先来看看第一类复杂表头: ...... 博主称这类excel模板为略复杂表头模板(蓝色部 ...
- NPOI之Excel——合并单元格、设置样式、输入公式
首先建立一个空白的工作簿用作测试,并在其中建立空白工作表,在表中建立空白行,在行中建立单元格,并填入内容: //建立空白工作簿 IWorkbook workbook = new HSSFWorkboo ...
- NPOI扩展--判断指定单元格是否为合并单元格和输出该单元格的行列跨度(维度)
因工作需要用到跨合并单元格获取数据,所以写了个NPOI扩展类. 主要方法如下: 1.判断指定行/列索引(单元格)是否为合并单元格. 2.获取指定列索引的实际含有数据的单元格. 3.返回指定行/列索引的 ...
- NPOI之Excel——合并单元格、设置样式、输入公式、设置筛选等
首先建立一个空白的工作簿用作测试,并在其中建立空白工作表,在表中建立空白行,在行中建立单元格,并填入内容: //建立空白工作簿 IWorkbook workbook = new HSSFWorkboo ...
- 用NPOI创建Excel、合并单元格、设置单元格样式、边框的方法
本篇文章小编为大家介绍,用NPOI创建Excel.合并单元格.设置单元格样式.边框的方法.需要的朋友参考下 今天在做项目中,遇到使用代码生成具有一定样式的Excel,找了很多资料,最后终于解决了,Ex ...
- 在Asp.Net MVC中使用NPOI插件实现对Excel的操作(导入,导出,合并单元格,设置样式,输入公式)
前言 NPOI 是 POI 项目的.NET版本,它不使用 Office COM 组件,不需要安装 Microsoft Office,目前支持 Office 2003 和 2007 版本. 1.整个Ex ...
- C# 如何使用NPOI操作Excel以及读取合并单元格等
C#操作Excel方法有很多,以前用的需要电脑安装office才能用,但因为版权问题公司不允许安装office.所以改用NPOI进行Excel操作,基本上一些简单的Excel操作都没有问题,读写合并单 ...
- npoi导出excel合并单元格
需要引用NPOI.dll程序集和Ionic.Zip.dll程序集 string[] headerRowName = { "序号", "地市", "镇街 ...
- 使用npoi导入Excel - 带合并单元格--附代码
之前我们在使用npoi导入excel表格的时候,往往会遇见那种带有合并单元格的数据在导入的时候出现合并为空的问题, 也就是只有第一条有数据,其余均为空白.在网上翻了半天也没有找到合适的解决方案,最后还 ...
- C# NPOI Excel 合并单元格和取消单元格
1.合并单元操作 //合并单元格 /** 第一个参数:从第几行开始合并 第二个参数:到第几行结束合并 第三个参数:从第几列开始合并 第四个参数:到第几列结束合并 **/ CellRangeAddres ...
随机推荐
- Quartz实现JAVA定时任务的动态配置
什么是动态配置定时任务? 首先说下这次主题,动态配置.没接触过定时任务的同学可以先看下此篇:JAVA定时任务实现的几种方式 定时任务实现方式千人千种,不过基础的无外乎 1.JDK 的Timer类 2. ...
- django-渲染页面+locals
from django.shortcuts import render, redirect from django.views import View from django.http import ...
- VLC播放RTSP视频延迟问题 (转)
原帖地址:http://blog.chinaunix.net/uid-26611383-id-3755283.html ======================================== ...
- LUA表与函数的深入理解
local heroInfo = {} --直接打印 table的名字,就会输出该table的内存地址 print("表地址---------------",heroInfo) - ...
- 新手C#属性set,get的学习(部分转)2018.08.06
public class person { public string name; } public class person { public string Name { set; get; } } ...
- Unity加载二进制数据
[Unity加载二进制数据] The first step is to save your binary data file with the ".bytes" extension ...
- 59. Spiral Matrix II (Array)
Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. For ...
- JS 将json数组转为嵌套层级数组
ele UI 的树级菜单的数据要求是这种嵌套的,但是Ztree的老用发的是 var zNodes =[ { id:, pId:, name:"zTree Home", pid:0} ...
- Division of Line Segment
Division of Line Segment /** */ void Line::EqualDivision(int nCount, QLineF fline, QList<QPointF& ...
- 74款安卓和IOS app源码地址
知乎专栏App https://github.com/bxbxbai/ZhuanLan WeChat高仿微信 项目地址: https://github.com/motianhuo/wechat Gan ...