import java.io.Serializable;

/**
* POI Excel报表导出,列合并实体<br>
*
* @author WQ
*
*/
public class PoiModel implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L; private String content; private String oldContent; private int rowIndex; private int cellIndex; public String getContent() {
return content;
} public void setContent(String content) {
this.content = content;
} public String getOldContent() {
return oldContent;
} public void setOldContent(String oldContent) {
this.oldContent = oldContent;
} public int getRowIndex() {
return rowIndex;
} public void setRowIndex(int rowIndex) {
this.rowIndex = rowIndex;
} public int getCellIndex() {
return cellIndex;
} public void setCellIndex(int cellIndex) {
this.cellIndex = cellIndex;
} public PoiModel() {
} public PoiModel(String content, String oldContent, int rowIndex,
int cellIndex) {
this.content = content;
this.oldContent = oldContent;
this.rowIndex = rowIndex;
this.cellIndex = cellIndex;
} @Override
public String toString() {
return "PoiModel [content=" + content + ", oldContent=" + oldContent
+ ", rowIndex=" + rowIndex + ", cellIndex=" + cellIndex + "]";
} }
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook; public class Demo { /**
* @param title 标题集合 tilte的长度应该与list中的model的属性个数一致
* @param maps 内容集合
* @param mergeIndex 合并单元格的列
*/
public static String createExcel(String[] title, Map<String, List<Map<String, String>>> maps, int[] mergeIndex){
if (title.length==0){
return null;
}
/*初始化excel模板*/
Workbook workbook = new XSSFWorkbook();
Sheet sheet = null;
int n = 0;
for(Map.Entry<String, List<Map<String, String>>> entry : maps.entrySet()){
try {
sheet = workbook.createSheet();
workbook.setSheetName(n, entry.getKey());
workbook.setSelectedTab(0);
}catch (Exception e){
e.printStackTrace();
}
/*初始化head,填值标题行(第一行)*/
Row row0 = sheet.createRow(0);
for(int i = 0; i<title.length; i++){
/*创建单元格,指定类型*/
Cell cell_1 = row0.createCell(i, Cell.CELL_TYPE_STRING);
cell_1.setCellValue(title[i]);
}
/*得到当前sheet下的数据集合*/
List<Map<String, String>> list = entry.getValue();
/*遍历该数据集合*/
List<PoiModel> poiModels = new ArrayList();
if(null!=workbook){
Iterator iterator = list.iterator();
int index = 1;
while (iterator.hasNext()){
Row row = sheet.createRow(index);
/*取得当前这行的map,该map中以key,value的形式存着这一行值*/
Map<String, String> map = (Map<String, String>)iterator.next();
/*循环列数,给当前行塞值*/
for(int i = 0; i<title.length; i++){
String old = "";
/*old存的是上一行统一位置的单元的值,第一行是最上一行了,所以从第二行开始记*/
if(index > 1){
old = poiModels.get(i)==null?"":poiModels.get(i).getContent();
}
/*循环需要合并的列*/
for(int j = 0; j < mergeIndex.length; j++){
if(index == 1){
/*记录第一行的开始行和开始列*/
PoiModel poiModel = new PoiModel();
poiModel.setOldContent(map.get(title[i]));
poiModel.setContent(map.get(title[i]));
poiModel.setRowIndex(1);
poiModel.setCellIndex(i);
poiModels.add(poiModel);
break;
}else if(i > 0 && mergeIndex[j] == i){/*这边i>0也是因为第一列已经是最前一列了,只能从第二列开始*/
/*当前同一列的内容与上一行同一列不同时,把那以上的合并, 或者在当前元素一样的情况下,前一列的元素并不一样,这种情况也合并*/
/*如果不需要考虑当前行与上一行内容相同,但是它们的前一列内容不一样则不合并的情况,把下面条件中
                  ||poiModels.get(i).getContent().equals(map.get(title[i])) && !poiModels.get(i - 1).getOldContent().equals(map.get(title[i-1]))去掉就行*/
if(!poiModels.get(i).getContent().equals(map.get(title[i])) || poiModels.get(i).getContent().equals(map.get(title[i]))
                    && !poiModels.get(i - 1).getOldContent().equals(map.get(title[i-1]))){
/*当前行的当前列与上一行的当前列的内容不一致时,则把当前行以上的合并*/
CellRangeAddress cra=new CellRangeAddress(poiModels.get(i).getRowIndex(), index - 1, poiModels.get(i).getCellIndex(), poiModels.get(i).getCellIndex());
//在sheet里增加合并单元格
sheet.addMergedRegion(cra);
/*重新记录该列的内容为当前内容,行标记改为当前行标记,列标记则为当前列*/
poiModels.get(i).setContent(map.get(title[i]));
poiModels.get(i).setRowIndex(index);
poiModels.get(i).setCellIndex(i);
}
}
/*处理第一列的情况*/
if(mergeIndex[j] == i && i == 0 && !poiModels.get(i).getContent().equals(map.get(title[i]))){
/*当前行的当前列与上一行的当前列的内容不一致时,则把当前行以上的合并*/
CellRangeAddress cra=new CellRangeAddress(poiModels.get(i).getRowIndex(), index - 1, poiModels.get(i).getCellIndex(), poiModels.get(i).getCellIndex());
//在sheet里增加合并单元格
sheet.addMergedRegion(cra);
/*重新记录该列的内容为当前内容,行标记改为当前行标记*/
poiModels.get(i).setContent(map.get(title[i]));
poiModels.get(i).setRowIndex(index);
poiModels.get(i).setCellIndex(i);
} /*最后一行没有后续的行与之比较,所有当到最后一行时则直接合并对应列的相同内容*/
if(mergeIndex[j] == i && index == list.size()){
CellRangeAddress cra=new CellRangeAddress(poiModels.get(i).getRowIndex(), index, poiModels.get(i).getCellIndex(), poiModels.get(i).getCellIndex());
//在sheet里增加合并单元格
sheet.addMergedRegion(cra);
}
}
Cell cell = row.createCell(i, Cell.CELL_TYPE_STRING);
cell.setCellValue(map.get(title[i]));
/*在每一个单元格处理完成后,把这个单元格内容设置为old内容*/
poiModels.get(i).setOldContent(old);
}
index++;
}
}
n++;
}
/*生成临时文件*/
FileOutputStream out = null;
String localPath = null;
File tempFile = null;
String fileName = String.valueOf(new Date().getTime()/1000);
try {
tempFile = File.createTempFile(fileName, ".xlsx");
localPath = tempFile.getAbsolutePath();
out = new FileOutputStream(localPath);
workbook.write(out);
}catch (IOException e){
e.printStackTrace();
}finally {
try {
out.flush();
out.close();
}catch (IOException e){
e.printStackTrace();
}
}
return localPath;
} public static void main(String[] args) throws IOException{
/*此处标题的数组则对应excel的标题*/
String[] title = {"id","标题","描述","负责人","开始时间"};
List<Map<String, String>> list = new ArrayList();
/*这边是制造一些数据,注意每个list中map的key要和标题数组中的元素一致*/
for(int i = 0; i<10; i++){
HashMap<String, String> map = new HashMap();
if(i > 5){
if(i<7){
map.put("id","333");
map.put("标题","mmmm");
}else {
map.put("id","333");
map.put("标题","aaaaa");
}
}else if (i >3){
map.put("id","222");
map.put("标题","哈哈哈哈");
}else if (i>1 && i<3){
map.put("id","222");
map.put("标题","hhhhhhhh");
}else {
map.put("id","222");
map.put("标题","bbbb");
}
map.put("描述","sssssss");
map.put("负责人","vvvvv");
map.put("开始时间","2017-02-27 11:20:26");
list.add(map);
}
Map<String, List<Map<String, String>>> map = new HashMap();
map.put("测试合并数据", list);
System.out.println(createExcel(title, map, new int[]{0,1,2}));
} }

