概述
近日项目中提出需求,需要导出Excel,最开始以为很简单,也没说明需要合并相同内容的行,于是偷个懒,使用原来写好的工具类直接导出。写好后以为okay了,结果,竟然又提供了另一个版本的模板,需要合并内容相同的列,麻烦来了,于是网上各种搜寻,最后找到一个例子,效果是我想要的,感谢大神的贡献,附上链接如下:
https://blog.csdn.net/qq_33142257/article/details/64929145
于是取下来先看看效果,然后再这基础上自己改进了一下做出了自己想要的效果,如下:
记录一下,以后备用
首先在maven工程的pom.xml文件中添加
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.14</version>
</dependency>
package com.test.testexcel;
public class PoiModel {
private String content;
private String oldContent;
private int rowIndex;
private int cellIndex;
public String getOldContent() {
return oldContent;
}
public void setOldContent(String oldContent) {
this.oldContent = oldContent;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
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;
}
}
package com.test.testexcel;
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;
import com.test.testexcel.PoiModel;
public class Test {
/**
* @param headers 标题集合 tilte的长度应该与list中的model的属性个数一致
* @param dataset 内容集合
* @param mergeColumns 合并单元格的列
*/
public static String createExcel(String[] headers, List<Map<String, String>> dataset, String[] mergeColumns) {
if (headers.length==0){
return null;
}
/*初始化excel模板*/
Workbook workbook = new XSSFWorkbook();
Sheet sheet = null;
try {
sheet = workbook.createSheet();
}catch (Exception e){
e.printStackTrace();
}
/*初始化head,填值标题行(第一行)*/
Row row0 = sheet.createRow(0);
for(int i = 0; i < headers.length; i++){
/*创建单元格,指定类型*/
Cell cell_1 = row0.createCell(i, Cell.CELL_TYPE_STRING);
cell_1.setCellValue(headers[i]);
}
List<PoiModel> poiModels = new ArrayList<PoiModel>();
Iterator<Map<String, String>> iterator = dataset.iterator();
int index = 1; //这里1是从excel的第二行开始,第一行已经塞入标题了
while (iterator.hasNext()){
Row row = sheet.createRow(index);
// 取得当前这行的map,该map中以key,value的形式存着这一行值
Map<String, String> map = iterator.next();
// 循环列数,给当前行塞值
for(int i = 0; i < headers.length; i++) {
String old = "";
// old存的是上一行统一位置的单元的值,第一行是最上一行了,所以从第二行开始记
if(index > 1) {
old = poiModels.get(i) == null ? "" : poiModels.get(i).getContent();
}
String value = map.get(headers[i]);
CellRangeAddress cra = null;
// 循环需要合并的列
for(int j = 0; j < mergeColumns.length; j++){
PoiModel poiModel = null;
if(index == 1) {
poiModel = new PoiModel();
poiModel.setOldContent(value);
poiModel.setContent(value);
poiModel.setRowIndex(1);
poiModel.setCellIndex(i);
poiModels.add(poiModel);
old = value;
break;
}
poiModel = poiModels.get(i);
int rowStartIndex = poiModel.getRowIndex();
int rowEndIndex = index - 1;
int cellIndex = poiModel.getCellIndex();
String content = poiModel.getContent();
String preOldContent = poiModels.get(0).getOldContent();
String preValue = map.get(headers[0]);
Boolean isHeaderEquals = mergeColumns[j].equals(headers[i]);
if(i == 0 && isHeaderEquals && !content.equals(value)) {
if (rowStartIndex != rowEndIndex) {
cra=new CellRangeAddress(rowStartIndex, rowEndIndex, cellIndex, cellIndex);
sheet.addMergedRegion(cra);
}
// 重新记录该列的内容为当前内容,行标记改为当前行标记
poiModel.setContent(value);
poiModel.setRowIndex(index);
poiModel.setCellIndex(i);
} else if (i > 0 && isHeaderEquals) {
if(!content.equals(value) || (content.equals(value) && !preOldContent.equals(preValue))) {
if (rowStartIndex != rowEndIndex) {
cra = new CellRangeAddress(rowStartIndex, rowEndIndex, cellIndex, cellIndex);
sheet.addMergedRegion(cra);
}
poiModels.get(i).setContent(value);
poiModels.get(i).setRowIndex(index);
poiModels.get(i).setCellIndex(i);
}
}
if(isHeaderEquals && index == dataset.size()) {
if (i == 0) {
if (content.equals(value)) {
cra = new CellRangeAddress(rowStartIndex, index, cellIndex, cellIndex);
sheet.addMergedRegion(cra);
}
} else if (i > 0) {
if (content.equals(value) && preOldContent.equals(preValue)) {
cra = new CellRangeAddress(rowStartIndex, index, cellIndex, cellIndex);
sheet.addMergedRegion(cra);
}
}
}
}
Cell cell = row.createCell(i, Cell.CELL_TYPE_STRING);
cell.setCellValue(value);
// 在每一个单元格处理完成后,把这个单元格内容设置为old内容
poiModels.get(i).setOldContent(old);
}
index++;
}
/*生成临时文件*/
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{
String[] headers = {"单位名称", "IP", "IP分类", "危险程度"};
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
Map<String, String> map = new HashMap<String, String>();
map.put("单位名称","test");
map.put("IP","10.130.138.96");
map.put("IP分类","主机IP");
map.put("危险程度","高危");
list.add(map);
map = new HashMap<String, String>();
map.put("单位名称","test");
map.put("IP","10.130.138.96");
map.put("IP分类","主机IP");
map.put("危险程度","高危");
list.add(map);
list.add(map);
map = new HashMap<String, String>();
map.put("单位名称","test111");
map.put("IP","10.130.138.96");
map.put("IP分类","主机IP");
map.put("危险程度","高危");
list.add(map);
list.add(map);
list.add(map);
list.add(map);
String[] regions = new String[]{"单位名称", "IP", "IP分类", "危险程度"};
System.out.println(createExcel(headers, list, regions));
}
}
最后,再次感谢提供思路的大神
最后
以上就是俊秀刺猬为你收集整理的Java poi生成Excel并合并内容相同的行的全部内容,希望文章能够帮你解决Java poi生成Excel并合并内容相同的行所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复