菜鸟的自我救赎,自从有了GPT,还是头一次一个bug写一天。
直接贴导出excel模板的完整案例
EasyExcel填充模板导出excel.xlsx / 导出excel模板
一、bug(不需要请跳过)
1.1 使用apache poi操作excel报错 java.lang.NoSuchMethodError: org.apache.logging.log4j.Logger.atTrace()Lorg/apache/logging/log4j/
1.2EasyPoi读取word时报错java.util.zip.ZipException: Unexpected record signature: 0X9
二、配置文件
xml
<!--以下代码为 使用easyExcel需要用到的包-->
<dependencies>
<!--排除自带低版本poi,解决依赖冲突问题-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.2</version>
<exclusions>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--添加适合的版本依赖-->
<!--排除自带低版本log4j-api,解决依赖冲突问题-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.2</version>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.2</version>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--添加适合的版本依赖-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.23.1</version>
</dependency>
</dependencies>
三、 excel模板
四、 模板存放路径
五、 代码
5.1 Controller
参数不需要可以去掉
java
@GetMapping("/excel/export/details")
public void excelExport(@RequestParam(name = "xxxx", required = false) String purchaseSeq, HttpServletResponse response) {
purchaseOrderService.excelExportDetails(purchaseSeq, response);
}
5.2 实体
java
package com.zetian.platform.modules.order.vo;
import java.io.Serializable;
import java.util.Date;
public class AdminPurchaseOrderDetailsExportDTO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 订单号
*/
private String purchaseSeq;
/**
* 下单门店
*/
private String orderStore;
/**
* 门店编码
*/
private String storeCode;
/**
* 联系人
*/
private String user;
/**
* 联系电话
*/
private String userMobile;
/**
* 门店类型
*/
private String storeType;
/**
* 收货地址
*/
private String userAddress;
/**
* 创建时间
*/
private Date createTime;
/**
* 发货日期
*/
private Date expectTime;
/**
* 订单状态
*/
private String orderStatus;
/**
* 订单来源
*/
private String orderSource;
/**
* 下单金额
*/
private String orderPrice;
/**
* 发货金额
*/
private String deliveryAmount;
/**
* 收货金额
*/
private String receivedAmount;
/**
* 司机
*/
private String driver;
/**
* 司机电话
*/
private String driverMobile;
/**
* 送货时间
*/
private Date deliveryTime;
/**
* 采购
*/
private String purchaseUser;
/**
* 采购电话
*/
private String purchaseMobile;
//TODO 详情部分 待添加
public String getPurchaseSeq() {
return purchaseSeq;
}
public void setPurchaseSeq(String purchaseSeq) {
this.purchaseSeq = purchaseSeq;
}
public String getOrderStore() {
return orderStore;
}
public void setOrderStore(String orderStore) {
this.orderStore = orderStore;
}
public String getStoreCode() {
return storeCode;
}
public void setStoreCode(String storeCode) {
this.storeCode = storeCode;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getUserMobile() {
return userMobile;
}
public void setUserMobile(String userMobile) {
this.userMobile = userMobile;
}
public String getStoreType() {
return storeType;
}
public void setStoreType(String storeType) {
this.storeType = storeType;
}
public String getUserAddress() {
return userAddress;
}
public void setUserAddress(String userAddress) {
this.userAddress = userAddress;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getExpectTime() {
return expectTime;
}
public void setExpectTime(Date expectTime) {
this.expectTime = expectTime;
}
public String getOrderStatus() {
return orderStatus;
}
public void setOrderStatus(String orderStatus) {
this.orderStatus = orderStatus;
}
public String getOrderSource() {
return orderSource;
}
public void setOrderSource(String orderSource) {
this.orderSource = orderSource;
}
public String getOrderPrice() {
return orderPrice;
}
public void setOrderPrice(String orderPrice) {
this.orderPrice = orderPrice;
}
public String getDeliveryAmount() {
return deliveryAmount;
}
public void setDeliveryAmount(String deliveryAmount) {
this.deliveryAmount = deliveryAmount;
}
public String getReceivedAmount() {
return receivedAmount;
}
public void setReceivedAmount(String receivedAmount) {
this.receivedAmount = receivedAmount;
}
public String getDriver() {
return driver;
}
public void setDriver(String driver) {
this.driver = driver;
}
public String getDriverMobile() {
return driverMobile;
}
public void setDriverMobile(String driverMobile) {
this.driverMobile = driverMobile;
}
public Date getDeliveryTime() {
return deliveryTime;
}
public void setDeliveryTime(Date deliveryTime) {
this.deliveryTime = deliveryTime;
}
public String getPurchaseUser() {
return purchaseUser;
}
public void setPurchaseUser(String purchaseUser) {
this.purchaseUser = purchaseUser;
}
public String getPurchaseMobile() {
return purchaseMobile;
}
public void setPurchaseMobile(String purchaseMobile) {
this.purchaseMobile = purchaseMobile;
}
}
5.3 Service
使用 @Value("classpath:xx/xx/xxx.xlsx") 获取文件路径
java
@Value("classpath:template/excel/ExportPurchaseOrderDetailsTemplate.xlsx")
private org.springframework.core.io.Resource templateResource;
方法
java
public void excelExportDetails(String purchaseSeq, HttpServletResponse response) {
try (InputStream templateInputStream = templateResource.getInputStream()) {
// 检查模板文件是否存在
if (!templateResource.exists()) {
throw new RuntimeException("模板文件不存在!路径为:" + templateResource.getDescription());
}
// 设置响应头,告诉浏览器这是一个文件下载请求
String fileName = URLEncoder.encode("导出采购订单详情", "UTF-8") + ".xlsx";
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
AdminPurchaseOrderDetailsExportDTO adminPurchaseOrderDetailsExportDTO = new AdminPurchaseOrderDetailsExportDTO();
adminPurchaseOrderDetailsExportDTO.setOrderStore("1");
adminPurchaseOrderDetailsExportDTO.setStoreCode("21321");
adminPurchaseOrderDetailsExportDTO.setUser("312321");
adminPurchaseOrderDetailsExportDTO.setUserMobile("12321");
adminPurchaseOrderDetailsExportDTO.setStoreType("321321");
adminPurchaseOrderDetailsExportDTO.setUserAddress("123123");
adminPurchaseOrderDetailsExportDTO.setCreateTime(new Date());
adminPurchaseOrderDetailsExportDTO.setExpectTime(new Date());
adminPurchaseOrderDetailsExportDTO.setOrderStatus("213213");
adminPurchaseOrderDetailsExportDTO.setOrderSource("21312");
adminPurchaseOrderDetailsExportDTO.setOrderPrice("12312");
adminPurchaseOrderDetailsExportDTO.setDeliveryAmount("312321");
adminPurchaseOrderDetailsExportDTO.setReceivedAmount("312321");
adminPurchaseOrderDetailsExportDTO.setDriver("21321");
adminPurchaseOrderDetailsExportDTO.setDriverMobile("12321");
adminPurchaseOrderDetailsExportDTO.setDeliveryTime(new Date());
adminPurchaseOrderDetailsExportDTO.setPurchaseUser("312312");
adminPurchaseOrderDetailsExportDTO.setPurchaseMobile("321321321");
try (ServletOutputStream outputStream = response.getOutputStream()) {
EasyExcelFactory.write(outputStream) // 将文件写入输出流,而不是文件路径
.withTemplate(templateInputStream) // 使用模板
.sheet() // 填充第一个sheet
.doFill(adminPurchaseOrderDetailsExportDTO); // 填充数据
}
} catch (Exception e) {
throw new RuntimeException("导出 Excel 文件失败", e);
}
}
六 测试
七 成果展示
八 导出列表数据
8.1 修改实体类
java
package com.zetian.platform.modules.order.vo;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* @author xxxxx
* @Description excel采购单详情 头部信息
* @since 2024/10/14 16:42
**/
public class AdminPurchaseOrderDetailsExportDTO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 订单号
*/
private String purchaseSeq;
/**
* 下单门店
*/
private String orderStore;
/**
* 门店编码
*/
private String storeCode;
/**
* 联系人
*/
private String user;
/**
* 联系电话
*/
private String userMobile;
/**
* 门店类型
*/
private String storeType;
/**
* 收货地址
*/
private String userAddress;
/**
* 创建时间
*/
private Date createTime;
/**
* 发货日期
*/
private Date expectTime;
/**
* 订单状态
*/
private String orderStatus;
/**
* 订单来源
*/
private String orderSource;
/**
* 下单金额
*/
private String orderPrice;
/**
* 发货金额
*/
private String deliveryAmount;
/**
* 收货金额
*/
private String receivedAmount;
/**
* 司机
*/
private String driver;
/**
* 司机电话
*/
private String driverMobile;
/**
* 送货时间
*/
private Date deliveryTime;
/**
* 采购
*/
private String purchaseUser;
/**
* 采购电话
*/
private String purchaseMobile;
/**
* 订单详情
*/
private List<OrderItem> orderItems;
public String getPurchaseSeq() {
return purchaseSeq;
}
public void setPurchaseSeq(String purchaseSeq) {
this.purchaseSeq = purchaseSeq;
}
public String getOrderStore() {
return orderStore;
}
public void setOrderStore(String orderStore) {
this.orderStore = orderStore;
}
public String getStoreCode() {
return storeCode;
}
public void setStoreCode(String storeCode) {
this.storeCode = storeCode;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getUserMobile() {
return userMobile;
}
public void setUserMobile(String userMobile) {
this.userMobile = userMobile;
}
public String getStoreType() {
return storeType;
}
public void setStoreType(String storeType) {
this.storeType = storeType;
}
public String getUserAddress() {
return userAddress;
}
public void setUserAddress(String userAddress) {
this.userAddress = userAddress;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getExpectTime() {
return expectTime;
}
public void setExpectTime(Date expectTime) {
this.expectTime = expectTime;
}
public String getOrderStatus() {
return orderStatus;
}
public void setOrderStatus(String orderStatus) {
this.orderStatus = orderStatus;
}
public String getOrderSource() {
return orderSource;
}
public void setOrderSource(String orderSource) {
this.orderSource = orderSource;
}
public String getOrderPrice() {
return orderPrice;
}
public void setOrderPrice(String orderPrice) {
this.orderPrice = orderPrice;
}
public String getDeliveryAmount() {
return deliveryAmount;
}
public void setDeliveryAmount(String deliveryAmount) {
this.deliveryAmount = deliveryAmount;
}
public String getReceivedAmount() {
return receivedAmount;
}
public void setReceivedAmount(String receivedAmount) {
this.receivedAmount = receivedAmount;
}
public String getDriver() {
return driver;
}
public void setDriver(String driver) {
this.driver = driver;
}
public String getDriverMobile() {
return driverMobile;
}
public void setDriverMobile(String driverMobile) {
this.driverMobile = driverMobile;
}
public Date getDeliveryTime() {
return deliveryTime;
}
public void setDeliveryTime(Date deliveryTime) {
this.deliveryTime = deliveryTime;
}
public String getPurchaseUser() {
return purchaseUser;
}
public void setPurchaseUser(String purchaseUser) {
this.purchaseUser = purchaseUser;
}
public String getPurchaseMobile() {
return purchaseMobile;
}
public void setPurchaseMobile(String purchaseMobile) {
this.purchaseMobile = purchaseMobile;
}
public static class OrderItem implements Serializable {
private static final long serialVersionUID = 1L;
private String rootCategoryCode;
private String parentCategoryCode;
private String categoryCode;
public String getRootCategoryCode() {
return rootCategoryCode;
}
public void setRootCategoryCode(String rootCategoryCode) {
this.rootCategoryCode = rootCategoryCode;
}
public String getParentCategoryCode() {
return parentCategoryCode;
}
public void setParentCategoryCode(String parentCategoryCode) {
this.parentCategoryCode = parentCategoryCode;
}
public String getCategoryCode() {
return categoryCode;
}
public void setCategoryCode(String categoryCode) {
this.categoryCode = categoryCode;
}
}
}
8.2 修改service
由于流使用一次就会关闭,这里选择一次性操作。
你也可以使用缓存的方式分两次写入。
java
@Value("classpath:template/excel/ExportPurchaseOrderDetailsTemplate.xlsx")
private org.springframework.core.io.Resource templateResource;
public void excelExportDetails(String purchaseSeq, HttpServletResponse response) {
try (InputStream templateInputStream = templateResource.getInputStream()) {
// 检查模板文件是否存在
if (!templateResource.exists()) {
throw new RuntimeException("模板文件不存在!路径为:" + templateResource.getDescription());
}
// 设置响应头,告诉浏览器这是一个文件下载请求
String fileName = URLEncoder.encode("导出采购订单详情", "UTF-8") + ".xlsx";
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
AdminPurchaseOrderDetailsExportDTO adminPurchaseOrderDetailsExportDTO = new AdminPurchaseOrderDetailsExportDTO();
adminPurchaseOrderDetailsExportDTO.setOrderStore("1");
adminPurchaseOrderDetailsExportDTO.setStoreCode("21321");
adminPurchaseOrderDetailsExportDTO.setUser("312321");
adminPurchaseOrderDetailsExportDTO.setUserMobile("12321");
adminPurchaseOrderDetailsExportDTO.setStoreType("321321");
adminPurchaseOrderDetailsExportDTO.setUserAddress("123123");
adminPurchaseOrderDetailsExportDTO.setCreateTime(new Date());
adminPurchaseOrderDetailsExportDTO.setExpectTime(new Date());
adminPurchaseOrderDetailsExportDTO.setOrderStatus("213213");
adminPurchaseOrderDetailsExportDTO.setOrderSource("21312");
adminPurchaseOrderDetailsExportDTO.setOrderPrice("12312");
adminPurchaseOrderDetailsExportDTO.setDeliveryAmount("312321");
adminPurchaseOrderDetailsExportDTO.setReceivedAmount("312321");
adminPurchaseOrderDetailsExportDTO.setDriver("21321");
adminPurchaseOrderDetailsExportDTO.setDriverMobile("12321");
adminPurchaseOrderDetailsExportDTO.setDeliveryTime(new Date());
adminPurchaseOrderDetailsExportDTO.setPurchaseUser("312312");
adminPurchaseOrderDetailsExportDTO.setPurchaseMobile("321321321");
List<AdminPurchaseOrderDetailsExportDTO.OrderItem> orderItemList = new ArrayList<>();
AdminPurchaseOrderDetailsExportDTO.OrderItem orderItem = new AdminPurchaseOrderDetailsExportDTO.OrderItem();
orderItem.setRootCategoryCode("3123213");
orderItem.setParentCategoryCode("123213");
orderItem.setCategoryCode("123213");
orderItemList.add(orderItem);
AdminPurchaseOrderDetailsExportDTO.OrderItem orderItem1 = new AdminPurchaseOrderDetailsExportDTO.OrderItem();
orderItem1.setRootCategoryCode("dsfsfds");
orderItem1.setParentCategoryCode("sdfgdsfg");
orderItem1.setCategoryCode("werewrewrwe");
orderItemList.add(orderItem1);
try (ServletOutputStream outputStream = response.getOutputStream()) {
// 一次性写入单个对象数据和对象列表数据
ExcelWriter excelWriter = EasyExcelFactory.write(outputStream)
.withTemplate(templateInputStream)
.build();
WriteSheet writeSheet = EasyExcel.writerSheet(0).build();
// 填充单个对象数据
excelWriter.fill(adminPurchaseOrderDetailsExportDTO, writeSheet);
// 填充对象列表数据
excelWriter.fill(orderItemList, writeSheet);
// 结束写入
excelWriter.finish();
}catch (Exception e){
throw new RuntimeException("导出 Excel 文件失败11111111111", e);
}
} catch (Exception e) {
throw new RuntimeException("导出 Excel 文件失败", e);
}
}
8.3 成品
这里只做了几个简单的参数例子