思路:

后来就通过建一个单元格对象,属性有单元格内容,与单元格同一列的上一行内容,起始行,起始列,就这四个属性

生成的文件效果(两种情况的):

 
 

POI Excel 合并数据相同的行的更多相关文章

  1. poi excel 合并单元格

    结论:final CellRangeAddress cra = new CellRangeAddress(rowId, rowId + rowSkip,        colId, colId + c ...

  2. java中使用POI+excel 实现数据的批量导入和导出

    java web中使用POI实现excel文件的导入和导出 文件导出 //导入excle表 public String exportXls() throws IOException{ //1.查询所有 ...

  3. Excel大数据排查重复行内容方法,三步搞定!

    首先第一步,我们找到一个空白列D输入公式“=A1&B1&C1”: 然后第二步,再选择下一空白列输入公式“=IF(COUNTIF(D:D,D1)>1,"重复", ...

  4. VC6.0读取Excel文件数据

    啰嗦一下:本人所在公司从事碟式斯特林太阳能发电设备的研发与销售.单台设备图如下: 工作原理如下:整个设备大致可分为五个部分, 1.服务器,负责气象.发电等数据存取,电.网连接等处理: 2.气象站,通过 ...

  5. poi导出excel合并单元格(包括列合并、行合并)

    1 工程所需jar包如下:commons-codec-1.5.jarcommons-logging-1.1.jarlog4j-1.2.13.jarjunit-3.8.1.jarpoi-3.9-2012 ...

  6. 使用poi读取Excel文件数据

    package com.haiyisoft.iecp.util; import java.io.File;import java.io.FileInputStream;import java.io.F ...

  7. POI实现excel的数据验证

    目录 前言 难点1:合并单元格 代码实现策略: step 1: 合并单元格 step 2: 给单元格赋值 难点2:数据验证-下拉框 代码实现策略: step 1:设置需要进行数据验证的单元格范围和可供 ...

  8. 项目一:第四天 1、快递员的条件分页查询-noSession,条件查询 2、快递员删除(逻辑删除) 3、基于Apache POI实现批量导入区域数据 a)Jquery OCUpload上传文件插件使用 b)Apache POI读取excel文件数据

    1. 快递员的条件分页查询-noSession,条件查询 2. 快递员删除(逻辑删除) 3. 基于Apache POI实现批量导入区域数据 a) Jquery OCUpload上传文件插件使用 b) ...

  9. 游标、获取本地本地多个文件、Excel数据导入、跨服务器数据拷贝、行转列示例

    )='C:\Users\Administrator\Desktop\待处理数据\顺江学校4\' ---------------------------------------------------- ...

