需求
將業務數據導出到excel中,老牌的可以選擇POI,也有個新的選擇EasyExcel。
有個小坑,客戶要求樣式比較美觀,數字列要求千位符,保留2位小數。
可以用代碼實現但非常繁瑣,用模板就特別方便,模板定義好格式,填充數據即可。
于是開干!
模板
在項目的src\main\resources\templates,靜態模板資源目錄下,如果templates不存在,創建即可
settle.xlsx
注意下面的模板格式,填充列表,下面{.name}代表entity對應的字段
修改Entity實體,加控制注解
注意兩個注解:
@ExcelIgnore 標識這個字段不會處理
@ExcelProperty(“結算金額”) 要處理的字段,已經如果寫入時,列頭的名稱
package com.rlcloud.system.entity;import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.Date;/*** @version v1.0 創建時間:2023/11/27 16:36* @author: 作者:陳子樞* @web CSDN:https://blog.csdn.net/nutony* @description 描述:*/@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("tb_settle") //映射數據庫表
public class Settle {//序列化時,不采用long類型,而采用string類型,防止雪花精度丟失問題@JsonSerialize(using= ToStringSerializer.class)@TableId(type = IdType.ASSIGN_ID) //主鍵生成策略,雪花@ExcelIgnoreprivate Long id;@NotNull(message = "結算批次不能為空")@ExcelProperty("結算批次")private String batch;@NotNull(message = "結算日期不能為空")@ExcelProperty("結算日期")private String dtTimeArr;@NotNull(message = "業務量不能為空")@ExcelProperty("業務量")private BigDecimal volumeAmt;@NotNull(message = "結算金額不能為空")@ExcelProperty("結算金額")private BigDecimal settleAmt;@ExcelIgnoreprivate String createBy;@ExcelIgnoreprivate Date createTime;
}
Controller代碼
@GetMapping("/ljt/settle/export")public void export(HttpServletResponse response) throws IOException {QueryWrapper qw = new QueryWrapper();qw.orderByDesc("create_time");//查詢數據List<Settle> dataList = settleService.list(qw);//此處getResourceAsStream 用于獲取服務器打包后的Excel模板文件流;//如果采用getPath方法獲取文件地址本地ieda環境可以獲取到,上傳到服務器后會失效。采用流可以都生效,具體原因暫未仔細查看。有興趣的童鞋可以自己去嘗試!InputStream resourceAsStream = ResourceUtil.getStream("classpath:templates/settle.xlsx");//讀取Excel 根據指定模板導出ExcelWriter excelWriter = EasyExcel.write(getOutputStream("結算數據.xlsx",response)).withTemplate(resourceAsStream).excelType(ExcelTypeEnum.XLSX).build();WriteSheet writeSheet = EasyExcel.writerSheet().build();FillConfig fillConfig = FillConfig.builder().forceNewRow(true).build(); //關鍵,多組數據填充需要另起一行,默認為false//直接寫入Excel數據(list是我查詢并需導出的數據,并且里面的字段和excel需要導出的字段對應)excelWriter.fill(dataList, fillConfig, writeSheet); //注意模板中需要寫變量{.name}excelWriter.finish();}public static OutputStream getOutputStream(String fileName, HttpServletResponse response) {try {fileName = URLEncoder.encode(fileName, "UTF-8");response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf8");response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".xls");response.setHeader("Pragma", "public");response.setHeader("Cache-Control", "no-store");response.addHeader("Cache-Control", "max-age=0");return response.getOutputStream();} catch (IOException e) {log.error("導出excel表格失敗", e);}return null;}