Java-使用 Easyexcel 导出 Excel 数据(动态列)

2023年06月03日 20:48 · 阅读(5090) ·

参考

Easy Excel

如何用 easyExcel 动态导出全部数据?

使用 easyExcel write 步骤;并且设置列宽

BuiltinFormats 速查表

EasyExcel格式化映射注解和样式注解详解

需求描述

  • 存在下面的数据
  1. @Data
  2. public class RepaymentPlanVO {
  3. /**
  4. * Last Interest Rate
  5. */
  6. private BigDecimal lastInterestRate;
  7. /**
  8. * 根据期间生成的动态列
  9. */
  10. private List<RepaymentPlanItemVO> listTrendsColumn;
  11. }
  • 其中 lastInterestRate 列是固定的

  • listTrendsColumn 是多列,根据计算得出

pom.xml

  1. <dependencies>
  2. <dependency>
  3. <groupId>com.alibaba</groupId>
  4. <artifactId>easyexcel</artifactId>
  5. <version>2.2.6</version>
  6. </dependency>
  7. </dependencies>

公共类

● 这里代码基本和 如何用 easyExcel 动态导出全部数据? 一致

ExcelHead-动态 excel 表头

  1. package com.luoma.finance.vo.report;
  2. import lombok.Data;
  3. /**
  4. * Excel 导出类 - ExcelHead
  5. */
  6. @Data
  7. public class ExcelHead<T> {
  8. /**
  9. * 内容里的字段名称
  10. */
  11. private String fieldName;
  12. /**
  13. * 显示值,一般为中文的
  14. */
  15. private String title;
  16. /**
  17. * 如果为 null 的值
  18. */
  19. private T nullValue;
  20. public ExcelHead(String fieldName, String title) {
  21. this.fieldName = fieldName;
  22. this.title = title;
  23. }
  24. public ExcelHead(String fieldName, String title, T nullValue) {
  25. this.fieldName = fieldName;
  26. this.title = title;
  27. this.nullValue = nullValue;
  28. }
  29. }

ContentTypeUtils- Content-type 工具类

  1. package com.luoma.finance.util;
  2. import cn.hutool.core.util.CharsetUtil;
  3. import com.luoma.finance.data.ResponseCode;
  4. import com.luoma.finance.excepiton.RemoteBaseException;
  5. import java.io.UnsupportedEncodingException;
  6. import java.net.URLEncoder;
  7. /**
  8. * Content-type 工具类
  9. */
  10. public final class ContentTypeUtils {
  11. public static final String CONTENT_DISPOSITION;
  12. public static final String APPLICATION_EXCEL;
  13. static {
  14. CONTENT_DISPOSITION = "Content-Disposition";
  15. APPLICATION_EXCEL = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
  16. }
  17. public static String encode(String fileName) {
  18. try {
  19. return "attachment;filename=" + URLEncoder.encode(fileName, CharsetUtil.UTF_8)
  20. + ".xlsx";
  21. } catch (UnsupportedEncodingException e) {
  22. throw new RemoteBaseException(ResponseCode.UNKNOWN_EXCEPTION, e.getMessage());
  23. }
  24. }
  25. }

ExcelSheetVerticalCellStyleStrategy-excel 样式设置

  1. package com.luoma.finance.util.excel;
  2. import com.alibaba.excel.metadata.Head;
  3. import com.alibaba.excel.write.metadata.style.WriteCellStyle;
  4. import com.alibaba.excel.write.style.AbstractVerticalCellStyleStrategy;
  5. import com.luoma.finance.util.ExcelUtils;
  6. /**
  7. * excel 样式设置
  8. */
  9. public class ExcelSheetVerticalCellStyleStrategy extends AbstractVerticalCellStyleStrategy {
  10. /**
  11. * 头部样式
  12. *
  13. * @return 样式
  14. */
  15. @Override
  16. protected WriteCellStyle headCellStyle(Head head) {
  17. return ExcelUtils.writeCellStyle();
  18. }
  19. /**
  20. * 内容样式
  21. *
  22. * @return 样式
  23. */
  24. @Override
  25. protected WriteCellStyle contentCellStyle(Head head) {
  26. return ExcelUtils.writeCellStyle();
  27. }
  28. }

ExcelUtils-excel 工具类

  1. package com.luoma.finance.util;
  2. import cn.hutool.core.util.CharsetUtil;
  3. import com.alibaba.excel.EasyExcel;
  4. import com.alibaba.excel.support.ExcelTypeEnum;
  5. import com.alibaba.excel.write.builder.ExcelWriterBuilder;
  6. import com.alibaba.excel.write.metadata.style.WriteCellStyle;
  7. import com.google.common.collect.Lists;
  8. import com.luoma.finance.common.Contents;
  9. import com.luoma.finance.data.ResponseCode;
  10. import com.luoma.finance.excepiton.InternalApiException;
  11. import com.luoma.finance.util.excel.ExcelSheetVerticalCellStyleStrategy;
  12. import com.luoma.finance.vo.report.ExcelHead;
  13. import org.apache.poi.ss.usermodel.BorderStyle;
  14. import org.apache.poi.ss.usermodel.HorizontalAlignment;
  15. import org.apache.poi.ss.usermodel.VerticalAlignment;
  16. import javax.servlet.http.HttpServletResponse;
  17. import java.io.IOException;
  18. import java.util.ArrayList;
  19. import java.util.List;
  20. import java.util.Map;
  21. /**
  22. * excel 工具类
  23. */
  24. public class ExcelUtils {
  25. /**
  26. * 单 sheet 导出公共方法
  27. *
  28. * @param list 导出数据集合
  29. * @param tClass 数据对象类型
  30. * @param fileName 文件名称
  31. * @param sheetName sheet页名称
  32. * @param response http写入
  33. * @param <T> 数据对象类型
  34. */
  35. public static <T> void applyExport(List<T> list, Class<T> tClass, String fileName, String sheetName,
  36. HttpServletResponse response) {
  37. if (null == list || list.size() <= 0) {
  38. throw new InternalApiException(ResponseCode.NO_DATA, Contents.EXPORT_NULL);
  39. }
  40. ExcelSheetVerticalCellStyleStrategy cellStyleStrategy = new ExcelSheetVerticalCellStyleStrategy();
  41. response.setCharacterEncoding(CharsetUtil.UTF_8);
  42. response.setContentType(ContentTypeUtils.APPLICATION_EXCEL);
  43. try {
  44. response.setHeader(ContentTypeUtils.CONTENT_DISPOSITION, ContentTypeUtils.encode(fileName));
  45. EasyExcel.write(response.getOutputStream(), tClass).sheet(sheetName).registerWriteHandler(cellStyleStrategy)
  46. .doWrite(list);
  47. } catch (IOException e) {
  48. throw new InternalApiException(ResponseCode.OPERATE_ERROR, e.getMessage());
  49. }
  50. }
  51. /**
  52. * 构造excel基础样式
  53. *
  54. * @return 样式
  55. */
  56. public static WriteCellStyle writeCellStyle() {
  57. WriteCellStyle writeCellStyle = new WriteCellStyle();
  58. writeCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
  59. writeCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
  60. writeCellStyle.setWrapped(true);
  61. writeCellStyle.setBorderBottom(BorderStyle.THIN);
  62. writeCellStyle.setBorderLeft(BorderStyle.THIN);
  63. writeCellStyle.setBorderRight(BorderStyle.THIN);
  64. writeCellStyle.setBorderTop(BorderStyle.THIN);
  65. return writeCellStyle;
  66. }
  67. /**
  68. * 导出 excel
  69. *
  70. * @param fileName 文件名称
  71. * @param headList 表头数据
  72. * @param dataList 表数据
  73. * @param response HttpServletResponse
  74. */
  75. public static void export(String fileName,
  76. List<ExcelHead> headList,
  77. List<Map<String, Object>> dataList,
  78. HttpServletResponse response) {
  79. try {
  80. response.setCharacterEncoding(CharsetUtil.UTF_8);
  81. response.setContentType(ContentTypeUtils.APPLICATION_EXCEL);
  82. response.setHeader(ContentTypeUtils.CONTENT_DISPOSITION, ContentTypeUtils.encode(fileName));
  83. ExcelWriterBuilder writerBuilder = EasyExcel.write();
  84. writerBuilder.file(response.getOutputStream());
  85. writerBuilder.excelType(ExcelTypeEnum.XLSX);
  86. writerBuilder.autoCloseStream(true);
  87. ExcelSheetVerticalCellStyleStrategy cellStyleStrategy = new ExcelSheetVerticalCellStyleStrategy();
  88. writerBuilder.registerWriteHandler(cellStyleStrategy);
  89. writerBuilder
  90. .head(convertHead(headList))
  91. .sheet("sheet1")
  92. .doWrite(convertData(headList, dataList));
  93. } catch (IOException e) {
  94. throw new InternalApiException(ResponseCode.OPERATE_ERROR, e.getMessage());
  95. }
  96. }
  97. /**
  98. * 写 excel
  99. *
  100. * @param filePath 保存的路径名
  101. * @param headList 表头数据
  102. * @param dataList 表数据
  103. */
  104. public static void write(String filePath, List<ExcelHead> headList, List<Map<String, Object>> dataList) {
  105. ExcelWriterBuilder writerBuilder = EasyExcel.write();
  106. writerBuilder.file(filePath);
  107. writerBuilder.excelType(ExcelTypeEnum.XLSX);
  108. writerBuilder.autoCloseStream(true);
  109. writerBuilder.head(convertHead(headList))
  110. .sheet("sheet1")
  111. .doWrite(convertData(headList, dataList));
  112. }
  113. /**
  114. * 会先删除 excel 所有 sheet,再写入
  115. *
  116. * @param filePath 保存的路径名
  117. * @param sheetName sheetName
  118. * @param c 数据对象类型
  119. * @param list 导出数据集合
  120. * @param <T> 数据对象类型
  121. */
  122. public static <T> void writeSheet(String filePath, String sheetName, Class<T> c, List<T> list) {
  123. EasyExcel.write(filePath, c).sheet(sheetName).doWrite(list);
  124. }
  125. /**
  126. * 表头数据转换
  127. * https://easyexcel.opensource.alibaba.com/docs/current/quickstart/write#%E5%8A%A8%E6%80%81%E5%A4%B4%E5%AE%9E%E6%97%B6%E7%94%9F%E6%88%90%E5%A4%B4%E5%86%99%E5%85%A5
  128. *
  129. * @param headList 表头数据
  130. * @return List<List < String>>
  131. */
  132. private static List<List<String>> convertHead(List<ExcelHead> headList) {
  133. List<List<String>> list = new ArrayList<>();
  134. for (ExcelHead head : headList) {
  135. list.add(Lists.newArrayList(head.getTitle()));
  136. }
  137. //沒有搞清楚 head 的参数为 List<List<String>>,用 List<String> 就 OK 了
  138. return list;
  139. }
  140. /**
  141. * 表内容数据转换
  142. *
  143. * @param headList 表头数据
  144. * @param dataList 表内容数据转换
  145. * @return List<List<Object>>
  146. */
  147. private static List<List<Object>> convertData(List<ExcelHead> headList,
  148. List<Map<String, Object>> dataList) {
  149. List<List<Object>> result = new ArrayList();
  150. //对 dataList 转为 easyExcel 的数据格式
  151. for (Map<String, Object> data : dataList) {
  152. List<Object> row = new ArrayList();
  153. for (ExcelHead h : headList) {
  154. Object o = data.get(h.getFieldName());
  155. //需要对null的处理,比如age的null,要转为-1
  156. row.add(handler(o, h.getNullValue()));
  157. }
  158. result.add(row);
  159. }
  160. return result;
  161. }
  162. /**
  163. * null 值处理
  164. *
  165. * @param 对象
  166. * @param nullValue 默认值
  167. * @return 默认值
  168. */
  169. private static Object handler(Object o, Object nullValue) {
  170. return o != null ? o : nullValue;
  171. }
  172. }