随机推荐

  1. Ubuntu服务器上相关软件或应用时常打不开的问题

    于接触linux系统时间不就,所以在操作上难免会出现失误,以下两个问题就是近期经常出现的问题,具体如下: 1.ubuntu服务器上的浏览器时常打不开. 2.安装的pycharm和系统自带的pychar ...

  2. CentOS 7 之 Docker 安装及操作命令

    Docker 安装 官方网站上有各种环境下的安装指南,比如:CentOS.Ubuntu 和 Debian 系列的安装. 而我们现在主要介绍的是基于 CentOS 7.x 上面的安装. 1.查看是否已经 ...

  3. spark streaming的容错:防止数据丢失

    官方这么说的 [Since Spark 1.2] Configuring write ahead logs - Since Spark 1.2, we have introduced write ah ...

  4. 032 Spark容错特性

    1.spark容错主要分为两个方面 其一是集群 再者为spark的应用程序. 2.Driver 重要补充: driver宕机: Spark On Yarn:总之,要重启 client:只能重启job ...

  5. ES8之async/await学习随笔

    详细学习参考文档: 阮一峰老师的博客,覆盖知识点ES6/7/8/9,本篇学习笔记对阮老师的关于async/await文档中的知识点进行分点总结 在ES8中加入async/await新特性后,很明显带来 ...

  6. JavaWeb快速入门

    孙卫琴老师的javaweb一书已经买了很多年,由于很厚一直也没有去好好阅读下, 项目发布后有闲暇时间,决定快速学习了,毕竟很多概念和知识主要还是复习. 对于互联网,我们可以简单认为浏览器就是会人类语言 ...

  7. .NET工作准备--03进阶知识

    (已过时) 高级特性,多线程编程,单元测试; 第一部分 .net高级特性 1.委托:提供安全的函数回调机制; *基本原理:与C++中的函数指针相似;安全--它和其他所有.net成员一样是一种类型,任何 ...

  8. java微信公众号JSAPI支付以及所遇到的坑

    上周做了个支付宝微信扫码支付,今天总结一下.微信相比支付宝要麻烦许多 由于涉及到代理商,没办法,让我写个详细的申请流程,懵逼啊. 笔记地址 http://note.youdao.com/notesha ...

  9. 每日踩坑 2018-12-25 【Unable to convert MySQL date/time value to System.DateTime】异常

    之前的公司一直是用 ORM ,所以底层的事情完全不用在意, 到了这家全是似乎全是 SQL 硬编码 所以也有机会重新去补补以前也没怎么写过的基本 ADO. 不过这两天总有自己写个简易ORM的想法在蠢蠢欲 ...

  10. [JZOJ4786]小a的强迫症

    [JZOJ4786]小a的强迫症 题目大意: 有\(n(n\le10^5)\)种颜色的珠子,第\(i\)种颜色有\(num[i]\)个.你要把这些珠子排成一排,使得第\(i\)种颜色的最后一个珠子一定 ...