通过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(cellmodel.getColumIndex());
sheet.setColumnWidth(cellmodel.getColumIndex(),INDEX);
}
if("3".equals(cellmodel.getTiltleType())){
cell.setCellValue(dataMap.get(i).get(j).getColsValue().substring(1,dataMap.get(i).get(j).getColsValue().length()));
}else {
cell.setCellValue(dataMap.get(i).get(j).getColsValue());
}
cell.setCellStyle(style);
}
}
}
/*****生成分值表******/
/**
* 创建选项行
*/
public static List<CellModel> getAvgHeaderCell(List<TitleAnswerModel> tilteAnswerList, List<CellModel> tilteList, Map<String, String> titleTypeMap) {
List<CellModel> headerList = new ArrayList<>();
tilteList.stream().forEach(qititle -> {
CellModel cellModel = CellModel.builder().cellName(qititle.getColsKey() + "、" + qititle.getCellName()).build();
titleTypeMap.put(qititle.getColsKey(), qititle.getTiltleType());
List<String> answerList = new ArrayList<>();
List<String> answer1List = new ArrayList<>();
tilteAnswerList.forEach(item -> {
if (item.getTitleQid().equals(qititle.getColsKey())) {
answerList.add(item.getTheAnswer() + "、" + item.getTheAnswerName());
answer1List.add(item.getTheAnswer());
}
});
answerList.add("平均分值");
answer1List.add("avg");
cellModel.setColspan(answerList.size());
cellModel.setColsKey(qititle.getColsKey());
cellModel.setChildCellList(answerList);
cellModel.setChildQz(answer1List);
headerList.add(cellModel);
});
return headerList;
}
/**
* 添加用户信息、用户选择答案
*/
public static void creatExcelData(Map<String, Map<String, Object>> dataResult, List<Map<String, CellValueModel>> excelData) {
for (String province : dataResult.keySet()) {
Map<String, CellValueModel> cellMap = new LinkedHashMap<>();
CellValueModel userData = new CellValueModel();
userData.setColsKey("province");
userData.setColsValue(province);
cellMap.put("province", userData);
for (String titleNum : dataResult.get(province).keySet()) {
for (Object num : ((Map) dataResult.get(province).get(titleNum)).keySet()) {
CellValueModel answerData = new CellValueModel();
answerData.setColsKey(titleNum + num.toString());
answerData.setColsValue(((Map) dataResult.get(province).get(titleNum)).get(num).toString());
cellMap.put(titleNum + num.toString(), answerData);
}
CellValueModel cellValueModel = new CellValueModel();
cellValueModel.setColsKey(titleNum + "avg");
cellValueModel.setColsValue("avg");
cellMap.put(titleNum + "avg", cellValueModel);
}
excelData.add(cellMap);
}
}
public static Map<String, CellModel> createExcelHeader(XSSFSheet sheet, List<CellModel> headerList, XSSFCellStyle headStyle) {
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(headStyle);
// 保留列头对应的信息 为填充数据准备
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));
cell2.setCellStyle(headStyle);
sheet.setColumnWidth(k,INDEX);
k = k + 1;
}
} else {
k = k + 1;
}
}
return headerMap;
}
public static void creatExcelIndex(List<Map<String, CellValueModel>> dataMap, XSSFSheet sheet, Map<String, Integer> indexMap,XSSFCellStyle contentStyle) {
for (int i = 0; i < dataMap.size(); i++) {
Map<String, BigDecimal> scoreMap = new LinkedHashMap<>();
XSSFRow row = sheet.createRow(i + 2);
for (Map.Entry<String, Integer> entry : indexMap.entrySet()) {
for (Map.Entry<String, CellValueModel> en : dataMap.get(i).entrySet()) {
XSSFCell cell1 = null;
if (!dataMap.get(i).containsKey(entry.getKey())) {
cell1 = row.createCell(entry.getValue());
cell1.setCellValue(String.valueOf(0));
cell1.setCellStyle(contentStyle);
} else {
if (indexMap.get(en.getValue().getColsKey()) != null) {
XSSFCell cell2 = row.createCell(indexMap.get(en.getValue().getColsKey()));
cell2.setCellValue(en.getValue().getColsValue());
cell2.setCellStyle(contentStyle);
if (en.getValue().getColsKey().endsWith("A")) {
scoreMap.put("A", new BigDecimal(en.getValue().getColsValue()).multiply(new BigDecimal("100")));
if (scoreMap.containsKey("SUM")) {
scoreMap.put("SUM", scoreMap.get("SUM").add(new BigDecimal(en.getValue().getColsValue())));
} else {
scoreMap.put("SUM", new BigDecimal(en.getValue().getColsValue()));
}
} else if (en.getValue().getColsKey().endsWith("B")) {
scoreMap.put("B", new BigDecimal(en.getValue().getColsValue()).multiply(new BigDecimal("75")));
if (scoreMap.containsKey("SUM")) {
scoreMap.put("SUM", scoreMap.get("SUM").add(new BigDecimal(en.getValue().getColsValue())));
} else {
scoreMap.put("SUM", new BigDecimal(en.getValue().getColsValue()));
}
} else if (en.getValue().getColsKey().endsWith("C")) {
scoreMap.put("C", new BigDecimal(en.getValue().getColsValue()).multiply(new BigDecimal("50")));
if (scoreMap.containsKey("SUM")) {
scoreMap.put("SUM", scoreMap.get("SUM").add(new BigDecimal(en.getValue().getColsValue())));
} else {
scoreMap.put("SUM", new BigDecimal(en.getValue().getColsValue()));
}
} else if (en.getValue().getColsKey().endsWith("D")) {
scoreMap.put("D", new BigDecimal(en.getValue().getColsValue()).multiply(new BigDecimal("25")));
if (scoreMap.containsKey("SUM")) {
scoreMap.put("SUM", scoreMap.get("SUM").add(new BigDecimal(en.getValue().getColsValue())));
} else {
scoreMap.put("SUM", new BigDecimal(en.getValue().getColsValue()));
}
} else if (en.getValue().getColsKey().endsWith("E")) {
scoreMap.put("E", new BigDecimal(en.getValue().getColsValue()).multiply(new BigDecimal("0")));
if (scoreMap.containsKey("SUM")) {
scoreMap.put("SUM", scoreMap.get("SUM").add(new BigDecimal(en.getValue().getColsValue())));
} else {
scoreMap.put("SUM", new BigDecimal(en.getValue().getColsValue()));
}
} else if (en.getValue().getColsKey().endsWith("avg")) {
BigDecimal bignum1 = new BigDecimal("0");
BigDecimal bignum2 = new BigDecimal("0");
for (String key : scoreMap.keySet()) {
if (!"SUM".equals(key)) {
bignum1 = bignum1.add(scoreMap.get(key));
bignum2 = scoreMap.get("SUM");
}
}
if (bignum1.equals(BigDecimal.ZERO) || bignum1.equals(BigDecimal.ZERO)) {
cell2.setCellValue(0);
} else {
cell2.setCellValue("" + bignum1.divide(bignum2, 2, RoundingMode.HALF_UP));
}
scoreMap.clear();
}
} else {
continue;
}
}
}
}
}
}
public static Map<String, Integer> createExcelIndex(XSSFSheet sheet, List<CellModel> headerList, XSSFCellStyle headStyle) {
Map<String, Integer> headerMap = new LinkedHashMap<>();
XSSFRow row = sheet.createRow(1);
// excel 列索引起始位置
int cols = 0;
//第二行 选项便宜计数器
int k = 0;
for (int i = 0; i < headerList.size(); i++) {
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 = row.createCell(k);
cell2.setCellValue(headerList.get(i).getChildCellList().get(j));
cell2.setCellStyle(headStyle);
sheet.setColumnWidth(k,INDEX);
headerMap.put(headerList.get(i).getColsKey() + headerList.get(i).getChildQz().get(j), k);
k = k + 1;
}
} else {
headerMap.put(headerList.get(i).getColsKey(), k);
k = k + 1;
}
}
return headerMap;
}
public static void createScoreData(Map<String, Map<String, Object>> dataResult, RowDataModel data, String type) {
if (dataResult.containsKey(type)) {
Map<String, Object> resultMap = dataResult.get(type);
String[] keyValue = data.getAnswer().split("\\|+");
for (int k = 0 ; k < keyValue.length; k ++){
String[] titValue = keyValue[k].split(":");
//xmMap中key存选项,Value存选项个数
if (resultMap.containsKey(titValue[0])) {
Map<String, Integer> xmMap = (Map<String, Integer>) resultMap.get(titValue[0]);
if (xmMap.containsKey(String.valueOf(titValue[1]))) {
int num = xmMap.get(titValue[1]);
xmMap.put(titValue[1], num + 1);
} else {
xmMap.put(titValue[1], 1);
}
//resultMap中key存题号,Value存选项个数
resultMap.put(titValue[0], xmMap);
} else {
// 没有题号
Map<String, Object> xmMap = new LinkedHashMap<>();
char[] typeChars = titValue[1].toCharArray();
for (int i = 0; i < typeChars.length; i++) {
xmMap.put(String.valueOf(typeChars[i]), 1);
}
resultMap.put(titValue[0], xmMap);
}
}
} else {
// key 题号 ,value 选项 和计数
Map<String, Object> resultMap = new LinkedHashMap<>();
String[] keyValue = data.getAnswer().split("\\|+");
for (int j = 0 ; j < keyValue.length; j++){
String[] titValue = keyValue[j].split(":");
//titValue[0] 代表题号
// key 选项 ,计数
Map<String, Integer> xmMap = new LinkedHashMap<>();
for (int i = 0; i < titValue.length-1; i++) {
xmMap.put(String.valueOf(titValue[i+1]), 1);
}
resultMap.put(titValue[0], xmMap);
}
dataResult.put(type, resultMap);
}
}
/**
* 生成占比表
* 占比表的头部信息和选项信息
*/
public static Map<String, Integer> createPercentHeader(XSSFSheet sheet, List<CellModel> headerList, Map<String, List<String>> listMap, XSSFCellStyle headStyle) {
Map<String, Integer> 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(headStyle);
// 保留列头对应的信息 为填充数据准备
//headerMap.put(headerList.get(i).getColsKey(), headerList.get(i).getColumIndex());
listMap.put(headerList.get(i).getColsKey(),headerList.get(i).getChildQz());
// 大于1 代表合并列 默认为1 代表不合并,获取行合并熟悉 大于1 代表合并行
if (headerList.get(i).getColspan() > 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).getChildQz().size(); j++) {
XSSFCell cell2 = row2.createCell(k);
cell2.setCellValue(headerList.get(i).getChildCellList().get(j));
sheet.setColumnWidth(k,INDEX);
cell2.setCellStyle(headStyle);
headerMap.put(headerList.get(i).getColsKey()+headerList.get(i).getChildQz().get(j), k);
k = k + 1;
}
} else {
k = k + 1;
}
}
return headerMap;
}
/**
* 创建选项行
*/
public static List<CellModel> getOptionCell(List<TitleAnswerModel> tilteAnswerList, List<CellModel> tilteList) {
List<CellModel> headerList = new ArrayList<>();
tilteList.stream().forEach(qititle -> {
CellModel cellModel = CellModel.builder().cellName(qititle.getColsKey() + "、" + qititle.getCellName()).build();
List<String> answerList = new ArrayList<>();
List<String> answer1List = new ArrayList<>();
answerList.add("参与人数");
answer1List.add("join");
tilteAnswerList.forEach(item -> {
if (item.getTitleQid().equals(qititle.getColsKey())) {
answerList.add(item.getTheAnswerName());
answer1List.add(item.getTheAnswer());
}
});
cellModel.setColspan(answerList.size());
cellModel.setColsKey(qititle.getColsKey());
cellModel.setChildCellList(answerList);
cellModel.setChildQz(answer1List);
headerList.add(cellModel);
});
return headerList;
}
/**
* 计算每个选项参与人数
*
* @param list
* @return
*/
public static Map<String, Integer> findSelectData(List<RowDataModel> list) {
//answerMap中key存题号+选项,value存每个选项的选择的人数
Map<String, Integer> answerMap = new LinkedHashMap<>();
for (RowDataModel data : list) {
String[] keyValue = data.getAnswer().split("\\|");
for (int i = 0; i < keyValue.length; i++) {
String[] titValue = keyValue[i].split(":");
//题号+选项
for (int j = 0; j < titValue.length - 1; j++) {
String qidAnswer = titValue[j] + titValue[j + 1];
if (answerMap.get(qidAnswer) == null || "".equals(answerMap.get(qidAnswer))) {
answerMap.put(qidAnswer, 1);
} else {
answerMap.put(qidAnswer, answerMap.get(qidAnswer) + 1);
}
}
}
}
return answerMap;
}
public static void creatExcelData(Map<String, Integer> countMap, XSSFSheet sheet, Map<String, List<String>> listMap,Map<String, Integer> headMap,List<RowDataModel> list,XSSFCellStyle contentStyle) {
XSSFRow row = sheet.createRow(2);
XSSFRow row1 = sheet.createRow(3);
for (String entry : headMap.keySet()) {
if(entry.endsWith("join")){
int num = Integer.valueOf(entry.replace("join",""));
List<String> childList = listMap.get(num +"");
int sum = 0;
for(int i = 0; i < childList.size();i++){
if(childList.get(i).endsWith("join")){
continue;
}
String key = num + childList.get(i);
XSSFCell cell1 = row.createCell(headMap.get(entry)+i);
if (ObjectUtils.isEmpty(countMap.get(key))){
cell1.setCellValue(0);
cell1.setCellStyle(contentStyle);
continue;
}
sum = sum + countMap.get(key).intValue();
//第一行数据
cell1.setCellValue(countMap.get(key));
cell1.setCellStyle(contentStyle);
}
XSSFCell cell2 = row.createCell(headMap.get(entry));
cell2.setCellValue(list.size());
cell2.setCellStyle(contentStyle);
for(int j = 0; j < childList.size();j++){
if(childList.get(j).endsWith("join")){
continue;
}
String key = num + childList.get(j);
XSSFCell cell3 = row1.createCell(headMap.get(entry)+j);
if (ObjectUtils.isEmpty(countMap.get(key))){
cell3.setCellValue("0%");
cell3.setCellStyle(contentStyle);
continue;
}
//第二行数据
double d1 = countMap.get(key);
double d2 = sum;
NumberFormat nt = NumberFormat.getPercentInstance();
//设置百分数保留两位小数
nt.setMinimumFractionDigits(2);
String s2 = nt.format(d1 / d2);
cell3.setCellValue(s2);
cell3.setCellStyle(contentStyle);
}
XSSFCell cell4 = row1.createCell(headMap.get(entry));
cell4.setCellValue("占比");
cell4.setCellStyle(contentStyle);
}
}
}
/**
* 下载生成的excel文件
*
* @param response
* @param fileName
* @param workbook
*/
public static void downloadWorkBook(HttpServletResponse response, String fileName, XSSFWorkbook workbook) {
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setHeader("Content-Disposition", "attachment;filename=" + toUtf8String(fileName + ".xlsx"));
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Type", "application/octet-stream");
response.setHeader("Access-Control-Expose-Headers", "content-Disposition");
OutputStream out = null;
try {
response.flushBuffer();
out = response.getOutputStream();
workbook.write(out);
out.flush();
out.close();
} catch (IOException e) {
log.debug("IO异常");
}
}
public static String toUtf8String(String s){
StringBuffer sb = new StringBuffer();
for (int i=0;i<s.length();i++){
char c = s.charAt(i);
if (c >= 0 && c <= 255){sb.append(c);}
else{
byte[] b;
try { b = Character.toString(c).getBytes("utf-8");}
catch (Exception ex) {
System.out.println(ex);
b = new byte[0];
}
for (int j = 0; j < b.length; j++) {
int k = b[j];
if (k < 0) {
k += 256;
}
sb.append("%" + Integer.toHexString(k).toUpperCase());
}
}
}
return sb.toString();
}
}
service层的实现类:
public void reportExport(HttpServletResponse response, ReportExportRequest reportExportRequest) {
int status= reportExportRequest.getCategory();
//导出详情
if (status == 0) {
//左边用户信息存进cellModel对象
List<ReportDetailResponse> detailResponseList = theAnswerMapper.findDetailByPidAndQId(reportExportRequest.getProjectId());
//查询结果表
List<Results> resultsList = resultsMapper.findAnswer(reportExportRequest);
if(resultsList.size() == 0){
log.debug("导出详情,没有可供导出的数据!");
}
//查询标题表
List<Title> titleList = titleMapper.selectByProjectId(reportExportRequest.getProjectId());
if(titleList.size() == 0){
log.debug("导出详情,没有可供导出的数据!");
}
//查询选项表
List<TheAnswer> answerList = theAnswerMapper.selectAnswerByProjectId(reportExportRequest.getProjectId());
if(answerList.size() == 0){
log.debug("导出详情,没有可供导出的数据!");
}
Map<String, String> startColumnMap = new LinkedHashMap<>();
Map<String, String> endColumnMap = new LinkedHashMap<>();
for (ReportDetailResponse res : detailResponseList) {
if (null == res) {
continue;
}
if ("Y".equals(res.getIsNoName())) {
startColumnMap.put(ExportUserInfo.USERNAME, "用户姓名");
}
if ("Y".equals(res.getIsNoPhone())) {
startColumnMap.put(ExportUserInfo.PHONE, "电话");
}
if ("Y".equals(res.getIsNoEmail())) {
startColumnMap.put(ExportUserInfo.EMAIL, "邮箱");
}
if ("Y".equals(res.getIsNoShowProvince())) {
startColumnMap.put(ExportUserInfo.PROVINCE, "省");
}
if ("Y".equals(res.getIsNoShowCity())) {
startColumnMap.put(ExportUserInfo.CITY, "市");
}
if ("Y".equals(res.getIsNoShowCounty())) {
startColumnMap.put(ExportUserInfo.COUNTRY, "区");
}
if ("Y".equals(res.getIsNoShowAddress())) {
startColumnMap.put(ExportUserInfo.ADDRESS, "详细地址");
}
}
endColumnMap.put(ExportUserInfo.DATASOURCEONE, "来源1(官网,微信,QQ,支付宝,移动官网,微博)");
endColumnMap.put(ExportUserInfo.DATASOURCETWO, "来源2(客户调查、客服电话代调查)");
endColumnMap.put(ExportUserInfo.ISLUCKY, "是否是幸运用户");
List<CellModel> titleCellModel = new ArrayList<>();
List<CellModel> answerCellModel = new ArrayList<>();
List<RowDataModel> rowDataList = new ArrayList<>();
titleList.forEach(title -> {
CellModel cellModel = CellModel.builder().cellName(title.getTitleName()).colsKey(title.getQId() + "").tiltleType(title.getTitleType()).build();
titleCellModel.add(cellModel);
});
answerList.forEach(answer -> {
CellModel cellModel = CellModel.builder().cellName(answer.getTheAnswer() + "、" + answer.getTheAnswerName()).colsKey(answer.getTitleQId() + "").build();
answerCellModel.add(cellModel);
});
resultsList.forEach(results -> {
RowDataModel rowDataModel = RowDataModel.builder().id(results.getId()).userName(results.getName()).phone(results.getPhone())
.email(results.getEmail()).province(results.getProvince()).city(results.getCity()).country(results.getCounty()).address(results.getAddress())
.answer(results.getAnswer()).sourceTool(results.getSourceTool()).sourceWay(results.getSourceWay()).isLucky(results.getIsLucky()).build();
rowDataList.add(rowDataModel);
});
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet(detailFile);
XSSFFont xssfFont = workbook.createFont();
xssfFont.setFontName("宋体");
xssfFont.setFontHeight(11);
XSSFCellStyle style = workbook.createCellStyle();
style.setFont(xssfFont);
style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setAlignment(HorizontalAlignment.CENTER);
style.setWrapText(true);
style.setBorderBottom(BorderStyle.THIN);
style.setBorderLeft(BorderStyle.THIN);
style.setBorderRight(BorderStyle.THIN);
style.setBorderTop(BorderStyle.THIN);
//获得用户信息列数据
List<CellModel> headerList = ExportExcelUtils.getExcelHead(startColumnMap);
Map<String, String> titleTypeMap = new HashMap<>();
//获得题目信息列数据
ExportExcelUtils.getHeaderCell(titleCellModel, answerCellModel, titleTypeMap).forEach(title -> headerList.add(title));
//获得结束列数据
ExportExcelUtils.getExcelHead(endColumnMap).forEach(endColumn -> headerList.add(endColumn));
//创建表格数据
List<List<CellValueModel>> excelData = new ArrayList<>();
ExportExcelUtils.creatExcelData(rowDataList, titleTypeMap, excelData);
Map<String, Integer> indexMap = new LinkedHashMap<>();
//生成表头
Map<String, CellModel> headerMap = ExportExcelUtils.generateExcelHeader(sheet, headerList,indexMap,style);
//生成表格
ExportExcelUtils.creatExcel(excelData, sheet, headerMap,indexMap,style);
//生成文件
ExportExcelUtils.downloadWorkBook(response, detailFile, workbook);
//导出占比
}else if(status == 1){
//查询结果表
List<Results> resultsList = resultsMapper.findAnswer(reportExportRequest);
if(resultsList.size() == 0){
log.debug("导出占比,没有可供导出的数据!");
}
//查询标题表
List<Title> titleList = titleMapper.findTitleByType(reportExportRequest.getProjectId());
if(titleList.size() == 0){
log.debug("导出占比,没有可供导出的数据!");
}
//查询选项表
List<TheAnswer> answerList = theAnswerMapper.selectAnswerByProjectId(reportExportRequest.getProjectId());
if(answerList.size() == 0){
log.debug("导出占比,没有可供导出的数据!");
}
List<CellModel> titles = new ArrayList<>();
List<TitleAnswerModel> answers = new ArrayList<>();
List<RowDataModel> rowDataList = new ArrayList<>();
for (Title title:titleList){
CellModel cellModel = CellModel.builder().cellName(title.getTitleName()).colsKey(title.getQId() + "").tiltleType(title.getTitleType()).build();
titles.add(cellModel);
}
answerList.forEach(answer -> {
TitleAnswerModel titleAnswerModel = TitleAnswerModel.builder().titleQid(answer.getTitleQId()+"").aswerId(answer.getId())
.theAnswer(answer.getTheAnswer()).theAnswerName(answer.getTheAnswerName()).allowNull(answer.getAllowNull())
.maxLength(answer.getMaxLength()).build();
answers.add(titleAnswerModel);
});
for(Results results : resultsList){
RowDataModel rowDataModel = RowDataModel.builder().answer(results.getAnswer()).build();
rowDataList.add(rowDataModel);
}
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet(recentFile);
XSSFFont xssfFont = workbook.createFont();
xssfFont.setFontName("宋体");
xssfFont.setFontHeight(11);
XSSFCellStyle style = workbook.createCellStyle();
style.setFont(xssfFont);
style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setAlignment(HorizontalAlignment.CENTER);
style.setWrapText(true);
style.setBorderBottom(BorderStyle.THIN);
style.setBorderLeft(BorderStyle.THIN);
style.setBorderRight(BorderStyle.THIN);
style.setBorderTop(BorderStyle.THIN);
List<CellModel> headerList = new ArrayList<>();
Map<String,List<String>> listMap = new HashMap<>();
//获得题目信息列数据
ExportExcelUtils.getOptionCell(answers,titles).forEach(title -> headerList.add(title));
Map<String, Integer> headMap = ExportExcelUtils.createPercentHeader(sheet,headerList,listMap,style);
Map<String, Integer> selectMap = ExportExcelUtils.findSelectData(rowDataList);
ExportExcelUtils.creatExcelData(selectMap,sheet,listMap,headMap,rowDataList,style);
//生成文件
ExportExcelUtils.downloadWorkBook(response, recentFile, workbook);
//导出分值
}else if(status == 2){
//查询结果表
List<Results> resultsList = resultsMapper.findAnswer(reportExportRequest);
if(resultsList.size() == 0){
log.debug("导出分值,没有可供导出的数据!");
}
//查询标题表
List<Title> titleList = titleMapper.findTitleScore(reportExportRequest.getProjectId());
if(titleList.size() == 0){
log.debug("导出分值,没有可供导出的数据!");
}
//查询选项表
List<TheAnswer> answerList = theAnswerMapper.selectAnswerByProjectId(reportExportRequest.getProjectId());
if(answerList.size() == 0){
log.debug("导出分值,没有可供导出的数据!");
}
List<CellModel> titles = new ArrayList<>();
List<TitleAnswerModel> answers = new ArrayList<>();
List<RowDataModel> rowDataList = new ArrayList<>();
titleList.forEach(title -> {
CellModel cellModel = CellModel.builder().cellName(title.getTitleName()).colsKey(title.getQId() + "").tiltleType(title.getTitleType()).build();
titles.add(cellModel);
});
answerList.forEach(answer -> {
TitleAnswerModel titleAnswerModel = TitleAnswerModel.builder().titleQid(answer.getTitleQId()+"").aswerId(answer.getId())
.theAnswer(answer.getTheAnswer()).theAnswerName(answer.getTheAnswerName()).allowNull(answer.getAllowNull())
.maxLength(answer.getMaxLength()).build();
answers.add(titleAnswerModel);
});
resultsList.forEach(results -> {
RowDataModel rowDataModel = RowDataModel.builder().id(results.getId()).userName(results.getName()).phone(results.getPhone())
.email(results.getEmail()).province(results.getProvince()).city(results.getCity()).country(results.getCounty()).address(results.getAddress())
.answer(results.getAnswer()).sourceTool(results.getSourceTool()).sourceWay(results.getSourceWay()).isLucky(results.getIsLucky()).build();
rowDataList.add(rowDataModel);
});
Map<String, String> startColumnMap = new LinkedHashMap<>();
startColumnMap.put("province", "省份");
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet(scoreFile);
XSSFFont xssfFont = workbook.createFont();
xssfFont.setFontName("宋体");
xssfFont.setFontHeight(11);
XSSFCellStyle style = workbook.createCellStyle();
style.setFont(xssfFont);
style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setAlignment(HorizontalAlignment.CENTER);
style.setWrapText(true);
style.setBorderBottom(BorderStyle.THIN);
style.setBorderLeft(BorderStyle.THIN);
style.setBorderRight(BorderStyle.THIN);
style.setBorderTop(BorderStyle.THIN);
//获得用户信息列数据
List<CellModel> headerList = ExportExcelUtils.getExcelHead(startColumnMap);
Map<String, String> titleTypeMap = new HashMap<>();
//创建表格数据
List<Map<String,CellValueModel>> excelData=new ArrayList<>();
// key 省份 value {key 题号, value选项 计数器}
Map<String, Map<String, Object>> dataResult = new LinkedHashMap<>();
rowDataList.forEach(data -> {
String type = (data.getProvince() != null && !data.getProvince().equals("")) ? data.getProvince() : data.getCity();
ExportExcelUtils.createScoreData(dataResult, data, type);
});
//获得题目信息列数据
ExportExcelUtils.getAvgHeaderCell(answers,titles, titleTypeMap).forEach(title -> headerList.add(title));
ExportExcelUtils.creatExcelData(dataResult, excelData);
//生成表头
Map<String, Integer> indexMap = ExportExcelUtils.createExcelIndex(sheet, headerList, style);
ExportExcelUtils.createExcelHeader(sheet, headerList,style);
ExportExcelUtils.creatExcelIndex(excelData, sheet, indexMap,style);
//生成文件
ExportExcelUtils.downloadWorkBook(response, scoreFile, workbook);
}
}
还有两个需要用到的dto:
import lombok.Builder;
import lombok.Data;
import java.util.List;
@Data
@Builder
public class CellModel {
// 列对应的key
String colsKey;
// 列对应的名字
String cellName;
// 列所在的起始位置
int columIndex;
// 列合并数 大于1代表合并
int colspan;
// 行合并数据,大于代表合并
int rowspan;
// 列合并数据 比如 A。满意, B.不满意
List<String> childCellList;
//列合并数据简写 如 A ,B
List<String> childQz;
String tiltleType;
}
还有:
import lombok.Data;
@Data
public class CellValueModel {
// 存放key
private String colsKey;
// 存放值
private String colsValue;
}
还有:
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class RowDataModel {
private String id;
private String items;
private String userName;
private String phone;
private String email;
private String province;
private String city;
private String country;
private String address;
private String answer;
private String sourceTool;
private String sourceWay;
private String isLucky;
}
还有:
import lombok.Builder;
import lombok.Data;
@Builder
@Data
public class TitleAnswerModel {
private String aswerId;
private String titleQid;//1
private String theAnswer;//A
private String theAnswerName;//是
private String allowNull;//N
private String maxLength;
}
具体的xml文件的sql就不贴了,涉及到公司的代码,以上就是我写的复杂报表的导出功能。