当前位置:   article > 正文

java easyexcel 基于excel模板填充数据 2023_java excel模板填充

java excel模板填充

基于excel模板填充数据,并下载,以及合计转大写工具类

【先看效果】

模板路径

模板样式 

源文件链接 ,Java共享中

share/Java共享icon-default.png?t=N7T8https://gitee.com/jiaketao/share.git

最终效果

废话少说上代码

1、pom依赖 主要是easyexcel  和 poi

  1. <!--easyExcel-->
  2. <dependency>
  3. <groupId>com.alibaba</groupId>
  4. <artifactId>easyexcel</artifactId>
  5. <version>3.3.2</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>com.alibaba</groupId>
  9. <artifactId>easyexcel-core</artifactId>
  10. <version>3.3.2</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>com.alibaba</groupId>
  14. <artifactId>easyexcel-support</artifactId>
  15. <version>3.3.2</version>
  16. </dependency>
  17. <!-- POI导入导出 -->
  18. <dependency>
  19. <groupId>org.apache.poi</groupId>
  20. <artifactId>poi</artifactId>
  21. <version>4.1.2</version>
  22. </dependency>
  23. <dependency>
  24. <groupId>org.apache.poi</groupId>
  25. <artifactId>poi-ooxml</artifactId>
  26. <version>4.1.2</version>
  27. </dependency>
  28. <dependency>
  29. <groupId>org.apache.poi</groupId>
  30. <artifactId>poi-ooxml-schemas</artifactId>
  31. <version>4.1.2</version>
  32. </dependency>
  33. <dependency>
  34. <groupId>org.apache.commons</groupId>
  35. <artifactId>commons-collections4</artifactId>
  36. <version>4.1</version>
  37. </dependency>
  38. <dependency>
  39. <groupId>cglib</groupId>
  40. <artifactId>cglib</artifactId>
  41. <version>3.1</version>
  42. </dependency>

2、新建 导出测试类

  1. import com.alibaba.excel.annotation.ExcelProperty;
  2. import com.alibaba.excel.annotation.write.style.ContentRowHeight;
  3. import com.alibaba.excel.annotation.write.style.HeadRowHeight;
  4. import com.baomidou.mybatisplus.annotation.TableName;
  5. import lombok.Data;
  6. import lombok.NoArgsConstructor;
  7. /**
  8. * 导出测试类
  9. */
  10. @Data
  11. @NoArgsConstructor
  12. @HeadRowHeight(30)
  13. @ContentRowHeight(22)
  14. @TableName("excel_demo_data")
  15. public class ExportTest {
  16. @ExcelProperty(index = 0, value = "序号")
  17. private Integer id;
  18. @ExcelProperty(index =1, value = "姓名")
  19. private String name;
  20. @ExcelProperty(index = 2, value = "数量")
  21. private Integer count;
  22. @ExcelProperty(index = 3, value = "价格")
  23. private float price;
  24. }

3、接口测试类

//配置多组数据填充完后,需要换行,防止覆盖模板中的单组数据模板
FillConfig fillConfig = FillConfig.builder().forceNewRow(true).build();

