fastExcel导出容器

main
huojin\hj 2025-07-15 10:24:09 +08:00
parent 2f0153c235
commit 4ad74a1dc9
8 changed files with 263 additions and 27 deletions

View File

@ -199,6 +199,12 @@
<version>6.11</version>
</dependency>
<!-- fastexcel导出 -->
<dependency>
<groupId>cn.idev.excel</groupId>
<artifactId>fastexcel</artifactId>
<version>1.2.0</version>
</dependency>
</dependencies>

View File

@ -22,6 +22,7 @@ import com.youchain.annotation.Log;
import com.youchain.basicdata.domain.Stock;
import com.youchain.basicdata.service.StockService;
import com.youchain.basicdata.service.dto.StockQueryCriteria;
import com.youchain.basicdata.vo.StockExcelVO;
import com.youchain.config.FileProperties;
import com.youchain.exception.handler.ApiResult;
import com.youchain.modules.system.domain.Dept;
@ -61,12 +62,19 @@ public class StockController {
@Log("导出数据")
@ApiOperation("导出数据")
@GetMapping(value = "/download")
@GetMapping(value = "/download2")
@PreAuthorize("@el.check('stock:list')")
public void exportStock(HttpServletResponse response, StockQueryCriteria criteria) throws IOException {
stockService.download(stockService.queryAll(criteria), response);
}
@Log("导出 @author 卓大")
@ApiOperation("导出数据")
@GetMapping("/download")
public void exportStocks(HttpServletResponse response,StockQueryCriteria criteria){
stockService.exportStocks(criteria, response);
}
@Log("容器导入")
@ApiOperation("容器导入")
@PostMapping(value = "/importStock")

View File

@ -21,6 +21,7 @@ import com.youchain.basicdata.domain.Point;
import com.youchain.basicdata.domain.Stock;
import com.youchain.basicdata.service.dto.StockDto;
import com.youchain.basicdata.service.dto.StockQueryCriteria;
import com.youchain.basicdata.vo.StockExcelVO;
import com.youchain.businessdata.domain.Pick;
import org.springframework.data.domain.Pageable;
import org.springframework.web.multipart.MultipartFile;
@ -137,9 +138,9 @@ public interface StockService {
*
*
* @param areaName
* @param status
* @param status
*/
List<Stock> findByFreeOrUsedStock(String areaName,String status);
List<Stock> findByFreeOrUsedStock(String areaName, String status);
/**
*
@ -162,5 +163,21 @@ public interface StockService {
*/
String stockMsg(String msg);
/**
*
*
* @param lastId id
* @param pageSize
* @param criteria
* @return List<Stock>
*/
List<Stock> listByStocks(Long lastId, int pageSize, StockQueryCriteria criteria);
/**
*
* @param criteria
* @param response
*/
void exportStocks(StockQueryCriteria criteria,HttpServletResponse response);
}

View File

@ -15,25 +15,16 @@
*/
package com.youchain.basicdata.service.impl;
import cn.hutool.core.date.DateUtil;
import com.youchain.basicdata.vo.StockExcelVO;
import org.apache.commons.lang3.StringUtils;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.youchain.RequestData.TransTask;
import com.youchain.appupdate.ReturnJson.ReturnTaskVo;
import com.youchain.basicdata.domain.Area;
import com.youchain.basicdata.domain.Item;
import com.youchain.basicdata.domain.Point;
import com.youchain.basicdata.domain.Stock;
import com.youchain.basicdata.repository.AreaRepository;
import com.youchain.basicdata.repository.PointRepository;
import com.youchain.basicdata.service.ItemService;
import com.youchain.basicdata.vo.BarCodeVo;
import com.youchain.businessdata.domain.*;
import com.youchain.businessdata.repository.*;
import com.youchain.businessdata.service.*;
import com.youchain.businessdata.service.dto.TaskDto;
import com.youchain.config.FileProperties;
import com.youchain.exception.BadRequestException;
import com.youchain.modules.mnt.websocket.MsgType;
@ -55,12 +46,10 @@ import org.springframework.data.domain.Pageable;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.sql.Timestamp;
import java.util.*;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.servlet.http.HttpServletResponse;
@ -78,6 +67,7 @@ public class StockServiceImpl implements StockService {
private final StockRepository stockRepository;
private final PointRepository pointRepository;
private final StockMapper stockMapper;
private final EntityManager entityMapper;
private final FileProperties properties;
@ -244,6 +234,54 @@ public class StockServiceImpl implements StockService {
return "error";
}
@Override
public List<Stock> listByStocks(Long lastId, int pageSize, StockQueryCriteria criteria) {
// 构建基础 HQL 查询语句
String hql = "SELECT s FROM Stock s WHERE 1=1 ";
if (StringUtils.isNotEmpty(criteria.getCode())) {
hql += " AND s.code ='" + criteria.getCode() + "' ";
}
// 添加游标条件:只获取比当前游标大的 id 的记录
if (lastId != null) {
hql += " AND s.id > " + lastId;
}
// 按照 id 排序,确保结果集顺序一致
hql += " ORDER BY s.id ASC";
// 创建查询对象
TypedQuery<Stock> query = entityMapper.createQuery(hql, Stock.class);
// 设置分页大小
query.setMaxResults(pageSize);
return query.getResultList();
}
@Override
public void exportStocks(StockQueryCriteria criteria, HttpServletResponse response) {
try {
FastExcelUtil.batchExportExcel(
response,
"容器信息.xlsx",
"容器",
StockExcelVO.class,
(lastId, pageSize) -> this.listByStocks(lastId, pageSize, criteria),
stock -> StockExcelVO.builder()
.code(stock.getCode())
.type(stock.getStockType())
.build(),
Stock::getId,
2000
);
} catch (IOException e) {
throw new BadRequestException("文件导出失败,请重试!");
}
}
/**
*

View File

@ -0,0 +1,22 @@
package com.youchain.basicdata.vo;
import cn.idev.excel.annotation.ExcelProperty;
import cn.idev.excel.annotation.write.style.ColumnWidth;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ColumnWidth(20)
public class StockExcelVO {
@ExcelProperty("代码")
private String code;
@ExcelProperty("类型")
private String type;
}

View File

@ -0,0 +1,145 @@
package com.youchain.utils;
import cn.idev.excel.ExcelWriter;
import cn.idev.excel.FastExcel;
import cn.idev.excel.write.metadata.WriteSheet;
import cn.idev.excel.write.metadata.style.WriteCellStyle;
import cn.idev.excel.write.metadata.style.WriteFont;
import cn.idev.excel.write.style.HorizontalCellStyleStrategy;
import com.youchain.exception.BadRequestException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.MediaTypeFactory;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Collection;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.ToLongFunction;
import java.util.stream.Collectors;
import static cn.hutool.core.util.CharsetUtil.UTF_8;
/**
* excel
*/
@Slf4j
public class FastExcelUtil {
/**
*
*
* @param response
* @param fileName
* @param fileSize
*/
public static void setDownloadFileHeader(HttpServletResponse response, String fileName, Long fileSize) {
response.setCharacterEncoding(UTF_8);
if (fileSize != null) {
response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(fileSize));
}
if (StringUtils.isNotEmpty(fileName)) {
response.setHeader(HttpHeaders.CONTENT_TYPE, MediaTypeFactory.getMediaType(fileName).orElse(MediaType.APPLICATION_OCTET_STREAM) + ";charset=utf-8");
try {
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + URLEncoder.encode(fileName, UTF_8).replaceAll("\\+", "%20"));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
response.setHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION);
}
}
/**
*
*
* @return horizontalCellStyleStrategy
*/
public static HorizontalCellStyleStrategy getHorizontalCellStyleStrategy() {
WriteCellStyle headWriteCellStyle = new WriteCellStyle();
headWriteCellStyle.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex());
WriteFont headWriteFont = new WriteFont();
headWriteFont.setFontName("宋体");
headWriteFont.setColor(IndexedColors.WHITE.getIndex());
headWriteCellStyle.setWriteFont(headWriteFont);
WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
contentWriteCellStyle.setFillForegroundColor(IndexedColors.BLACK.getIndex());
return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
}
/**
* sheet
*/
public static void exportExcel(HttpServletResponse response, String fileName, String sheetName, Class head, Collection<?> data) throws IOException {
// 设置下载消息头
setDownloadFileHeader(response, fileName, null);
//样式
HorizontalCellStyleStrategy horizontalCellStyleStrategy = getHorizontalCellStyleStrategy();
// 下载
FastExcel.write(response.getOutputStream(), head)
.autoCloseStream(Boolean.FALSE)
.sheet(sheetName)
.registerWriteHandler(horizontalCellStyleStrategy)
.doWrite(data);
}
/**
*
* @param response
* @param fileName
* @param sheetName sheet
* @param head
* @param pageQueryFunction
* @param convertFunction
* @param idExtractor id
* @param pageSize
* @param <T>
* @param <E>
* @throws IOException IO
*/
public static <T, E> void batchExportExcel(HttpServletResponse response, String fileName, String sheetName, Class head, BiFunction<Long, Integer, List<T>> pageQueryFunction, Function<T, E> convertFunction, ToLongFunction<T> idExtractor, int pageSize) throws IOException {
long startTime = System.currentTimeMillis();
// 设置下载消息头
setDownloadFileHeader(response, fileName, null);
HorizontalCellStyleStrategy horizontalCellStyleStrategy = getHorizontalCellStyleStrategy();
try (ExcelWriter excelWriter = FastExcel.write(response.getOutputStream(), head).registerWriteHandler(horizontalCellStyleStrategy).build()) {
WriteSheet writeSheet = FastExcel.writerSheet(sheetName).build();
long lastId = 0;//最后一个id
while (true) {
List<T> batch = pageQueryFunction.apply(lastId, pageSize);
if (batch.isEmpty()) {
break;
}
List<E> excelData = batch.stream()
.map(convertFunction)
.collect(Collectors.toList());
excelWriter.write(excelData, writeSheet);
lastId = batch.stream()
.mapToLong(idExtractor)
.max()
.orElse(lastId);
}
excelWriter.finish();
log.info(" 耗时: {}ms", System.currentTimeMillis() - startTime);
} catch (Exception e) {
throw new BadRequestException("导出失败");
}
}
}