测试

导出 Excel 到本地

  1. public static void main(String[] args) {
  2. String filePath = "d:\\temp\\a.xlsx";
  3. //表头数据
  4. List<ExcelHead> headList = new ArrayList();
  5. headList.add(new ExcelHead<String>("name", "名称"));
  6. headList.add(new ExcelHead("age", "年龄", -1));
  7. //表内容数据
  8. List<Map<String, Object>> dataList = new ArrayList();
  9. Map<String, Object> one = new HashMap();
  10. one.put("name", "张三");
  11. one.put("age", 20);
  12. dataList.add(one);
  13. Map<String, Object> two = new HashMap();
  14. two.put("name", "李四");
  15. two.put("age", 18);
  16. dataList.add(two);
  17. Map<String, Object> there = new HashMap();
  18. there.put("name", "不知道年龄");
  19. there.put("age", null);
  20. dataList.add(there);
  21. //保存 excel 到指定路径
  22. ExcelUtils.write(filePath, headList, dataList);
  23. }
  • 运行后,打开 a.xlsx

浏览器导出 Excel

  1. package com.luoma.finance.controller;
  2. import io.swagger.annotations.ApiOperation;
  3. import lombok.extern.slf4j.Slf4j;
  4. import org.springframework.validation.annotation.Validated;
  5. import org.springframework.web.bind.annotation.*;
  6. import javax.annotation.Resource;
  7. import javax.servlet.http.HttpServletResponse;
  8. import java.util.ArrayList;
  9. import java.util.HashMap;
  10. import java.util.List;
  11. import java.util.Map;
  12. /**
  13. * 控制器 - 报表 - 还款计划报表
  14. */
  15. @Slf4j
  16. @RestController
  17. @RequestMapping("/api/repaymentPlanReport")
  18. public class RepaymentPlanReportController {
  19. @GetMapping("/testExport")
  20. public void testExport(HttpServletResponse response) {
  21. //表头数据
  22. List<ExcelHead> headList = new ArrayList();
  23. headList.add(new ExcelHead<String>("name", "名称"));
  24. headList.add(new ExcelHead("age", "年龄", -1));
  25. //表内容数据
  26. List<Map<String, Object>> dataList = new ArrayList();
  27. Map<String, Object> one = new HashMap();
  28. one.put("name", "张三");
  29. one.put("age", 20);
  30. dataList.add(one);
  31. Map<String, Object> two = new HashMap();
  32. two.put("name", "李四");
  33. two.put("age", 18);
  34. dataList.add(two);
  35. Map<String, Object> there = new HashMap();
  36. there.put("name", "不知道年龄");
  37. there.put("age", null);
  38. dataList.add(there);
  39. //导出 excel
  40. ExcelUtils.export("testExcel", headList, dataList, response);
  41. }
  42. }

