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. django中注册功能signup的测试例

    这个是套路, 有了这些测试用例, 开发就会更有保障, 且每次重写,都好麻烦, 不好cp来得快~~:) from django.test import TestCase from django.urls ...

  2. 【LOJ】#2513. 「BJOI2018」治疗之雨

    题解 具体就是列一个未知数方程\(dp[i]\)表示有\(i\)滴血的时候期望多少轮 \(dp[i] = 1 + \sum_{j = 1}^{i + 1} a_{i,j}dp[j]\) \(dp[n] ...

  3. select 详解

    In summary, a socket will be identified in a particular set when select returns if: readfds:If liste ...

  4. ref:web security最新学习资料收集

    ref:https://chybeta.github.io/2017/08/19/Web-Security-Learning/ ref:https://github.com/CHYbeta/Web-S ...

  5. codevs 1795 金字塔 2

    codevs 1795 金字塔 2这个题比完全背包多了一个总数的限制,即一定要选(m+n)个,题中说总重量不超过n,所以至少选择m个重量为0的,然后初始化的时候,都填成重量为0的,然后再一个个地把它们 ...

  6. 医学图像之DICOM格式解析

    最近导师给安排了新任务,由于刚进入实验室,对于医学图像这一块还一知半解,所以就想分享一下有关医学常见影像的学习(尤其是dicom后缀的图像文件),欢迎大家一起交流. 目录 1.医学影像学的介绍 2.D ...

  7. linux驱动之LCD(无framebuffer)

    <简介> a:什么是液晶 物质一般有三态,固态,气态,和液态.这只是一种比较大致的划分,但是有些物质介于液体和固体之间——液晶.一般固体的分子或原子都由固定的排列方式,但是液晶介于固体和液 ...

  8. Bzoj5251 线段树+贪心

    Bzoj5251 线段树+贪心 记录本蒟蒻省选后的第一篇题解!国际惯例的题面:首先这个东西显然是一棵树.如果我们把数值排序,并建立这棵树的dfs序,显然dfs序上的一个区间对应数值的一个区间,且根为数 ...

  9. BZOJ.3139.[HNOI2013]比赛(搜索 Hash)

    题目链接 不会搜索了.. DFS()中两个参数,枚举每两个队伍的比赛结果(分配当前队伍的分数). 可以发现方案数量与具体哪只球队得了多少分无关,只与当前比赛的队伍数量和得分序列的组成有关.可以记忆化搜 ...

  10. java基础学习总结——super关键字

    一.super关键字