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;}@Overridepublic 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. excel拆分数据如何按行拆分

    今天跟大家分享一下excel拆分数据如何按行拆分 1.首先我们打开演示文件 2.然后点击下图选项 3.点击[汇总拆分] 4.选择[拆分工作表] 5.点击[按行数拆分],然后将[表头行数]设置为2 6. ...

  2. Excel合并数据查找函数VLOOKUP()一直显示最后一行数据或者一直报错的解决方法

    Excel合并数据查找函数VLOOKUP()一直显示最后一行数据或者一直报错的解决方法 大家好,我叫亓官劼(qí guān jié ),在CSDN中记录学习的点滴历程,时光荏苒,未来可期,加油~博客地 ...

  3. 【Java】poi | excel | 合并单元格

    一.说明 1.maven项目 2.基于ruoyi-fast 二.解决方案 1.合并行 需求:合并第一行和第二行 解决: CellRangeAddress region = new CellRangeA ...

  4. 批量提取合并EXCEL表格数据 从特定行开始(去表头合并)

    OFFICE excel功能着实强大 遇到一大批三调数据需要处理,近100个Excel表格需要合并,导入数据库. 终于在百度各大神的方法下找到了解决方法 1将所有要合并的表格汇总至一个新的文件夹中 2 ...

  5. 使用poi在根据Excel中数据在每行生成折线统计图

    1.加入依赖 poi-4.1.2.jar poi-ooxml-4.1.2.jarpoi-ooxml-schemas-4.1.2.jar 2.读取excel中每行的数据,使用LinkedHashMap& ...

  6. java poi excel合并单元格 相同的列以及在有父级约束条件下合并二级列

    import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.util.CellRangeAddress;public clas ...

  7. POI Excel 如何插入新的行?

    使用shifRows方法,第1个参数是指要开始插入的行,第2个参数是结尾行数 HSSFSheet sheet = workbook.getSheetAt(0); sheet.shiftRows(12, ...

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

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

  9. php表格增加一行数据,““vb中数据库内容输出到excel如何把表格第一行合并添加一个大标题...

    excel表格上面和下面都有行怎么在中间添加一行 excel表面和下面都有行怎么在中间添加一行的方法如下: 1.打开要处理的文档, 2.标定位到要插入的位置之后,比如要在2,3行之间插入,就定位到第3 ...

最新文章

  1. VS Code配置PHP XDebug
  2. 一行代码解决IFrame自适应高度问题
  3. Devexpress GridControl中 repositoryItemCheckEdit作为选择列以及作为显示列的使用方法
  4. IAP的原理和stm8的IAP
  5. 数据中心空调系统一种变风量节能控制策略
  6. 转:“401 - 未授权:由于凭据无效,访问被拒绝”在iis的解决办法
  7. 程序员面试金典适合java么,【程序员面试金典】面试题 01.03. URL化(示例代码)
  8. 加拿大大数据:正在升温的大数据市场
  9. a标签跳转后返回原页面 layui_layui页面操作,点击一个添加页面,跳转有确定,然后点击确定后将选择的几个数据返回前一个页面获取值,然后ajax请求后台...
  10. axure命令行_axure怎么做计算器
  11. 120个常用货源网站,赶紧收藏!
  12. 什么是黑盒测试,白盒测试,灰盒测试?
  13. 笔记本电脑桌面的计算机图标不见了,笔记本电脑桌面显示没了怎么办呢
  14. 如何使用 Python 将 Nifti 文件转换为 Dicom 系列
  15. [转]《财富》推荐的75本必读书 !!推荐看看!受益匪浅
  16. 三阶魔方没有。四阶魔方 有的公式
  17. LeetCode Day01:一年中的第几天
  18. 3dmax2014【3dsmax2014】官方简体中文(64位)安装图文教程、破解注册方法
  19. 京东JDK在大数据平台的探索与研究
  20. 笑谈贝叶斯网络(干货)上

热门文章

  1. 离散数学及其应用怎么样_有名气的冲击式移动破碎站效果怎么样?
  2. 顶岗实习周记java方向_会计学院顺利召开2021届毕业生顶岗实习动员大会
  3. python字符串_python的字符串怎么拼接
  4. python如何读取tfrecord_tensorflow读取tfrecords格式文件
  5. python AES加密解密
  6. python读取data_Python批处理数据读取方法的细节:dataloader,Pytorch,批量,详解,DataLoader...
  7. java case 语句_ECMAScript switch 语句
  8. python string.format(),Python string.format()百分比,不取整
  9. matlab中circle函数_JavaScript碎片——函数闭包(模拟面向对象)
  10. Vue中子组件如何向父组件传递数据?