非注解方式数据格式化

修改 ExcelHead-动态 excel 表头

  1. package com.luoma.finance.vo.report;
  2. import lombok.Data;
  3. /**
  4. * Excel 导出表头类 - ExcelHead
  5. * v_hwhao - 2023年06月03日19:26:06
  6. */
  7. @Data
  8. public class ExcelHead<T> {
  9. /**
  10. * 内容里的字段名称
  11. */
  12. private String fieldName;
  13. /**
  14. * 显示值,一般为中文的
  15. */
  16. private String title;
  17. /**
  18. * 列类型
  19. * 从 BuiltinFormats 的 BUILTIN_FORMATS_CN[] 获取
  20. * 序号参考:https://blog.csdn.net/ruantiao3440/article/details/126704369
  21. * 快速根据索引获取字符串、或根据字符串获取索引
  22. * int builtinFormat = BuiltinFormats.getBuiltinFormat("h:mm:ss AM/PM");
  23. * System.out.println(builtinFormat);
  24. * String builtinFormat1 = BuiltinFormats.getBuiltinFormat(49);
  25. * System.out.println(builtinFormat1);
  26. */
  27. private String dataFormat;
  28. /**
  29. * 字体颜色
  30. */
  31. private String fontColor;
  32. /**
  33. * 对齐方式,right:右对齐
  34. */
  35. private String alignment;
  36. /**
  37. * 如果为 null 的值
  38. */
  39. private T nullValue;
  40. public ExcelHead(String fieldName, String title, String dataFormat) {
  41. this.fieldName = fieldName;
  42. this.title = title;
  43. this.dataFormat = dataFormat;
  44. }
  45. public ExcelHead(String fieldName, String title, String dataFormat, T nullValue) {
  46. this.fieldName = fieldName;
  47. this.title = title;
  48. this.dataFormat = dataFormat;
  49. this.nullValue = nullValue;
  50. }
  51. public ExcelHead(){}
  52. }

修改表头定义

  1. @GetMapping("/testExport")
  2. public void testExport(HttpServletResponse response) {
  3. //表头数据
  4. List<ExcelHead> headList = new ArrayList();
  5. headList.add(new ExcelHead<String>("name", "名称",null));
  6. ExcelHead<BigDecimal> ageHead = new ExcelHead<BigDecimal>("age", "年龄","4");
  7. ageHead.setFontColor("red");
  8. headList.add(ageHead);
  9. //表内容数据
  10. List<Map<String, Object>> dataList = new ArrayList();
  11. Map<String, Object> one = new HashMap();
  12. one.put("name", "张三");
  13. one.put("age", new BigDecimal("11111.23456789"));
  14. dataList.add(one);
  15. Map<String, Object> two = new HashMap();
  16. two.put("name", "李四");
  17. two.put("age", new BigDecimal("11122.23456"));
  18. dataList.add(two);
  19. Map<String, Object> there = new HashMap();
  20. there.put("name", "不知道年龄");
  21. there.put("age", null);
  22. dataList.add(there);
  23. //浏览器下载导出 excel
  24. ExcelUtils.export("testExcel", headList, dataList, response);
  25. }

新增样式设置类-RepaymentPlanExcelStyle

  1. package com.luoma.finance.vo.report;
  2. import com.alibaba.excel.metadata.Head;
  3. import com.alibaba.excel.write.metadata.style.WriteCellStyle;
  4. import com.alibaba.excel.write.metadata.style.WriteFont;
  5. import com.alibaba.excel.write.style.AbstractVerticalCellStyleStrategy;
  6. import com.luoma.finance.util.CommonUtil;
  7. import com.luoma.finance.util.ExcelUtils;
  8. import org.apache.poi.ss.usermodel.BorderStyle;
  9. import org.apache.poi.ss.usermodel.HorizontalAlignment;
  10. import org.apache.poi.ss.usermodel.IndexedColors;
  11. import org.apache.poi.ss.usermodel.VerticalAlignment;
  12. import java.util.List;
  13. /**
  14. * Excel 样式设置 - 还款计划表
  15. */
  16. public class RepaymentPlanExcelStyle extends AbstractVerticalCellStyleStrategy {
  17. /**
  18. * 表头数据
  19. */
  20. private List<ExcelHead> headList;
  21. public RepaymentPlanExcelStyle(List<ExcelHead> headList) {
  22. this.headList = headList;
  23. }
  24. /**
  25. * 头部样式
  26. *
  27. * @return 样式
  28. */
  29. @Override
  30. protected WriteCellStyle headCellStyle(Head head) {
  31. WriteCellStyle writeCellStyle = new WriteCellStyle();
  32. writeCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);//水平居中
  33. writeCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
  34. //writeCellStyle.setWrapped(true);//自动换行
  35. writeCellStyle.setBorderBottom(BorderStyle.THIN);//下边框
  36. writeCellStyle.setBorderLeft(BorderStyle.THIN);//左边框
  37. writeCellStyle.setBorderRight(BorderStyle.THIN);//右边框
  38. writeCellStyle.setBorderTop(BorderStyle.THIN);//上边框
  39. writeCellStyle.setShrinkToFit(true);//设置文本收缩至合适
  40. return writeCellStyle;
  41. }
  42. /**
  43. * 内容样式
  44. *
  45. * @return 样式
  46. */
  47. @Override
  48. protected WriteCellStyle contentCellStyle(Head head) {
  49. //默认样式
  50. WriteCellStyle writeCellStyle = ExcelUtils.writeCellStyle();
  51. int columnIndex = 0;
  52. for (ExcelHead itemColumn : headList) {
  53. //数据格式化代码
  54. String dataFormat = itemColumn.getDataFormat();
  55. if(CommonUtil.isNotNull(dataFormat)){
  56. if(columnIndex == head.getColumnIndex()) {
  57. writeCellStyle.setDataFormat(Short.valueOf(dataFormat));
  58. }
  59. }
  60. //字体颜色
  61. String fontRed = itemColumn.getFontColor();
  62. if(CommonUtil.isNotNull(fontRed) && "red".equals(fontRed)){
  63. if(columnIndex == head.getColumnIndex()) {
  64. WriteFont font = new WriteFont();
  65. font.setColor(IndexedColors.RED.getIndex()); //红色
  66. writeCellStyle.setWriteFont(font);
  67. }
  68. }
  69. //对齐方式
  70. String alignment = itemColumn.getAlignment();
  71. if(CommonUtil.isNotNull(alignment) && Contents.alignmentRight.equals(alignment)){
  72. if(columnIndex == head.getColumnIndex()) {
  73. writeCellStyle.setHorizontalAlignment(HorizontalAlignment.RIGHT);
  74. }
  75. }
  76. columnIndex++;
  77. }
  78. //if(head.getColumnIndex() == 1) {
  79. // //------------------------字体设置
  80. // WriteFont font = new WriteFont();
  81. // font.setColor(IndexedColors.RED.getIndex()); //红色
  82. // writeCellStyle.setWriteFont(font);
  83. //
  84. // //------------------------千分位设置
  85. // //序号:4,从 BuiltinFormats 的 BUILTIN_FORMATS_CN[] 获取
  86. // //https://blog.csdn.net/ruantiao3440/article/details/126704369
  87. // //BuiltinFormats.getBuiltinFormat(4,"#,##0.00", Locale.SIMPLIFIED_CHINESE);
  88. // //writeCellStyle.setDataFormat((short)4);
  89. //}
  90. return writeCellStyle;
  91. }
  92. }

