数据报表销量导出修改

This commit is contained in:
SongZhang 2024-08-01 16:07:29 +08:00
parent b7453e1123
commit 4f7a387349
4 changed files with 106 additions and 17 deletions

View File

@ -32,9 +32,11 @@ import java.io.*;
import java.security.MessageDigest;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
* File工具类扩展 hutool 工具包
@ -231,6 +233,36 @@ public class FileUtil extends cn.hutool.core.io.FileUtil {
IoUtil.close(out);
}
public static void downloadExcelAndMerge(ConcurrentLinkedQueue<Map<String, Object>> list, int colSize, HttpServletResponse response, ArrayList<Integer> mergeRowIndex) throws IOException {
String tempPath = SYS_TEM_DIR + IdUtil.fastSimpleUUID() + ".xlsx";
File file = new File(tempPath);
BigExcelWriter writer = ExcelUtil.getBigWriter(file);
// 合并单元格后的标题行使用默认标题样式.
for (int i = 0; i < mergeRowIndex.size(); i++) {
for (int i1 = 0; i1 < colSize; i1++) {
writer.merge(i == 0 ? 0 : mergeRowIndex.get(i - 1) + 1, mergeRowIndex.get(i), i1, i1, "", true);
}
}
// 一次性写出内容使用默认样式强制输出标题
writer.write(list, true);
SXSSFSheet sheet = (SXSSFSheet)writer.getSheet();
//上面需要强转SXSSFSheet 不然没有trackAllColumnsForAutoSizing方法
sheet.trackAllColumnsForAutoSizing();
//列宽自适应
writer.autoSizeColumnAll();
//response为HttpServletResponse对象
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
//test.xls是弹出下载对话框的文件名不能为中文中文请自行编码
response.setHeader("Content-Disposition", "attachment;filename=file.xlsx");
ServletOutputStream out = response.getOutputStream();
// 终止后删除临时文件
file.deleteOnExit();
writer.flush(out, true);
//此处记得关闭输出Servlet流
IoUtil.close(out);
}
public static String getFileType(String type) {
String documents = "txt doc pdf ppt pps xlsx xls docx";
String music = "mp3 wav wma mpa ram ra aac aif m4a";
@ -353,4 +385,6 @@ public class FileUtil extends cn.hutool.core.io.FileUtil {
public static String getMd5(File file) {
return getMd5(getByte(file));
}
}

View File

@ -3,6 +3,7 @@ package cn.ysk.cashier.repository.order;
import cn.ysk.cashier.dto.product.StockCountDTO;
import cn.ysk.cashier.pojo.order.TbOrderDetail;
import cn.ysk.cashier.vo.TbOrderPayCountVo;
import cn.ysk.cashier.vo.TbOrderSaleVO;
import cn.ysk.cashier.vo.TbOrderSalesCountByDayVo;
import org.apache.ibatis.annotations.Param;
import org.springframework.data.domain.Page;
@ -77,6 +78,7 @@ public interface TbOrderDetailRepository extends JpaRepository<TbOrderDetail, In
@Query("SELECT new cn.ysk.cashier.vo.TbOrderSalesCountByDayVo(" +
"info.productId, info.productSkuId," +
"info.productName, info.productSkuName, cate.name, unit.name,info.price," +
"SUM(CASE WHEN orders.orderType!='return' THEN info.num ELSE 0 END) as salesNum, " +
"SUM(CASE WHEN orders.orderType='return' THEN info.num ELSE 0 END), " +
@ -145,4 +147,19 @@ public interface TbOrderDetailRepository extends JpaRepository<TbOrderDetail, In
List<Integer> findOrderIdsByProductNameLike(@Param("productName") String productName, @Param("shop_id") String shopId,
@Param("startTime") Date startTime, @Param("endTime") Date endTime);
@Query(value = "SELECT\n" +
"od.num,\n" +
"od.price AS price,\n" +
"od.status, oi.orderNo \n" +
"FROM\n" +
"TbOrderInfo oi\n" +
"LEFT JOIN TbOrderDetail od ON oi.id = od.orderId \n" +
"WHERE\n" +
"od.shopId = :shopId \n" +
"AND ( od.status = 'closed' OR od.status = 'refund' ) \n" +
"AND oi.createdAt > :startTime \n" +
"AND oi.createdAt < :endTime \n" +
"AND od.productId = :productId\n" +
"AND od.productSkuId = :productSkuId")
List<TbOrderSaleVO> querySaleOrderInfo(Date startTime, Date endTime, Integer productId, Integer productSkuId, String shopId);
}

View File

@ -37,6 +37,7 @@ import java.time.Instant;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
@Service
@RequiredArgsConstructor
@ -403,10 +404,13 @@ public class SummaryServiceImpl implements SummaryService {
@Override
public void download(ShopSummaryDto summaryDto, HttpServletResponse response) throws IOException {
List<Map<String, Object>> list = new ArrayList<>();
// List<Map<String, Object>> list = new ArrayList<>();
ConcurrentLinkedQueue<Map<String, Object>> list = new ConcurrentLinkedQueue();
if(StringUtils.isBlank(summaryDto.getCateId())){
summaryDto.setCateId(null);
}
ArrayList<Integer> mergeRowIndex = new ArrayList<>();
if (summaryDto.getType() != null && summaryDto.getType() == 1) {//金额
Long start = 1704038400000L;
Long end = Instant.now().toEpochMilli();
@ -430,23 +434,39 @@ public class SummaryServiceImpl implements SummaryService {
summaryDto.setStartTime(DateUtil.toDate(DateUtil.fromTimeStamp(1704038400L)));
summaryDto.setEndTime(new Date());
}
List<TbOrderSalesCountByDayVo> tbOrderSalesCountByDayVos = detailRepository.queryTbOrderSalesCountByDay(Integer.valueOf(summaryDto.getShopId()),summaryDto.getCateId(),summaryDto.getProName(), summaryDto.getStartTime(), summaryDto.getEndTime());
for (TbOrderSalesCountByDayVo all : tbOrderSalesCountByDayVos) {
Map<String, Object> map = new LinkedHashMap<>();
map.put("商品分类", all.getCateName());
map.put("商品名称", all.getProductName());
map.put("单 位", all.getUnitName());
map.put("商品规格", StringUtils.isBlank(all.getProductSkuName()) ? "" : all.getProductSkuName());
map.put("销 售 额", all.getSalesAmount());
map.put("销 量", all.getSalesNum());
map.put("单 价", all.getPrice());
map.put("退 单 量", all.getRefNum());
map.put("退 单 额", all.getRefAmount().compareTo(BigDecimal.ZERO)==0?all.getRefAmount():"-"+all.getRefAmount());
map.put("总 量", all.getNum()-all.getRefNum());
list.add(map);
}
List<TbOrderSalesCountByDayVo> tbOrderSalesCountByDayVos = detailRepository
.queryTbOrderSalesCountByDay(Integer.valueOf(summaryDto.getShopId()),summaryDto.getCateId(),summaryDto.getProName(), summaryDto.getStartTime(), summaryDto.getEndTime());
tbOrderSalesCountByDayVos.stream().parallel().forEach(all -> {
List<TbOrderSaleVO> tbOrderSaleVOS = detailRepository.querySaleOrderInfo(summaryDto.getStartTime(),
summaryDto.getEndTime(), all.getProductId(), all.getProductSkuId(), summaryDto.getShopId());
for (TbOrderSaleVO tbOrderSaleVO : tbOrderSaleVOS) {
Map<String, Object> map = new LinkedHashMap<>();
map.put("商品分类", all.getCateName());
map.put("商品名称", all.getProductName());
map.put("单 位", all.getUnitName());
map.put("商品规格", StringUtils.isBlank(all.getProductSkuName()) ? "" : all.getProductSkuName());
map.put("销 售 额", all.getSalesAmount());
map.put("销 量", all.getSalesNum());
map.put("单 价", all.getPrice());
map.put("退 单 量", all.getRefNum());
map.put("退 单 额", all.getRefAmount().compareTo(BigDecimal.ZERO)==0?all.getRefAmount():"-"+all.getRefAmount());
map.put("总 量", all.getNum()-all.getRefNum());
map.put("订单编号", tbOrderSaleVO.getOrderNo());
map.put("售出数量", tbOrderSaleVO.getNum());
list.add(map);
}
if (!tbOrderSaleVOS.isEmpty()) {
if (mergeRowIndex.isEmpty()) {
mergeRowIndex.add(tbOrderSaleVOS.size());
}else {
mergeRowIndex.add(mergeRowIndex.get(mergeRowIndex.size() - 1) + tbOrderSaleVOS.size());
}
}
});
}
FileUtil.downloadExcel(list, response);
FileUtil.downloadExcelAndMerge(list, 12, response, mergeRowIndex);
}
@Override

View File

@ -14,6 +14,24 @@ public class TbOrderSalesCountByDayVo {
private BigDecimal salesAmount;
private BigDecimal refAmount;
private Long num;
private Integer productId;
private Integer productSkuId;
public Integer getProductId() {
return productId;
}
public void setProductId(Integer productId) {
this.productId = productId;
}
public Integer getProductSkuId() {
return productSkuId;
}
public void setProductSkuId(Integer productSkuId) {
this.productSkuId = productSkuId;
}
public String getProductName() {
return productName;