From 4c6aab0221a4506e8aa629224812c88aced15670 Mon Sep 17 00:00:00 2001 From: qjq <1766193529@qq.com> Date: Fri, 18 Oct 2024 16:23:53 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E6=97=B6=E9=97=B4=E5=AF=BC?= =?UTF-8?q?=E5=87=BA=E5=A4=9A=E4=B8=AAsheet=20=E9=A1=B51?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CustomizeExcelController.java | 72 ++++++++++--- .../member/util/CustomMergeStrategy.java | 102 ++++++++++++++++++ 2 files changed, 158 insertions(+), 16 deletions(-) create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/util/CustomMergeStrategy.java diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/customizeExcel/CustomizeExcelController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/customizeExcel/CustomizeExcelController.java index 9d973860..85994a98 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/customizeExcel/CustomizeExcelController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/customizeExcel/CustomizeExcelController.java @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.module.member.controller.admin.customizeExcel.vo.OrderExcelVO; import cn.iocoder.yudao.module.member.service.customizeExcel.CustomizeExcelService; +import cn.iocoder.yudao.module.member.util.CustomMergeStrategy; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.converters.longconverter.LongStringConverter; @@ -12,6 +13,9 @@ import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -23,9 +27,11 @@ import java.io.IOException; import java.io.OutputStream; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import java.util.stream.Stream; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; @@ -59,30 +65,64 @@ public class CustomizeExcelController { * @param response * @throws IOException */ - public void exporOrderDate(List list,HttpServletResponse response) throws IOException { - Map> collect = list.stream().collect(Collectors.groupingBy(OrderExcelVO::getDayTime)); + public void exporOrderDate(List data1,HttpServletResponse response) throws IOException { + Map> collect = data1.stream().collect(Collectors.groupingBy(OrderExcelVO::getDayTime)); // 按key(时间)排序,将数据按时间顺序放入列表 List>> sortedEntries = collect.entrySet() .stream() .sorted(Map.Entry.comparingByKey()) // 按时间排序 .collect(Collectors.toList()); - // 创建输出流 - try (OutputStream outputStream = response.getOutputStream(); - ExcelWriter excelWriter = EasyExcel.write(outputStream).build()) { - int sheetIndex = 0; - // 逐个创建Sheet,并写入每个时间段的数据 + long l = System.currentTimeMillis(); + // 设置文件名和响应内容类型 + response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("订单详情统计.xlsx", StandardCharsets.UTF_8.name())); + response.setContentType("application/vnd.ms-excel;charset=UTF-8"); + try (SXSSFWorkbook workbook = new SXSSFWorkbook(); OutputStream outputStream = response.getOutputStream()) { for (Map.Entry> entry : sortedEntries) { - WriteSheet writeSheet = EasyExcel.writerSheet(sheetIndex, "数据 " + entry.getKey()) // 使用时间作为sheet名 - .head(OrderExcelVO.class) - .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 自动列宽策略 - .build(); - // 写入数据到当前Sheet - excelWriter.write(entry.getValue(), writeSheet); - sheetIndex++; + // 创建一个Sheet + Sheet sheet = workbook.createSheet("数据"+entry.getKey()); + // 处理数据和写入逻辑 + createHeader(sheet, workbook); // 创建表头 + int rowNum = 1; + // 写入数据 + for (OrderExcelVO order : data1) { + Row row = sheet.createRow(rowNum++); + row.createCell(0).setCellValue(order.getDayTime()); + row.createCell(1).setCellValue(order.getNickname()); + row.createCell(2).setCellValue(order.getMobile()); + row.createCell(3).setCellValue(order.getTimeSlot()); + row.createCell(4).setCellValue(order.getTotalMoney().toString()); + row.createCell(5).setCellValue(order.getDishesName()); + row.createCell(5).setCellValue(order.getUnitPrice()==null?"0.00":order.getUnitPrice().toString()); + row.createCell(7).setCellValue(order.getWeight()); + row.createCell(8).setCellValue(order.getPrice().toString()); + } + List data = entry.getValue(); + List> collect1 = Stream.of(data.stream().map(OrderExcelVO::getNickname).collect(Collectors.toList()), data.stream().map(OrderExcelVO::getMobile).collect(Collectors.toList()), data.stream().map(f -> f.getTotalMoney().toString()).collect(Collectors.toList())).collect(Collectors.toList()); + Map map = new HashMap<>(); + map.put(1, 0); // 第三列合并 + map.put(2, 1); // 第三列合并 + map.put(3, 2); // 第三列合并 + map.put(4, 2); // 第四列合并 + CustomMergeStrategy customMergeStrategy = new CustomMergeStrategy(collect1, map); + customMergeStrategy.merge(sheet,4); + // 将数据写入输出流 } - // 下载EXCEL,返回给前段stream流 - excelWriter.finish(); + workbook.write(outputStream); outputStream.flush(); + System.out.println( System.currentTimeMillis()-l); } } + // 创建表头 + private void createHeader(Sheet sheet, SXSSFWorkbook workbook) { + Row header = sheet.createRow(0); + header.createCell(0).setCellValue("日期"); + header.createCell(1).setCellValue("用户名"); + header.createCell(2).setCellValue("手机"); + header.createCell(3).setCellValue("总价"); + header.createCell(4).setCellValue("时间段"); + header.createCell(5).setCellValue("菜名"); + header.createCell(6).setCellValue("单价(元/50g)"); + header.createCell(7).setCellValue("重量(g)"); + header.createCell(8).setCellValue("价格(元)"); + } } \ No newline at end of file diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/util/CustomMergeStrategy.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/util/CustomMergeStrategy.java new file mode 100644 index 00000000..d7d325f6 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/util/CustomMergeStrategy.java @@ -0,0 +1,102 @@ +package cn.iocoder.yudao.module.member.util; + +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.springframework.util.ObjectUtils; + +import java.util.*; + +public class CustomMergeStrategy { + + /** + * 分组,每几行合并一次 + */ + private final List> mergeColDataGroupCountList; + + /** + * 目标合并列index + */ + private final Map targetColumnIndex; + /** + * 需要开始合并单元格的首行index + */ + private Integer rowIndex; + //存放合并的 + private Map> aaa=new HashMap<>(); + + /** + * mergeColDataList为待合并目标列的值 + */ + public CustomMergeStrategy(List> mergeColDataList, Map targetColumnIndex) { + this.mergeColDataGroupCountList = getGroupCountList(mergeColDataList); + this.targetColumnIndex = targetColumnIndex; + } + + public void merge(Sheet sheet,int i) { + rowIndex = 1; // 假设从第二行开始合并,第一行为表头 + // 遍历所有行 + Iterator rowIterator = sheet.rowIterator(); + while (rowIterator.hasNext()) { + Row row = rowIterator.next(); + int i1=0; + Iterator cellIterator = row.cellIterator(); + while (cellIterator.hasNext()) { + if(i1>i){ + return; + } + Cell cell = cellIterator.next(); + if (null == rowIndex) { + rowIndex = cell.getRowIndex(); + } + // 仅从首行以及目标列的单元格开始合并,忽略其他 + if (targetColumnIndex.get(cell.getColumnIndex())!=null) { + //找到对应的需要合并的列 + mergeGroupColumn(sheet, targetColumnIndex.get(cell.getColumnIndex()),cell.getColumnIndex()); + } + i1++; + } + } + } + + private void mergeGroupColumn(Sheet sheet, Integer index,Integer i) { + int rowCount = rowIndex; + for (Integer count : mergeColDataGroupCountList.get(index)) { + if (count == 1) { + rowCount += count; + continue; + } + // 合并单元格 + CellRangeAddress cellRangeAddress = new CellRangeAddress(rowCount, rowCount + count - 1, + i, i); + sheet.addMergedRegion(cellRangeAddress); + + rowCount += count; + } + } + + /** + * 该方法将目标列根据值是否相同连续可合并,存储可合并的行数 + */ + private List> getGroupCountList(List> exportDataList) { + if (ObjectUtils.isEmpty(exportDataList)) { + return new ArrayList<>(); + } + List> groupCountListList = new ArrayList<>(); + for (List dataList : exportDataList) { + List groupCountList = new ArrayList<>(); + int count = 1; + for (int i = 1; i < dataList.size(); i++) { + if (dataList.get(i).equals(dataList.get(i - 1))) { + count++; + } else { + groupCountList.add(count); + count = 1; + } + } + // 处理完最后一条后 + groupCountList.add(count); + groupCountListList.add(groupCountList); + } + return groupCountListList; + } +}