修改 ExcelUtils 中 export 方法

  1. /**
  2. * excel工具类
  3. */
  4. public class ExcelUtils {
  5. //其它代码省略
  6. /**
  7. * 导出 excel
  8. *
  9. * @param fileName 文件名称
  10. * @param headList 表头数据
  11. * @param dataList 表数据
  12. * @param response HttpServletResponse
  13. */
  14. public static void export(String fileName,
  15. List<ExcelHead> headList,
  16. List<Map<String, Object>> dataList,
  17. HttpServletResponse response) {
  18. try {
  19. response.setCharacterEncoding(CharsetUtil.UTF_8);
  20. response.setContentType(ContentTypeUtils.APPLICATION_EXCEL);
  21. response.setHeader(ContentTypeUtils.CONTENT_DISPOSITION, ContentTypeUtils.encode(fileName));
  22. ExcelWriterBuilder writerBuilder = EasyExcel.write();
  23. writerBuilder.file(response.getOutputStream());
  24. writerBuilder.excelType(ExcelTypeEnum.XLSX);
  25. writerBuilder.autoCloseStream(true);
  26. RepaymentPlanExcelStyle cellStyleStrategy = new RepaymentPlanExcelStyle(headList);
  27. writerBuilder.registerWriteHandler(cellStyleStrategy);
  28. writerBuilder
  29. .head(convertHead(headList))
  30. .sheet("sheet1")
  31. .doWrite(convertData(headList, dataList));
  32. } catch (IOException e) {
  33. throw new InternalApiException(ResponseCode.OPERATE_ERROR, e.getMessage());
  34. }
  35. }
  36. }

测试

非注解方式定义列宽和行高

参考:使用 easyExcel write 步骤;并且设置列宽

修改 ExcelUtils 中 export 方法

  1. public class ExcelUtils {
  2. //其它代码省略
  3. /**
  4. * 导出 excel
  5. *
  6. * @param fileName 文件名称
  7. * @param headList 表头数据
  8. * @param dataList 表数据
  9. * @param response HttpServletResponse
  10. */
  11. public static void export(String fileName,
  12. List<ExcelHead> headList,
  13. List<Map<String, Object>> dataList,
  14. HttpServletResponse response) {
  15. try {
  16. response.setCharacterEncoding(CharsetUtil.UTF_8);
  17. response.setContentType(ContentTypeUtils.APPLICATION_EXCEL);
  18. response.setHeader(ContentTypeUtils.CONTENT_DISPOSITION, ContentTypeUtils.encode(fileName));
  19. ExcelWriterBuilder writerBuilder = EasyExcel.write();
  20. writerBuilder.file(response.getOutputStream());
  21. writerBuilder.excelType(ExcelTypeEnum.XLSX);
  22. writerBuilder.autoCloseStream(true);
  23. RepaymentPlanExcelStyle cellStyleStrategy = new RepaymentPlanExcelStyle(headList);
  24. writerBuilder.registerWriteHandler(cellStyleStrategy);
  25. writerBuilder
  26. //表头
  27. .head(convertHead(headList))
  28. //sheet
  29. .sheet("sheet1")
  30. //注册策略——简单的列宽策略,列宽 25
  31. .registerWriteHandler(new SimpleColumnWidthStyleStrategy(25))
  32. //注册策略——简单的行高策略,头行高 30,内容行高 20
  33. //.registerWriteHandler(new SimpleRowHeightStyleStrategy((short)30,(short)20))
  34. //写数据
  35. .doWrite(convertData(headList, dataList));
  36. } catch (IOException e) {
  37. throw new InternalApiException(ResponseCode.OPERATE_ERROR, e.getMessage());
  38. }
  39. }
  40. }