这一行很重要,true是追加,false是覆盖,会覆盖主下边的合计

  1. import com.alibaba.excel.EasyExcel;
  2. import com.alibaba.excel.ExcelWriter;
  3. import com.alibaba.excel.write.metadata.WriteSheet;
  4. import com.alibaba.excel.write.metadata.fill.FillConfig;
  5. import com.alibaba.fastjson.JSON;
  6. import com.sun.deploy.net.URLEncoder;
  7. import com.xiaoqiu.juyihoutai.pojo.*;
  8. import com.xiaoqiu.juyihoutai.utils.ChineseMoneyUtils;
  9. import io.swagger.annotations.Api;
  10. import io.swagger.annotations.ApiOperation;
  11. import org.springframework.web.bind.annotation.GetMapping;
  12. import org.springframework.web.bind.annotation.RequestMapping;
  13. import org.springframework.web.bind.annotation.RestController;
  14. import javax.servlet.http.HttpServletResponse;
  15. import java.io.IOException;
  16. import java.math.BigDecimal;
  17. import java.util.ArrayList;
  18. import java.util.HashMap;
  19. import java.util.List;
  20. import java.util.Map;
  21. @Api("测试导出excel")
  22. @RestController
  23. @RequestMapping("/test")
  24. public class TestController {
  25. @ApiOperation("导出excel")
  26. @GetMapping
  27. public void exportToExcel(HttpServletResponse response) throws IOException {
  28. //要导出的数据
  29. List<ExportTest> exportTestList = (List<ExportTest>) getData().get("exportTestList");
  30. //模板文件
  31. InputStream templateFile = Thread.currentThread().getContextClassLoader().getResourceAsStream("template/template.xlsx");
  32. //导出后的文件名
  33. String fileName = exportTestList.get(0).getName() + "模板";
  34. //写入
  35. ExcelWriter excelWriter = null;
  36. try {
  37. //本地导出
  38. //excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build();
  39. //流输出
  40. excelWriter = EasyExcel.write(response.getOutputStream())
  41. .withTemplate(templateFile )
  42. .build();
  43. WriteSheet writeSheet = EasyExcel.writerSheet().build();
  44. //配置多组数据填充完后,需要换行,防止覆盖模板中的单组数据模板
  45. FillConfig fillConfig = FillConfig.builder().forceNewRow(true).build();
  46. // 直接写入list数据
  47. excelWriter.fill(exportTestList, fillConfig, writeSheet);
  48. // 写入自定义的表头
  49. Map<String, Object> map = new HashMap<>();
  50. map.put("template", "测试");
  51. map.put("date", "2023-12-15 12:12:00");
  52. map.put("sumAmountChinese", getData().get("sumAmountChinese"));
  53. map.put("sumAmount", getData().get("sumAmount"));
  54. excelWriter.fill(map, writeSheet);
  55. //浏览器下载操作
  56. response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
  57. response.setCharacterEncoding("utf-8");
  58. // 这里URLEncoder.encode可以防止中文乱码
  59. fileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
  60. response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
  61. excelWriter.finish();
  62. } catch (Exception e) {
  63. // 重置response
  64. response.reset();
  65. response.setContentType("application/json");
  66. response.setCharacterEncoding("utf-8");
  67. Map<String, String> map = new HashMap<String, String>();
  68. map.put("status", "failure");
  69. map.put("message", "下载文件失败" + e.getMessage());
  70. response.getWriter().println(JSON.toJSONString(map));
  71. } finally {
  72. // 千万别忘记关闭流
  73. if (excelWriter != null) {
  74. excelWriter.finish();
  75. }
  76. }
  77. }
  78. /**
  79. * 获取要导出的数据
  80. */
  81. public HashMap getData() {
  82. HashMap hashMap = new HashMap<>();
  83. List<ExportTest> exportTestList = new ArrayList<>();
  84. for (int i = 1; i < 10; i++) {
  85. ExportTest exportTest = new ExportTest();
  86. exportTest.setId(i);
  87. exportTest.setName("小明" + i);
  88. exportTest.setCount(i);
  89. exportTest.setPrice(5);
  90. exportTestList.add(exportTest);
  91. }
  92. float sumAmount = 0;
  93. for (ExportTest exportTest : exportTestList) {
  94. sumAmount += exportTest.getPrice();
  95. }
  96. hashMap.put("exportTestList", exportTestList);
  97. //合计
  98. hashMap.put("sumAmount", sumAmount);
  99. //合计大写转换
  100. hashMap.put("sumAmountChinese", ChineseMoneyUtils.toChineseMoney(BigDecimal.valueOf(sumAmount)));
  101. return hashMap;
  102. }
  103. }
如果模板数据(例如模板规定9行)超出,进行分组写入
  1. //存储前9条的数据列表
  2. List<ExportOrder> exportOrderList9 = new ArrayList<>();
  3. //存储9条以后的数据列表
  4. List<ExportOrder> exportOrderList10 = new ArrayList<>();
  5. // 如果列表数据数量大于9,分两次方式写入,前9条覆盖写入,9条以后追加不覆盖写入
  6. if (exportOrderList.size() > 9) {
  7. //9条覆盖写入
  8. for (int i = 0; i < 9; i++) {
  9. exportOrderList9.add(exportOrderList.get(i));
  10. }
  11. //9条以后追加不覆盖写入
  12. for (int i = 9; i < exportOrderList.size(); i++) {
  13. exportOrderList10.add(exportOrderList.get(i));
  14. }
  15. //配置多组数据填充完后,需要换行,false防止覆盖模板中的单组数据模板
  16. FillConfig fillConfig = FillConfig.builder().forceNewRow(false).build();
  17. excelWriter.fill(exportOrderList9, fillConfig, writeSheet);
  18. //配置多组数据填充完后,需要换行,true覆盖模板中的单组数据模板
  19. FillConfig fillConfig2 = FillConfig.builder().forceNewRow(true).build();
  20. excelWriter.fill(exportOrderList10, fillConfig2, writeSheet);
  21. } else {
  22. //配置多组数据填充完后,需要换行,false防止覆盖模板中的单组数据模板
  23. FillConfig fillConfig = FillConfig.builder().forceNewRow(false).build();
  24. // 如果列表数据数量小于9,覆盖写入
  25. excelWriter.fill(exportOrderList, fillConfig, writeSheet);
  26. }

