fastExcel导出容器
parent
2f0153c235
commit
4ad74a1dc9
6
pom.xml
6
pom.xml
|
|
@ -199,6 +199,12 @@
|
||||||
<version>6.11</version>
|
<version>6.11</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- fastexcel导出 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.idev.excel</groupId>
|
||||||
|
<artifactId>fastexcel</artifactId>
|
||||||
|
<version>1.2.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import com.youchain.annotation.Log;
|
||||||
import com.youchain.basicdata.domain.Stock;
|
import com.youchain.basicdata.domain.Stock;
|
||||||
import com.youchain.basicdata.service.StockService;
|
import com.youchain.basicdata.service.StockService;
|
||||||
import com.youchain.basicdata.service.dto.StockQueryCriteria;
|
import com.youchain.basicdata.service.dto.StockQueryCriteria;
|
||||||
|
import com.youchain.basicdata.vo.StockExcelVO;
|
||||||
import com.youchain.config.FileProperties;
|
import com.youchain.config.FileProperties;
|
||||||
import com.youchain.exception.handler.ApiResult;
|
import com.youchain.exception.handler.ApiResult;
|
||||||
import com.youchain.modules.system.domain.Dept;
|
import com.youchain.modules.system.domain.Dept;
|
||||||
|
|
@ -61,12 +62,19 @@ public class StockController {
|
||||||
|
|
||||||
@Log("导出数据")
|
@Log("导出数据")
|
||||||
@ApiOperation("导出数据")
|
@ApiOperation("导出数据")
|
||||||
@GetMapping(value = "/download")
|
@GetMapping(value = "/download2")
|
||||||
@PreAuthorize("@el.check('stock:list')")
|
@PreAuthorize("@el.check('stock:list')")
|
||||||
public void exportStock(HttpServletResponse response, StockQueryCriteria criteria) throws IOException {
|
public void exportStock(HttpServletResponse response, StockQueryCriteria criteria) throws IOException {
|
||||||
stockService.download(stockService.queryAll(criteria), response);
|
stockService.download(stockService.queryAll(criteria), response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Log("导出 @author 卓大")
|
||||||
|
@ApiOperation("导出数据")
|
||||||
|
@GetMapping("/download")
|
||||||
|
public void exportStocks(HttpServletResponse response,StockQueryCriteria criteria){
|
||||||
|
stockService.exportStocks(criteria, response);
|
||||||
|
}
|
||||||
|
|
||||||
@Log("容器导入")
|
@Log("容器导入")
|
||||||
@ApiOperation("容器导入")
|
@ApiOperation("容器导入")
|
||||||
@PostMapping(value = "/importStock")
|
@PostMapping(value = "/importStock")
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import com.youchain.basicdata.domain.Point;
|
||||||
import com.youchain.basicdata.domain.Stock;
|
import com.youchain.basicdata.domain.Stock;
|
||||||
import com.youchain.basicdata.service.dto.StockDto;
|
import com.youchain.basicdata.service.dto.StockDto;
|
||||||
import com.youchain.basicdata.service.dto.StockQueryCriteria;
|
import com.youchain.basicdata.service.dto.StockQueryCriteria;
|
||||||
|
import com.youchain.basicdata.vo.StockExcelVO;
|
||||||
import com.youchain.businessdata.domain.Pick;
|
import com.youchain.businessdata.domain.Pick;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
@ -137,9 +138,9 @@ public interface StockService {
|
||||||
* 查询指定库区可用的空车
|
* 查询指定库区可用的空车
|
||||||
*
|
*
|
||||||
* @param areaName 库区
|
* @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);
|
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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,25 +15,16 @@
|
||||||
*/
|
*/
|
||||||
package com.youchain.basicdata.service.impl;
|
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.ExcelReader;
|
||||||
import cn.hutool.poi.excel.ExcelUtil;
|
import cn.hutool.poi.excel.ExcelUtil;
|
||||||
import com.alibaba.fastjson.JSON;
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
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.Point;
|
||||||
import com.youchain.basicdata.domain.Stock;
|
import com.youchain.basicdata.domain.Stock;
|
||||||
import com.youchain.basicdata.repository.AreaRepository;
|
|
||||||
import com.youchain.basicdata.repository.PointRepository;
|
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.config.FileProperties;
|
||||||
import com.youchain.exception.BadRequestException;
|
import com.youchain.exception.BadRequestException;
|
||||||
import com.youchain.modules.mnt.websocket.MsgType;
|
import com.youchain.modules.mnt.websocket.MsgType;
|
||||||
|
|
@ -55,12 +46,10 @@ import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.regex.Matcher;
|
import javax.persistence.EntityManager;
|
||||||
import java.util.regex.Pattern;
|
import javax.persistence.TypedQuery;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -78,6 +67,7 @@ public class StockServiceImpl implements StockService {
|
||||||
private final StockRepository stockRepository;
|
private final StockRepository stockRepository;
|
||||||
private final PointRepository pointRepository;
|
private final PointRepository pointRepository;
|
||||||
private final StockMapper stockMapper;
|
private final StockMapper stockMapper;
|
||||||
|
private final EntityManager entityMapper;
|
||||||
private final FileProperties properties;
|
private final FileProperties properties;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -244,6 +234,54 @@ public class StockServiceImpl implements StockService {
|
||||||
return "error";
|
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("文件导出失败,请重试!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证容器是否存在
|
* 验证容器是否存在
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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("导出失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,7 +4,7 @@ spring:
|
||||||
druid:
|
druid:
|
||||||
db-type: com.alibaba.druid.pool.DruidDataSource
|
db-type: com.alibaba.druid.pool.DruidDataSource
|
||||||
driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
|
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}
|
username: ${DB_USER:root}
|
||||||
password: ${DB_PWD:Youchain@56}
|
password: ${DB_PWD:Youchain@56}
|
||||||
# 初始连接数
|
# 初始连接数
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ spring:
|
||||||
freemarker:
|
freemarker:
|
||||||
check-template-location: false
|
check-template-location: false
|
||||||
profiles:
|
profiles:
|
||||||
active: prod
|
#active: prod
|
||||||
#active: dev
|
active: dev
|
||||||
jackson:
|
jackson:
|
||||||
time-zone: GMT+8
|
time-zone: GMT+8
|
||||||
data:
|
data:
|
||||||
|
|
@ -36,11 +36,11 @@ spring:
|
||||||
redis:
|
redis:
|
||||||
#数据库索引
|
#数据库索引
|
||||||
database: ${REDIS_DB:2}
|
database: ${REDIS_DB:2}
|
||||||
host: ${REDIS_HOST:192.168.100.102}
|
#host: ${REDIS_HOST:192.168.100.102}
|
||||||
password: ${REDIS_PWD:123456}
|
#password: ${REDIS_PWD:123456}
|
||||||
|
|
||||||
#host: ${REDIS_HOST:localhost}
|
host: ${REDIS_HOST:localhost}
|
||||||
#password: ${REDIS_PWD:}
|
password: ${REDIS_PWD:}
|
||||||
port: ${REDIS_PORT:6379}
|
port: ${REDIS_PORT:6379}
|
||||||
#连接超时时间
|
#连接超时时间
|
||||||
timeout: 5000
|
timeout: 5000
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue