通过poi导出形如以下的复杂excel:
此excel里左边和右边的用户可以自由选择是否导出这几列,中间的题型有单选、多选、填空、排序
这是详情表,还有分值表如下:
占比表如下:
我自己写了个针对上面的工具类:
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.util.ObjectUtils;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.text.NumberFormat;
import java.util.*;
@Slf4j
public class ExportExcelUtils {
private final static int INDEX = 75*70;
/**
* 创建起始列和结束列信息
*/
public static List<CellModel> getExcelHead(Map<String, String> startColumnMap) {
List<CellModel> colunmList = new ArrayList<>();
for (String column : startColumnMap.keySet()) {
CellModel cellModel = CellModel.builder().colsKey(column).cellName(startColumnMap.get(column)).rowspan(2).colspan(1).build();
colunmList.add(cellModel);
}
return colunmList;
}
public static Map<String, CellModel> generateExcelHeader(XSSFSheet sheet, List<CellModel> headerList,Map<String, Integer> indexMap,XSSFCellStyle style) {
Map<String, CellModel> headerMap = new LinkedHashMap<>();
XSSFRow row = sheet.createRow(0);
XSSFRow row2 = sheet.createRow(1);
// excel 列索引起始位置
int cols = 0;
//第二行 选项便宜计数器
int k = 0;
for (int i = 0; i < headerList.size(); i++) {
// 创建单元格
XSSFCell cell1 = row.createCell(cols);
// 保存单元格索引位置
headerList.get(i).setColumIndex(cols);
// 单元格赋值
cell1.setCellValue(headerList.get(i).getCellName());
cell1.setCellStyle(style);
// 保留列头对应的信息 为填充数据准备
headerMap.put(headerList.get(i).getColsKey(), headerList.get(i));
// 大于1 代表合并列 默认为1 代表不合并
if (headerList.get(i).getColspan() > 1) {
// 获取行合并熟悉 大于1 代表合并行
// 列合并 ,合并第一行 cols 起始合并列
sheet.addMergedRegion(new CellRangeAddress(0, 0, cols, cols + headerList.get(i).getColspan() - 1));
cols = cols + headerList.get(i).getColspan();
} else {
// 合并列
if (headerList.get(i).getRowspan() > 1) {
sheet.addMergedRegion(new CellRangeAddress(0, 1, cols, cols + 1 - 1));
}
cols = cols + 1;
}
if (headerList.get(i).getChildCellList() != null && headerList.get(i).getChildCellList().size() > 0) {
for (int j = 0; j < headerList.get(i).getChildCellList().size(); j++) {
XSSFCell cell2 = row2.createCell(k);
cell2.setCellValue(headerList.get(i).getChildCellList().get(j));
sheet.setColumnWidth(k,INDEX);
cell2.setCellStyle(style);
indexMap.put(headerList.get(i).getColsKey()+headerList.get(i).getChildCellList().get(j),k);
k = k + 1;
}
} else {
k = k + 1;
}
}
return headerMap;
}
/*****生成详情表******/
/**
* 创建选项行
*/
public static List<CellModel> getHeaderCell(List<CellModel> tilteList, List<CellModel> tilteAnswerList, Map<String, String> titleTypeMap) {
List<CellModel> headerList = new ArrayList<>();
tilteList.stream().forEach(qititle -> {
CellModel cellModel = CellModel.builder().cellName(qititle.getColsKey() + "、" + qititle.getCellName()).tiltleType(qititle.getTiltleType()).build();
titleTypeMap.put(qititle.getColsKey(), qititle.getTiltleType());
if (qititle.getTiltleType().equals("2")) {
cellModel.setColspan(1);
cellModel.setColsKey(qititle.getColsKey());
cellModel.setChildCellList(new ArrayList<String>() {
{
add(" ");
}});
} else {
List<String> answerList = new ArrayList<>();
tilteAnswerList.forEach(item -> {
if (item.getColsKey().equals(qititle.getColsKey())) {
answerList.add(item.getCellName());
}
});
cellModel.setColspan(answerList.size());
cellModel.setColsKey(qititle.getColsKey());
cellModel.setChildCellList(answerList);
}
headerList.add(cellModel);
});
return headerList;
}
/**
* 添加用户信息、用户选择答案、是否幸运用户
*/
public static void creatExcelData(List<RowDataModel> rowDataList, Map<String, String> titleTypeMap, List<List<CellValueModel>> excelData) {
rowDataList.forEach(data -> {
List<CellValueModel> cellList = new ArrayList<>();
Class cl = data.getClass();
Field[] fields = cl.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
CellValueModel userData = new CellValueModel();
Field field = fields[i];
field.setAccessible(true);
String name = field.getName();
userData.setColsKey(name);
try {
Object obj = field.get(data);
if (obj == null) {
userData.setColsValue("");
} else {
userData.setColsValue(obj + "");
}
cellList.add(userData);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
String[] keyValue = data.getAnswer().split("\\|+");
Arrays.stream(keyValue).forEach(answers -> {
String[] titValue = answers.split(":");
if ("1".equals(titleTypeMap.get(titValue[0]))) {
char[] typeChars = titValue[1].toCharArray();
for (int i = 0; i < typeChars.length; i++) {
CellValueModel answerData = new CellValueModel();
answerData.setColsKey(titValue[0]);
answerData.setColsValue(String.valueOf(typeChars[i]));
cellList.add(answerData);
}
} else if("3".equals(titleTypeMap.get(titValue[0]))) {
char[] typeChars = titValue[1].toCharArray();
for (int i = 0; i < typeChars.length; i++) {
CellValueModel answerData = new CellValueModel();
answerData.setColsKey(titValue[0]);
answerData.setColsValue(String.valueOf(typeChars[i]) + (i + 1));
cellList.add(answerData);
}
}
else {
CellValueModel answerData = new CellValueModel();
answerData.setColsKey(titValue[0]);
answerData.setColsValue(titValue[1]);
cellList.add(answerData);
}
});
excelData.add(cellList);
});
}
/**
* 添加表格数据
*/
public static void creatExcel(List<List<CellValueModel>> dataMap, XSSFSheet sheet, Map<String, CellModel> headerMap,Map<String, Integer> indexMap,XSSFCellStyle style) {
for (int i = 0; i < dataMap.size(); i++) {
XSSFRow row = sheet.createRow(i + 2);
XSSFCell cell;
for (int j = 0; j < dataMap.get(i).size(); j++) {
CellModel cellmodel = headerMap.get(dataMap.get(i).get(j).getColsKey());
if (cellmodel == null) {
for(String str : indexMap.keySet()){
cell = row.createCell(indexMap.get(str));
cell.setCellStyle(style);
}
continue;
}
List<String> lists = cellmodel.getChildCellList();
if (lists != null && lists.size() > 0) {
int z = 0;
for (int k = 0; k < lists.size(); k++) {
if (lists.get(k).startsWith(dataMap.get(i).get(j).getColsValue())) {
z = k;
break;
}
if("3".equals(cellmodel.getTiltleType())){
if (lists.get(k).startsWith(dataMap.get(i).get(j).getColsValue().substring(0,1))) {
z = k;
break;
}
}
}
cell = row.createCell(cellmodel.getColumIndex() + z);
sheet.setColumnWidth(cellmodel.getColumIndex() + z,INDEX);
} else {
cell = row.createCell(