通过poi导出复杂excel既有合并行又有合并列

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/danruoshui315/article/details/89468239

通过poi导出形如以下的复杂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("导出占比,没有可供导出的数据!");
                throw new YtoException(400, "没有可供导出的数据!");
            }
            //查询标题表
            List<Title> titleList = titleMapper.findTitleByType(reportExportRequest.getProjectId());
            if(titleList.size() == 0){
                log.debug("导出占比,没有可供导出的数据!");
                throw new YtoException(400, "没有可供导出的数据!");
            }
            //查询选项表
            List<TheAnswer> answerList = theAnswerMapper.selectAnswerByProjectId(reportExportRequest.getProjectId());
            if(answerList.size() == 0){
                log.debug("导出占比,没有可供导出的数据!");
                throw new YtoException(400, "没有可供导出的数据!");
            }
            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就不贴了,涉及到公司的代码,以上就是我写的复杂报表的导出功能。

猜你喜欢

转载自blog.csdn.net/danruoshui315/article/details/89468239
今日推荐