• EasyExcel动态表头导出


    1、封装方法

    1. package com.skybird.iot.base.utils;
    2. import cn.hutool.core.util.StrUtil;
    3. import com.alibaba.excel.EasyExcel;
    4. import com.alibaba.excel.support.ExcelTypeEnum;
    5. import com.alibaba.excel.write.metadata.style.WriteCellStyle;
    6. import com.alibaba.excel.write.metadata.style.WriteFont;
    7. import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
    8. import com.skybird.iot.base.utils.bean.Custemhandler;
    9. import java.io.IOException;
    10. import java.io.OutputStream;
    11. import java.net.URLEncoder;
    12. import java.util.List;
    13. import javax.servlet.http.HttpServletRequest;
    14. import javax.servlet.http.HttpServletResponse;
    15. import org.apache.poi.ss.usermodel.HorizontalAlignment;
    16. import org.apache.poi.ss.usermodel.IndexedColors;
    17. import org.apache.poi.ss.usermodel.VerticalAlignment;
    18. public class EasyExcelUtil {
    19. /**
    20. * @param response
    21. * @param t 导出实体类
    22. * @param list 数据集合
    23. * @param name 文件名称
    24. * @throws IOException
    25. * @throws IllegalAccessException
    26. * @throws InstantiationException
    27. */
    28. public static void download(
    29. HttpServletRequest request, HttpServletResponse response, Class t, List list, String name)
    30. throws IOException, IllegalAccessException, InstantiationException {
    31. /*兼容IE和其他浏览器导出文件名乱码的问题*/
    32. // name = downloadCommFileName(name, request);
    33. response.setContentType("application/vnd.ms-excel"); // 设置文本内省
    34. response.setCharacterEncoding("utf-8"); // 设置字符编码
    35. response.setHeader("Content-disposition", "attachment;fileName=name.xlsx"); // 设置响应头
    36. try (OutputStream outStream = response.getOutputStream()) {
    37. EasyExcel.write(outStream, t)
    38. .excelType(ExcelTypeEnum.XLSX)
    39. .registerWriteHandler(new Custemhandler()) // 设置自动列宽设置
    40. .registerWriteHandler(getStyleStrategy()) // 设置样式
    41. .sheet(name)
    42. .doWrite(list); // 用io流来写入数据
    43. outStream.flush();
    44. }
    45. }
    46. /**
    47. * 动态表头导出
    48. *
    49. * @param request
    50. * @param response
    51. * @param head 表头数据
    52. * @param dataList 内容数据
    53. * @param name 名称
    54. * @throws IOException
    55. */
    56. public static void trendsDownload(
    57. HttpServletRequest request,
    58. HttpServletResponse response,
    59. List> head,
    60. List> dataList,
    61. String name)
    62. throws IOException {
    63. try (OutputStream outStream = response.getOutputStream()) {
    64. EasyExcel.write(outStream)
    65. .head(head)
    66. .sheet(name)
    67. .registerWriteHandler(new Custemhandler()) // 设置自动列宽设置
    68. .registerWriteHandler(getStyleStrategy()) // 设置样式
    69. .doWrite(dataList);
    70. outStream.flush();
    71. }
    72. }
    73. /*兼容IE和其他浏览器导出文件名乱码的问题*/
    74. public static String downloadCommFileName(String fileOut, HttpServletRequest request)
    75. throws IOException {
    76. String userAgent = request.getHeader("user-agent").toLowerCase();
    77. if (!StrUtil.contains(userAgent, "chrome")
    78. && (userAgent.contains("msie") || userAgent.contains("like gecko"))) {
    79. // win10 ie edge 浏览器 和其他系统的ie
    80. fileOut = URLEncoder.encode(fileOut, "UTF-8");
    81. } else {
    82. // 其他
    83. fileOut = new String(fileOut.getBytes("utf-8"), "iso-8859-1");
    84. }
    85. return fileOut;
    86. }
    87. public static HorizontalCellStyleStrategy getStyleStrategy() {
    88. // 头的策略
    89. WriteCellStyle headWriteCellStyle = new WriteCellStyle();
    90. // 背景设置
    91. headWriteCellStyle.setFillForegroundColor(IndexedColors.AUTOMATIC.getIndex());
    92. WriteFont headWriteFont = new WriteFont();
    93. headWriteFont.setFontHeightInPoints((short) 12);
    94. // 字体样式
    95. headWriteFont.setFontName("宋体");
    96. headWriteFont.setBold(false); // 取消加粗
    97. // 字体设置成红色
    98. // headWriteFont.setColor(IndexedColors.RED.getIndex());
    99. headWriteCellStyle.setWriteFont(headWriteFont);
    100. // 自动换行
    101. headWriteCellStyle.setWrapped(false);
    102. // headWriteCellStyle.setBorderTop(BorderStyle.SLANTED_DASH_DOT);//右边框
    103. // headWriteCellStyle.setBorderBottom(BorderStyle.SLANTED_DASH_DOT);//左
    104. // headWriteCellStyle.setBorderLeft(BorderStyle.SLANTED_DASH_DOT);//底
    105. // headWriteCellStyle.setBorderRight(BorderStyle.SLANTED_DASH_DOT);
    106. // 水平对齐方式
    107. headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
    108. // 垂直对齐方式
    109. headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
    110. // 内容的策略
    111. WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
    112. // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了
    113. // FillPatternType所以可以不指定
    114. // contentWriteCellStyle.setFillPatternType(FillPatternType.SQUARES);
    115. // 背景白色
    116. contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
    117. WriteFont contentWriteFont = new WriteFont();
    118. // 字体大小
    119. contentWriteFont.setFontHeightInPoints((short) 12);
    120. // 字体样式
    121. contentWriteFont.setFontName("Calibri");
    122. contentWriteCellStyle.setWriteFont(contentWriteFont);
    123. return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
    124. }
    125. }

    2、Java请求接口

    1. @RequestMapping("/excel")
    2. public void excel(
    3. HttpServletRequest request,
    4. HttpServletResponse response,
    5. @RequestParam(value = "dateRange", required = false) Integer dateRange)
    6. throws Exception {
    7. List list = getList(dateRange);
    8. // 表头数据
    9. List> head = ListUtils.newArrayList();
    10. getHead(head);
    11. List dtoList = DocuLib.getList(list.get(0), "causeMalfunctionDetails");
    12. for (Document item : dtoList) {
    13. List head1 = ListUtils.newArrayList();
    14. head1.add(DocuLib.getStr(item, "causeMalfunctionName"));
    15. head.add(head1);
    16. }
    17. // 内容数据
    18. List> dataList = ListUtils.newArrayList();
    19. for (Document item : list) {
    20. List data = ListUtils.newArrayList();
    21. data.add(DocuLib.getStr(item, "yearMonth"));
    22. data.add(DocuLib.getStr(item, "totalMonthly"));
    23. data.add(DocuLib.getStr(item, "auditMonthly"));
    24. data.add(DocuLib.getStr(item, "completedMonthly"));
    25. List rowList = DocuLib.getList(item, "causeMalfunctionDetails");
    26. for (Document dto : rowList) {
    27. data.add(DocuLib.getStr(dto, "count"));
    28. }
    29. dataList.add(data);
    30. }
    31. EasyExcelUtil.trendsDownload(request, response, head, dataList, "销售退货统计");
    32. }
    33. private void getHead(List> head) {
    34. List head1 = ListUtils.newArrayList();
    35. head1.add("时间");
    36. List head2 = ListUtils.newArrayList();
    37. head2.add("退货单数");
    38. List head3 = ListUtils.newArrayList();
    39. head3.add("审核通过");
    40. List head4 = ListUtils.newArrayList();
    41. head4.add("完成单数");
    42. head.add(head1);
    43. head.add(head2);
    44. head.add(head3);
    45. head.add(head4);
    46. }
    47. 3、html关键代码

      1. <div class='card-body' style='height: 100%;'>
      2. <div style="display: flex;flex-wrap: wrap; align-items: center;">
      3. <cb-date inline="true"
      4. style="width:100px;margin-bottom: 10px; display: block;"
      5. ng-model="ctrl.filter.dateRange"
      6. placeholder="创建时间"
      7. picker="year">cb-date>
      8. <button class="btn btn-default btn-sm"
      9. style="margin-left: 8px; margin-bottom: 10px; display: block;" type="button"
      10. ng-click="ctrl.loadData()">
      11. <i class="bi bi-search">i>
      12. 查询
      13. button>
      14. <div>
      15. <button class='btn btn-outline-primary btn-sm' ng-click='ctrl.export()'
      16. style="margin-left: 5px;margin-bottom: 10px;"
      17. ng-if="''| SecurityFilter: 'saleReturnOrderStatistics':'export'"
      18. type='button'>
      19. <i class='bi'>i>
      20. 导出
      21. button>
      22. div>
      23. div>
      24. <div style="overflow: scroll;overflow-x: auto; width: 100%;height: calc(100% - 80px);"
      25. ng-if="check === false">
      26. <table class="table table-bordered" style="width: 1640px;table-layout: fixed;">
      27. <thead style="position: sticky;top: -1px;z-index: 1;">
      28. <tr>
      29. <th width="100px;">时间th>
      30. <th width="150px;">退货单数th>
      31. <th width="150px;">审核通过th>
      32. <th width="150px;">完成单数th>
      33. <th ng-repeat="dailyDetail in entity[0].causeMalfunctionDetails"
      34. ng-style="{width: dailyDetail.causeMalfunctionName.length>=5?dailyDetail.causeMalfunctionName.length*17:100}">
      35. {{dailyDetail.causeMalfunctionName}}
      36. th>
      37. tr>
      38. thead>
      39. <tbody>
      40. <tr ng-repeat="row in entity">
      41. <td>{{row.yearMonth}}td>
      42. <td>{{row.totalMonthly}}td>
      43. <td>{{row.auditMonthly}}td>
      44. <td>{{row.completedMonthly}}td>
      45. <td ng-repeat="dailyDetail in row.causeMalfunctionDetails">{{dailyDetail.count}}td>
      46. tr>
      47. tbody>
      48. table>
      49. div>
      50. <div style="overflow: scroll; width: 100%;height: calc(100% - 80px);" ng-if="check === true">
      51. <table class="table table-bordered" style="width: auto;table-layout: fixed;">
      52. <thead style="position: sticky;top: -1px;z-index: 1;">
      53. <tr>
      54. <th width="100px;">时间th>
      55. <th width="150px;">退货单数th>
      56. <th width="150px;">审核通过th>
      57. <th width="150px;">完成单数th>
      58. <th ng-repeat="dailyDetail in entity[0].causeMalfunctionDetails">
      59. {{dailyDetail.causeMalfunctionName}}
      60. th>
      61. tr>
      62. thead>
      63. <tbody>
      64. <tr ng-repeat="row in entity">
      65. <td>{{row.yearMonth}}td>
      66. <td>{{row.totalMonthly}}td>
      67. <td>{{row.auditMonthly}}td>
      68. <td>{{row.completedMonthly}}td>
      69. <td ng-repeat="dailyDetail in row.causeMalfunctionDetails">{{dailyDetail.count}}td>
      70. tr>
      71. tbody>
      72. table>
      73. div>
      74. div>

      4、js关键代码

      1. export: function () {
      2. //后端导出
      3. http.getFile('saleReturnOrderStatistics/excel', {
      4. dateRange: ctrl.filter.dateRange
      5. }).then(function (response) {
      6. const url = window.URL.createObjectURL(new Blob([response.data]));
      7. const link = document.createElement('a');
      8. link.href = url;
      9. link.setAttribute('download', '销售退货统计.xlsx');
      10. document.body.appendChild(link);
      11. link.click();
      12. });
      13. }

      5、效果

    48. 相关阅读:
      SQL8 查找某个年龄段的用户信息
      cpp primer plus笔记01-注意事项
      C++:指针:智能指针
      商品最大价值-第13届蓝桥杯选拔赛Python真题精选
      Nginx
      Visual Studio 2022创建项目没有CUDA模板的解决方法
      剑指 Offer 19. 正则表达式匹配
      软考重点8 面向对象及数据库
      Postman —— 配置环境变量
      docker 部署 mysql8.0.30
    49. 原文地址:https://blog.csdn.net/xingchenyv/article/details/141067979