Java

说明

  • 使用的是EasyPoi进行导出
  • 行头是动态生成
  • 依据key进行列匹配,进行数据填充
  • 第一列进行纵向动态合并

    工具依赖

    1. <dependency>
    2. <groupId>cn.afterturn</groupId>
    3. <artifactId>easypoi-base</artifactId>
    4. <version>3.2.0</version>
    5. </dependency>
    6. <dependency>
    7. <groupId>cn.afterturn</groupId>
    8. <artifactId>easypoi-annotation</artifactId>
    9. <version>3.2.0</version>
    10. </dependency>
    11. <dependency>
    12. <groupId>cn.afterturn</groupId>
    13. <artifactId>easypoi-web</artifactId>
    14. <version>3.2.0</version>
    15. </dependency>

    实现效果

    变更前样式
    2022-06-29-08-41-23-824140.png
    变更后样式
    2022-06-29-08-41-23-921433.png

    代码解析

    动态生成列头

    1. private List<ExcelExportEntity> dynamicNewAddExcel(Map<String, PlatformStatisParamRespData> paramInfo) {
    2. //表头的集合,用于添加表头
    3. List<ExcelExportEntity> entityList = new ArrayList<>();
    4. //ExcelExportEntity构造参数【第一个是列名头的统计字段,第二个是需要指定的一个key在填充数据的时候是需要根据这个key进行填充值,第三个参数是列宽】
    5. ExcelExportEntity platformXh = new ExcelExportEntity("统计字段1", "statisKey1", 30);
    6. //列的合并(纵向列的同名称会进行合并,效果见上图的平台名称的变化)
    7. platformXh.setMergeVertical(true);
    8. entityList.add(platformXh);
    9. ExcelExportEntity statisDateXh = new ExcelExportEntity("统计字段2", "statisKey2", 30);
    10. entityList.add(statisDateXh);
    11. //参数信息--[用于动态拼接列头]
    12. final Iterator<String> iterator = paramInfo.keySet().iterator();
    13. while (iterator.hasNext()) {
    14. final String paramKeyStr = iterator.next();
    15. final String paramNameStr = paramInfo.get(paramKeyStr).getDataName();
    16. //列头由参数汉字名称,参数key为列key
    17. entityList.add(new ExcelExportEntity(paramNameStr, paramKeyStr, 30));
    18. }
    19. return entityList;
    20. }

    动态填充数据

    1. private List<Map<String, Object>> dynamicListDataByKey(List<PlatformIncomeRespDTO> statisData) {
    2. //参数类型
    3. final Set<String> statisParamKey = statisData.get(0).getParamInfo().keySet();
    4. final List<String> statisDate = statisData.get(0).getStatisDate();
    5. final int platformNum = statisData.size();
    6. //最终的数据
    7. List<Map<String, Object>> datas = new ArrayList<>();
    8. for (int i = 0; i < platformNum; i++) {
    9. for (int j = 0; j < statisDate.size(); j++) {
    10. Map<String, Object> hashMap = new LinkedHashMap<>(10);
    11. //这个是依据key进行数据的填充,(根据前面填写的statisKey1进行填充数据)
    12. hashMap.put("statisKey1", statisData.get(i).getPlatformNickName());
    13. String statisDateStr = statisDate.get(j);
    14. //这个是依据key进行数据的填充,(根据前面填写的statisKey2进行填充数据)
    15. hashMap.put("statisKey2", statisDateStr);
    16. //参数的验证
    17. for (String paramKey : statisParamKey) {
    18. for (BiPlatformStatisRespDTO paramData : statisData.get(i).getStatisData().get(j)) {
    19. if (paramKey.equals(paramData.getParamKey())) {
    20. hashMap.put(paramData.getParamKey(), paramData.getValue() + "(" + paramData.getRateValue() + ")");
    21. }
    22. }
    23. }
    24. datas.add(hashMap);
    25. }
    26. }
    27. return datas;
    28. }

    Excel的导出

    1. //statisData就是查询出来的数据
    2. public void downloadPlatformIncomeContrast(List<PlatformIncomeRespDTO> statisData, HttpServletResponse response) {
    3. if (CollectionUtils.isEmpty(statisData)) {
    4. return;
    5. }
    6. //获取参数信息
    7. final Map<String, PlatformStatisParamRespData> paramInfo = statisData.get(0).getParamInfo();
    8. //拼装列头
    9. List<ExcelExportEntity> colList = this.dynamicNewAddExcel(paramInfo);
    10. //数据拼装
    11. List<Map<String, Object>> list = this.dynamicListDataByKey(statisData);
    12. final String xlsFileName = DateHelper.getNowString(FormatUnit.yyyyMMddHHmmss, true) + ".xls";
    13. final Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), colList, list);
    14. //动态合并纵列[mergeMap key列索引(从0开始),value依赖的列,没有传空,startRow 开始行(从零开始)]
    15. //Map<Integer, int[]> mer = new HashMap<>();
    16. //mer.put(0, new int[]{});
    17. //PoiMergeCellUtil.mergeCells(workbook.getSheetAt(0), mer, 1);
    18. EasypoiUtil.downLoadExcel(xlsFileName, response, workbook);
    19. }

    EasypoiUtil工具类

    1. public static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) {
    2. try {
    3. response.setCharacterEncoding("UTF-8");
    4. response.setHeader("content-Type", "application/vnd.ms-excel");
    5. response.setHeader("Content-Disposition",
    6. "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
    7. workbook.write(response.getOutputStream());
    8. } catch (IOException e) {
    9. throw new RuntimeException(e.getMessage());
    10. }
    11. }

    PlatformIncomeRespDTO ```java @Data @NoArgsConstructor @AllArgsConstructor public class PlatformIncomeRespDTO implements Serializable {

    private static final long serialVersionUID = 1100499105160261425L;

  1. /**
  2. * 平台别名
  3. */
  4. private String platformNickName;
  5. /*统计时间*/
  6. private List<String> statisDate;
  7. /*查询参数信息--[用户收入来源统计导出使用]*/
  8. private Map<String, PlatformStatisParamRespData> paramInfo;
  9. /*统计数据*/
  10. private List<List<BiPlatformStatisRespDTO>> statisData;

}

  1. PlatformStatisParamRespData
  2. ```java
  3. @Data
  4. @NoArgsConstructor
  5. @AllArgsConstructor
  6. public class PlatformStatisParamRespData implements Serializable {
  7. private static final long serialVersionUID = 4263523446154995471L;
  8. /**
  9. * 参数名称
  10. */
  11. private String dataName;
  12. /**
  13. * 参数key
  14. */
  15. private String dateKey;
  16. /**
  17. * 参数描述
  18. */
  19. private String dateDesc;
  20. }

BiPlatformStatisRespDTO

  1. @Data
  2. @AllArgsConstructor
  3. public class BiPlatformStatisRespDTO implements Serializable {
  4. private static final long serialVersionUID = 6070471415344415351L;
  5. @Excel(name = "统计字段", orderNum = "1")
  6. private String param;
  7. /**
  8. * 参数的key
  9. */
  10. private String paramKey;
  11. /**
  12. * 参数描述
  13. */
  14. private String paramDesc;
  15. private String startDate;
  16. private String endDate;
  17. @Excel(name = "统计数据", orderNum = "2")
  18. private String value;
  19. private String rateValue;
  20. private Long id;
  21. private Integer riseOrFall;
  22. public BiPlatformStatisRespDTO(String startDate, String paramKey, String value) {
  23. this.paramKey = paramKey;
  24. this.startDate = startDate;
  25. this.value = value;
  26. }
  27. public BiPlatformStatisRespDTO() {
  28. }
  29. }

测试用例

测试特殊说明

导出的结果有个控制,是在拼装的时候没有填充此数据,不影响整体效果。

测试结果示例

2022-06-29-08-41-23-989731.png

测试数据json示例

  1. [
  2. {
  3. "paramInfo": {
  4. "userCount": {
  5. "dataName": "用户数",
  6. "dateDesc": "用户信息",
  7. "dateKey": "userCount"
  8. },
  9. "friendsCount": {
  10. "dataName": "好友数",
  11. "dateDesc": "好友信息",
  12. "dateKey": "friendsCount"
  13. }
  14. },
  15. "platformNickName": "aaa",
  16. "statisData": [
  17. [
  18. {
  19. "paramKey": "userCount",
  20. "startDate": "2019-12-26",
  21. "value": "100"
  22. },
  23. {
  24. "paramKey": "friendsCount",
  25. "startDate": "2019-12-26",
  26. "value": "200"
  27. }
  28. ],
  29. [
  30. {
  31. "paramKey": "userCount",
  32. "startDate": "2019-12-27",
  33. "value": "300"
  34. },
  35. {
  36. "paramKey": "friendsCount",
  37. "startDate": "2019-12-27",
  38. "value": "400"
  39. }
  40. ]
  41. ],
  42. "statisDate": [
  43. "2019-12-26",
  44. "2019-12-27"
  45. ]
  46. },
  47. {
  48. "paramInfo": {
  49. "userCount": {
  50. "dataName": "用户数",
  51. "dateDesc": "用户信息",
  52. "dateKey": "userCount"
  53. },
  54. "friendsCount": {
  55. "dataName": "好友数",
  56. "dateDesc": "好友信息",
  57. "dateKey": "friendsCount"
  58. }
  59. },
  60. "platformNickName": "bbb",
  61. "statisData": [
  62. [
  63. {
  64. "paramKey": "userCount",
  65. "startDate": "2019-12-26",
  66. "value": "500"
  67. },
  68. {
  69. "paramKey": "friendsCount",
  70. "startDate": "2019-12-26",
  71. "value": "600"
  72. }
  73. ],
  74. [
  75. {
  76. "paramKey": "userCount",
  77. "startDate": "2019-12-27",
  78. "value": "700"
  79. },
  80. {
  81. "paramKey": "friendsCount",
  82. "startDate": "2019-12-27",
  83. "value": "800"
  84. }
  85. ]
  86. ],
  87. "statisDate": [
  88. "2019-12-26",
  89. "2019-12-27"
  90. ]
  91. }
  92. ]

测试用例代码

  1. public class Simple {
  2. /**
  3. * @Description: 拼接表头
  4. * @Param: paramInfo :表头信息
  5. * @return: java.util.List<cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity>
  6. */
  7. private static List<ExcelExportEntity> dynamicNewAddExcel(Map<String, PlatformStatisParamRespData> paramInfo) {
  8. //表头的集合,用于添加表头
  9. List<ExcelExportEntity> entityList = new ArrayList<>();
  10. //ExcelExportEntity构造参数【第一个是列名头的统计字段,第二个是需要指定的一个key在填充数据的时候是需要根据这个key进行填充值,第三个参数是列宽】
  11. ExcelExportEntity platformXh = new ExcelExportEntity("统计字段1", "statisKey1", 30);
  12. //列的合并(纵向列的同名称会进行合并,效果见上图的平台名称的变化)
  13. platformXh.setMergeVertical(true);
  14. entityList.add(platformXh);
  15. ExcelExportEntity statisDateXh = new ExcelExportEntity("统计字段2", "statisKey2", 30);
  16. entityList.add(statisDateXh);
  17. //参数信息--[用于动态拼接列头]
  18. final Iterator<String> iterator = paramInfo.keySet().iterator();
  19. while (iterator.hasNext()) {
  20. final String paramKeyStr = iterator.next();
  21. final String paramNameStr = paramInfo.get(paramKeyStr).getDataName();
  22. //列头由参数汉字名称,参数key为列key
  23. entityList.add(new ExcelExportEntity(paramNameStr, paramKeyStr, 30));
  24. }
  25. return entityList;
  26. }
  27. /**
  28. * @Description: 拼接数据
  29. * @Param: statisData :拼接数据
  30. */
  31. private static List<Map<String, Object>> dynamicListDataByKey(List<PlatformIncomeRespDTO> statisData) {
  32. //参数类型
  33. final Set<String> statisParamKey = statisData.get(0).getParamInfo().keySet();
  34. final List<String> statisDate = statisData.get(0).getStatisDate();
  35. final int platformNum = statisData.size();
  36. //最终的数据
  37. List<Map<String, Object>> datas = new ArrayList<>();
  38. for (int i = 0; i < platformNum; i++) {
  39. for (int j = 0; j < statisDate.size(); j++) {
  40. Map<String, Object> hashMap = new LinkedHashMap<>(10);
  41. //这个是依据key进行数据的填充,(根据前面填写的statisKey1进行填充数据)
  42. hashMap.put("statisKey1", statisData.get(i).getPlatformNickName());
  43. String statisDateStr = statisDate.get(j);
  44. //这个是依据key进行数据的填充,(根据前面填写的statisKey2进行填充 数据)
  45. hashMap.put("statisKey2", statisDateStr);
  46. //参数的验证
  47. for (String paramKey : statisParamKey) {
  48. for (BiPlatformStatisRespDTO paramData : statisData.get(i).getStatisData().get(j)) {
  49. if (paramKey.equals(paramData.getParamKey())) {
  50. hashMap.put(paramData.getParamKey(), paramData.getValue() + "(" + paramData.getRateValue() + ")");
  51. }
  52. }
  53. }
  54. datas.add(hashMap);
  55. }
  56. }
  57. return datas;
  58. }
  59. @Test
  60. public void Administrator_84_20191226095523() throws IOException {
  61. System.out.println("欢迎使用单元测试方法【Administrator_84()_20191226095523】");
  62. System.out.println("此方法测试描述:【】");
  63. //拼装第一个数据---------------------------------------------------------------------
  64. final PlatformIncomeRespDTO platformIncomeRespDTO1 = new PlatformIncomeRespDTO();
  65. platformIncomeRespDTO1.setPlatformNickName("aaa");
  66. //拼装时间维度
  67. platformIncomeRespDTO1.setStatisDate(Lists.newArrayList("2019-12-26","2019-12-27"));
  68. //拼装头信息
  69. Map<String, PlatformStatisParamRespData> paramInfo1=new HashMap<>();
  70. paramInfo1.put("userCount", new PlatformStatisParamRespData("用户数","userCount","用户信息"));
  71. paramInfo1.put("friendsCount", new PlatformStatisParamRespData("好友数","friendsCount","好友信息"));
  72. platformIncomeRespDTO1.setParamInfo(paramInfo1);
  73. //拼装数据
  74. final ArrayList<List<BiPlatformStatisRespDTO>> data1 = Lists.newArrayList();
  75. data1.add(Lists.newArrayList(new BiPlatformStatisRespDTO("2019-12-26","userCount","100"),new BiPlatformStatisRespDTO("2019-12-26","friendsCount","200")));
  76. data1.add(Lists.newArrayList(new BiPlatformStatisRespDTO("2019-12-27","userCount","300"),new BiPlatformStatisRespDTO("2019-12-27","friendsCount","400")));
  77. platformIncomeRespDTO1.setStatisData(data1);
  78. //拼装第二个数据---------------------------------------------------------------------
  79. final PlatformIncomeRespDTO platformIncomeRespDTO2 = new PlatformIncomeRespDTO();
  80. platformIncomeRespDTO2.setPlatformNickName("bbb");
  81. //拼装时间维度
  82. platformIncomeRespDTO2.setStatisDate(Lists.newArrayList("2019-12-26","2019-12-27"));
  83. //拼装头信息
  84. Map<String, PlatformStatisParamRespData> paramInfo2=new HashMap<>();
  85. paramInfo2.put("userCount", new PlatformStatisParamRespData("用户数","userCount","用户信息"));
  86. paramInfo2.put("friendsCount", new PlatformStatisParamRespData("好友数","friendsCount","好友信息"));
  87. platformIncomeRespDTO2.setParamInfo(paramInfo2);
  88. //拼装数据
  89. final ArrayList<List<BiPlatformStatisRespDTO>> data2 = Lists.newArrayList();
  90. data2.add(Lists.newArrayList(new BiPlatformStatisRespDTO("2019-12-26","userCount","500"),new BiPlatformStatisRespDTO("2019-12-26","friendsCount","600")));
  91. data2.add(Lists.newArrayList(new BiPlatformStatisRespDTO("2019-12-27","userCount","700"),new BiPlatformStatisRespDTO("2019-12-27","friendsCount","800")));
  92. platformIncomeRespDTO2.setStatisData(data2);
  93. final ArrayList<PlatformIncomeRespDTO> platformIncomeRespDTOS = Lists.newArrayList(platformIncomeRespDTO1, platformIncomeRespDTO2);
  94. System.out.println(JSONObject.toJSONString(platformIncomeRespDTOS));
  95. //拼装列头
  96. List<ExcelExportEntity> colList = dynamicNewAddExcel(paramInfo2);
  97. //数据拼装
  98. List<Map<String, Object>> list = dynamicListDataByKey(platformIncomeRespDTOS);
  99. //文件名称
  100. final Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), colList, list);
  101. //此功能与【拼装列头】中的 platformXh.setMergeVertical(true);功能效果一样,可直接使用 platformXh.setMergeVertical(true);进行纵向合并
  102. //动态合并纵列[mergeMap key列索引(从0开始),value依赖的列,没有传空,startRow 开始行(从零开始)]
  103. //Map<Integer, int[]> mer = new HashMap<>();
  104. //mer.put(0, new int[]{});
  105. //PoiMergeCellUtil.mergeCells(workbook.getSheetAt(0), mer, 1);
  106. final FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\1.xls");
  107. //导出excel
  108. downLoadExcel(null, fileOutputStream, workbook);
  109. }
  110. /**
  111. * @Description: 下载文件
  112. * @Param: fileName
  113. * @Param outputStream
  114. * @Param workbook
  115. * @return: void
  116. */
  117. public static void downLoadExcel(String fileName, FileOutputStream outputStream, Workbook workbook)
  118. throws IOException {
  119. try {
  120. workbook.write(outputStream);
  121. } catch (IOException e) {
  122. throw new RuntimeException(e.getMessage());
  123. } finally {
  124. outputStream.close();
  125. }
  126. }
  127. }