diff --git a/pom.xml b/pom.xml
index 11d9233..706b742 100644
--- a/pom.xml
+++ b/pom.xml
@@ -199,6 +199,12 @@
6.11
+
+
+ cn.idev.excel
+ fastexcel
+ 1.2.0
+
diff --git a/youchain-system/src/main/java/com/youchain/basicdata/rest/StockController.java b/youchain-system/src/main/java/com/youchain/basicdata/rest/StockController.java
index d494024..1b7b2fe 100644
--- a/youchain-system/src/main/java/com/youchain/basicdata/rest/StockController.java
+++ b/youchain-system/src/main/java/com/youchain/basicdata/rest/StockController.java
@@ -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")
diff --git a/youchain-system/src/main/java/com/youchain/basicdata/service/StockService.java b/youchain-system/src/main/java/com/youchain/basicdata/service/StockService.java
index de182e1..4cc4686 100644
--- a/youchain-system/src/main/java/com/youchain/basicdata/service/StockService.java
+++ b/youchain-system/src/main/java/com/youchain/basicdata/service/StockService.java
@@ -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 findByFreeOrUsedStock(String areaName,String status);
+ List 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
+ */
+ List listByStocks(Long lastId, int pageSize, StockQueryCriteria criteria);
+
+ /**
+ * 导出
+ * @param criteria 查询参数
+ * @param response 请求
+ */
+ void exportStocks(StockQueryCriteria criteria,HttpServletResponse response);
}
diff --git a/youchain-system/src/main/java/com/youchain/basicdata/service/impl/StockServiceImpl.java b/youchain-system/src/main/java/com/youchain/basicdata/service/impl/StockServiceImpl.java
index 8903b38..e032b7f 100644
--- a/youchain-system/src/main/java/com/youchain/basicdata/service/impl/StockServiceImpl.java
+++ b/youchain-system/src/main/java/com/youchain/basicdata/service/impl/StockServiceImpl.java
@@ -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 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 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("文件导出失败,请重试!");
+ }
+
+ }
+
/**
* 验证容器是否存在
diff --git a/youchain-system/src/main/java/com/youchain/basicdata/vo/StockExcelVO.java b/youchain-system/src/main/java/com/youchain/basicdata/vo/StockExcelVO.java
new file mode 100644
index 0000000..bc1bb48
--- /dev/null
+++ b/youchain-system/src/main/java/com/youchain/basicdata/vo/StockExcelVO.java
@@ -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;
+
+}
diff --git a/youchain-system/src/main/java/com/youchain/utils/FastExcelUtil.java b/youchain-system/src/main/java/com/youchain/utils/FastExcelUtil.java
new file mode 100644
index 0000000..7d641bd
--- /dev/null
+++ b/youchain-system/src/main/java/com/youchain/utils/FastExcelUtil.java
@@ -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 泛型
+ * @param 泛型
+ * @throws IOException 抛出IO异常
+ */
+ public static void batchExportExcel(HttpServletResponse response, String fileName, String sheetName, Class head, BiFunction> pageQueryFunction, Function convertFunction, ToLongFunction 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 batch = pageQueryFunction.apply(lastId, pageSize);
+ if (batch.isEmpty()) {
+ break;
+ }
+
+ List 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("导出失败");
+ }
+ }
+}
diff --git a/youchain-system/src/main/resources/config/application-dev.yml b/youchain-system/src/main/resources/config/application-dev.yml
index 5fe3b40..02f875a 100644
--- a/youchain-system/src/main/resources/config/application-dev.yml
+++ b/youchain-system/src/main/resources/config/application-dev.yml
@@ -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}
# 初始连接数
diff --git a/youchain-system/src/main/resources/config/application.yml b/youchain-system/src/main/resources/config/application.yml
index b1ffe53..65ebfa4 100644
--- a/youchain-system/src/main/resources/config/application.yml
+++ b/youchain-system/src/main/resources/config/application.yml
@@ -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