View File

@ -4,7 +4,7 @@ spring:
druid:
db-type: com.alibaba.druid.pool.DruidDataSource
driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
url: jdbc:log4jdbc:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:53306}/${DB_NAME:byd_wms}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&rewriteBatchedStatements=true
url: jdbc:log4jdbc:mysql://${DB_HOST:47.103.100.52}:${DB_PORT:53306}/${DB_NAME:byd_wms}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&rewriteBatchedStatements=true
username: ${DB_USER:root}
password: ${DB_PWD:Youchain@56}
# 初始连接数

View File

@ -6,8 +6,8 @@ spring:
freemarker:
check-template-location: false
profiles:
active: prod
#active: dev
#active: prod
active: dev
jackson:
time-zone: GMT+8
data:
@ -36,11 +36,11 @@ spring:
redis:
#数据库索引
database: ${REDIS_DB:2}
host: ${REDIS_HOST:192.168.100.102}
password: ${REDIS_PWD:123456}
#host: ${REDIS_HOST:192.168.100.102}
#password: ${REDIS_PWD:123456}
#host: ${REDIS_HOST:localhost}
#password: ${REDIS_PWD:}
host: ${REDIS_HOST:localhost}
password: ${REDIS_PWD:}
port: ${REDIS_PORT:6379}
#连接超时时间
timeout: 5000