非注解方式自定义数据格式【未完成】

  • 比如我先设置百分比的位数为 5 位,通过 BuiltinFormats 中查询,得到最多就是保留 2 为小数
  1. // 68
  2. "t0.00%",
  • 假如我想要这种格式呢?"t0.0000%",没有。

  • 想解决这个问题,我找了百度和谷歌几乎所有答案,看官方文档,都没有

  • 最后的结论是,不行

  • 即使 >@ContentStyle注解的dataFormat,除了内建的BuiltinFormats格式之外,是否支持自定义格式呢 中提到的,可以通过在 CellWriteHandler中覆盖 dataFormat。最终也是不行的。也还是只能支持 BuiltinFormats 中的格式。

  • 折中的解决方案是,把这一列转换为文本,把百分比数据 0.000123 直接转换成字符串 0.0123%,直接写入到单元格中,同时把这个一列设置为文本

  1. ExcelHead<BigDecimal> ageHead = new ExcelHead<BigDecimal>("age", "年龄","49");
  2. ageHead.setFontColor("red");
  3. headList.add(ageHead);
  4. //表内容数据
  5. List<Map<String, Object>> dataList = new ArrayList();
  6. Map<String, Object> one = new HashMap();
  7. one.put("name", "张三111111111111111111111111111111111");
  8. one.put("age", "0.110123%");
  9. dataList.add(one);
  • 49 对应的 BuiltinFormats
  1. // 49
  2. "@",

这样的效果效果并不是想要的

注解方式自定义数据格式【未完成】

EasyExcel注解方式导出数据过程解析

ExcelTestVO

  1. package com.luoma.finance.vo.report;
  2. import com.alibaba.excel.annotation.ExcelIgnore;
  3. import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
  4. import com.alibaba.excel.annotation.ExcelProperty;
  5. import com.alibaba.excel.annotation.format.NumberFormat;
  6. import com.alibaba.excel.annotation.write.style.ColumnWidth;
  7. import com.alibaba.excel.annotation.write.style.ContentRowHeight;
  8. import com.alibaba.excel.annotation.write.style.ContentStyle;
  9. import com.alibaba.excel.annotation.write.style.HeadRowHeight;
  10. import lombok.Data;
  11. import java.math.BigDecimal;
  12. /**
  13. * Excel 导出类 - 测试类
  14. */
  15. @Data
  16. @ColumnWidth(25)
  17. @ContentRowHeight(25)
  18. @HeadRowHeight(45)
  19. @ExcelIgnoreUnannotated
  20. public class ExcelTestVO {
  21. @ExcelProperty(value = "姓名")
  22. private String name;
  23. @NumberFormat(value = "#,##0.00")//千分位,保留 2 位小数
  24. @ExcelProperty(value = "金额")
  25. private BigDecimal amount;
  26. /**
  27. * 这个数值格式化注解时内置转换器使用,当没有配置自定义转换器converter时
  28. * 会根据field.getType类型+ String匹配内置的转换器。如 DoubleStringConverter
  29. */
  30. @ExcelProperty(value = "汇率")
  31. @NumberFormat(value = "#.#####%")//自定义格式,转换为百分比,保留 5 位小数
  32. private BigDecimal rate;
  33. @ExcelIgnore//不包含到导出列中
  34. private String remark;
  35. }

导出接口

  1. @GetMapping("/testExportModel")
  2. public void testExportModel(HttpServletResponse response) {
  3. List<ExcelTestVO> list = new ArrayList<>();
  4. ExcelTestVO vo = new ExcelTestVO();
  5. vo.setName("张三");
  6. vo.setAmount(new BigDecimal("6666.6666"));
  7. vo.setRate(new BigDecimal("0.0001234"));
  8. vo.setRemark("test1");
  9. list.add(vo);
  10. vo = new ExcelTestVO();
  11. vo.setName("李四");
  12. vo.setAmount(new BigDecimal("7777.7777"));
  13. vo.setRate(new BigDecimal("0.0005678"));
  14. vo.setRemark("test2");
  15. list.add(vo);
  16. ExcelUtils.applyExport(list, ExcelTestVO.class,
  17. "testExportModel", "testExportModel", response);
  18. }

导出效果

也不是我想要的效果