根据时间导出多个sheet 页1
This commit is contained in:
@ -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<OrderExcelVO> list,HttpServletResponse response) throws IOException {
|
||||
Map<String, List<OrderExcelVO>> collect = list.stream().collect(Collectors.groupingBy(OrderExcelVO::getDayTime));
|
||||
public void exporOrderDate(List<OrderExcelVO> data1,HttpServletResponse response) throws IOException {
|
||||
Map<String, List<OrderExcelVO>> collect = data1.stream().collect(Collectors.groupingBy(OrderExcelVO::getDayTime));
|
||||
// 按key(时间)排序,将数据按时间顺序放入列表
|
||||
List<Map.Entry<String, List<OrderExcelVO>>> 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<String, List<OrderExcelVO>> 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<OrderExcelVO> data = entry.getValue();
|
||||
List<List<String>> 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<Integer, Integer> 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("价格(元)");
|
||||
}
|
||||
}
|
@ -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<List<Integer>> mergeColDataGroupCountList;
|
||||
|
||||
/**
|
||||
* 目标合并列index
|
||||
*/
|
||||
private final Map<Integer, Integer> targetColumnIndex;
|
||||
/**
|
||||
* 需要开始合并单元格的首行index
|
||||
*/
|
||||
private Integer rowIndex;
|
||||
//存放合并的
|
||||
private Map<Integer,List<Integer>> aaa=new HashMap<>();
|
||||
|
||||
/**
|
||||
* mergeColDataList为待合并目标列的值
|
||||
*/
|
||||
public CustomMergeStrategy(List<List<String>> mergeColDataList, Map<Integer, Integer> targetColumnIndex) {
|
||||
this.mergeColDataGroupCountList = getGroupCountList(mergeColDataList);
|
||||
this.targetColumnIndex = targetColumnIndex;
|
||||
}
|
||||
|
||||
public void merge(Sheet sheet,int i) {
|
||||
rowIndex = 1; // 假设从第二行开始合并,第一行为表头
|
||||
// 遍历所有行
|
||||
Iterator<Row> rowIterator = sheet.rowIterator();
|
||||
while (rowIterator.hasNext()) {
|
||||
Row row = rowIterator.next();
|
||||
int i1=0;
|
||||
Iterator<Cell> 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<List<Integer>> getGroupCountList(List<List<String>> exportDataList) {
|
||||
if (ObjectUtils.isEmpty(exportDataList)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<List<Integer>> groupCountListList = new ArrayList<>();
|
||||
for (List<String> dataList : exportDataList) {
|
||||
List<Integer> 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;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user