4、工具类:合计金额大写转换

  1. import java.math.BigDecimal;
  2. import java.math.RoundingMode;
  3. /**
  4. * 合计金额 转中文大写工具类
  5. */
  6. public class ChineseMoneyUtils {
  7. /**
  8. * 中文数字
  9. */
  10. final static private String[] CHINESE_NUMBER = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
  11. /**
  12. * 中文数字单位
  13. */
  14. final static private String[] CHINESE_NUMBER_UNIT = {"", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟"};
  15. /**
  16. * 人民币单位
  17. */
  18. final static private String[] CHINESE_MONEY_UNIT = {"圆", "角", "分"};
  19. // public static void main(String[] args) {
  20. // String chineseMoney = toChineseMoney(new BigDecimal("7068.52"));
  21. // System.out.println("chineseMoney = " + chineseMoney);
  22. // }
  23. /**
  24. * @param sourceMoney 要转换的数值,最多支持到亿
  25. * @return 结果
  26. */
  27. public static String toChineseMoney(BigDecimal sourceMoney) {
  28. if (new BigDecimal("1000000000000").compareTo(sourceMoney) <= 0
  29. && BigDecimal.ZERO.compareTo(sourceMoney) >= 0) {
  30. throw new RuntimeException("支持转换的金额范围为0~1万亿");
  31. }
  32. StringBuilder sb = new StringBuilder();
  33. // 整数部分
  34. BigDecimal intPart = sourceMoney.setScale(0, RoundingMode.DOWN);
  35. // 小数部分
  36. BigDecimal decimalPart = sourceMoney.subtract(intPart).multiply(new BigDecimal(100)).setScale(0,
  37. RoundingMode.DOWN);
  38. // 处理整数部分圆
  39. if (intPart.compareTo(BigDecimal.ZERO) > 0) {
  40. String intPartNumberString = intPart.toPlainString();
  41. int length = intPartNumberString.length();
  42. // 统计末尾的零,末尾零不做处理
  43. int zeroCount = 0;
  44. for (int i = length - 1; i >= 0; i--) {
  45. int number = Integer.parseInt(String.valueOf(intPartNumberString.charAt(i)));
  46. if (number == 0) {
  47. zeroCount++;
  48. } else {
  49. break;
  50. }
  51. }
  52. for (int i = 0; i < length; i++) {
  53. // 如果转换到末尾0,则停止转换
  54. if (i + zeroCount == length) {
  55. break;
  56. }
  57. int number = Integer.parseInt(String.valueOf(intPartNumberString.charAt(i)));
  58. // 获取中文数字
  59. String chineseNumber = CHINESE_NUMBER[number];
  60. // 获取中文数字单位
  61. String chineseNumberUnit = CHINESE_NUMBER_UNIT[length - i - 1];
  62. sb.append(chineseNumber).append(chineseNumberUnit);
  63. }
  64. // 统计完后加上金额单位
  65. sb.append(CHINESE_MONEY_UNIT[0]);
  66. } else {
  67. sb.append(CHINESE_NUMBER[0]).append(CHINESE_MONEY_UNIT[0]);
  68. }
  69. // 处理小数部分
  70. if (decimalPart.compareTo(new BigDecimal(10)) >= 0) {
  71. //
  72. String jiao = decimalPart.toPlainString();
  73. int number = Integer.parseInt(String.valueOf(jiao.charAt(0)));
  74. if (number != 0) {
  75. String chineseNumber = CHINESE_NUMBER[number];
  76. sb.append(chineseNumber).append(CHINESE_MONEY_UNIT[1]);
  77. }
  78. //
  79. String fen = decimalPart.toPlainString();
  80. number = Integer.parseInt(String.valueOf(fen.charAt(1)));
  81. if (number != 0) {
  82. String chineseNumber = CHINESE_NUMBER[number];
  83. sb.append(chineseNumber).append(CHINESE_MONEY_UNIT[2]);
  84. }
  85. } else if (decimalPart.compareTo(BigDecimal.ZERO) > 0) {
  86. //
  87. String fen = decimalPart.toPlainString();
  88. int number = Integer.parseInt(String.valueOf(fen.charAt(0)));
  89. if (number != 0) {
  90. String chineseNumber = CHINESE_NUMBER[number];
  91. sb.append(chineseNumber).append(CHINESE_MONEY_UNIT[2]);
  92. }
  93. } else {
  94. sb.append("整");
  95. }
  96. return sb.toString();
  97. }
  98. }

5、生成接口,将接口复制到浏览器回车就会弹窗提示下载

点击1会跳转2,复制接口

打开效果如下

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/590449
推荐阅读
相关标签
  

闽ICP备14008679号