java导出excel动态加载多sheet多复杂表头

2024-05-15 02:12

本文主要是介绍java导出excel动态加载多sheet多复杂表头,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

java导出excel动态加载多sheet多复杂表头

  • 实体
  • 实现类
  • sheet方法
  • 业务工具方法
  • 实现效果

实体

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;import java.io.Serializable;
import java.sql.Date;@Data
@Accessors(chain = true)
public class CurrentPlanCityTunePowerVo implements Serializable {private static final long serialVersionUID = 1L;private String dateTime;private Double output;private String id;private String areaName;private String type;
}
import lombok.Data;
import lombok.experimental.Accessors;import java.io.Serializable;
import java.util.List;
import java.util.Map;@Data
@Accessors(chain = true)
public class DayPlanArchiveHeadVo implements Serializable {private static final long serialVersionUID = 1L;private Map<String, String> rqjhMenuMap;private Map<String, List<String>> head1Map;private Map<String, List<String>> waterHead1Map;}

import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;import java.io.Serializable;
import java.util.Date;
import java.util.List;@Data
@Accessors(chain = true)
public class DayPlanArchiveResultVo implements Serializable {private static final long serialVersionUID = 1L;private List<DayPlanArchiveVo> dayPlanArchiveVoList;private List<CurrentPlanCityTunePowerVo> currentPlanCityTunePowerVoList;}
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;@Data
@Accessors(chain = true)
public class DayPlanArchiveVo implements Serializable {private static final long serialVersionUID = 1L;private Date dateTime;private Double output;private String stationId;private String shortName;private String schedulingLevel;private String region;private String stationType;private String category;private String vol;private String tunePower;
}

实现类

@Overridepublic void export(String date, String txtName, HttpServletResponse response) {/** 第一步,创建一个Workbook,对应一个Excel文件  */XSSFWorkbook wb = new XSSFWorkbook();try {//获取文件内容DayPlanArchiveResultVo dayPlanArchiveResultVo = this.listDayPlanArchive(new DayPlanArchiveDto().setTxtName(txtName));List<DayPlanArchiveVo> dayPlanArchiveVoList = dayPlanArchiveResultVo.getDayPlanArchiveVoList();double allTypeSum = Math.floor(dayPlanArchiveVoList.stream().mapToDouble(DayPlanArchiveVo::getOutput).sum() / 4);Map<String, Double> allTypeByTimeSumMap = dayPlanArchiveVoList.stream().collect(Collectors.groupingBy(vo -> SDF.format(vo.getDateTime()), TreeMap::new, Collectors.summingDouble(DayPlanArchiveVo::getOutput)));List<String> dateList = new ArrayList<>(allTypeByTimeSumMap.keySet());typeList().forEach(typeStr -> {/** 第二步,在Workbook中添加sheet,对应Excel文件中的sheet  */XSSFSheet sheet = wb.createSheet(typeStr);//往sheet录入数据if ("测试数据".equals(typeStr)) {addHyPowerSheet(typeStr, date, sheet, (List<DayPlanArchiveVo>) SerializationUtils.clone((Serializable) dayPlanArchiveVoList), allTypeSum, allTypeByTimeSumMap, dateList);} else if ("测试数据".equals(typeStr)) {addTunePowerSheet(typeStr, date, wb, sheet, dayPlanArchiveResultVo.getCurrentPlanCityTunePowerVoList(), allTypeSum, allTypeByTimeSumMap, dateList);} else {addSheet(typeStr, date, sheet, (List<DayPlanArchiveVo>) SerializationUtils.clone((Serializable) dayPlanArchiveVoList), allTypeSum, allTypeByTimeSumMap, dateList);}//设置样式居中XSSFCellStyle cellStyle = wb.createCellStyle();cellStyle.setAlignment(HorizontalAlignment.CENTER);cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);for (int i = 0; i < sheet.getLastRowNum(); i++) {XSSFRow row = sheet.getRow(i);if (row != null) {for (int j = 0; j < row.getLastCellNum(); j++) {if (row.getCell(j) != null) {row.getCell(j).setCellStyle(cellStyle);}}}}});String fileName = txtName.substring(0, txtName.indexOf(".")) + ".xlsx";response.setContentType("application/octet-stream");// 可自行定义编码格式response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8"));//清除jsp编译html文件的空白,防止excel出现空行response.flushBuffer();OutputStream stream = response.getOutputStream();if (null != stream) {//写出wb.write(stream);wb.close();stream.close();}} catch (Exception e) {e.printStackTrace();} finally {IOUtils.closeQuietly(wb);}}

sheet方法

/*** sheet录入数据*/private void addSheet(String type, String date, XSSFSheet sheet, List<DayPlanArchiveVo> dayPlanArchiveVoList, double allTypeSum, Map<String, Double> allTypeByTimeSumMap, List<String> dateList) {//过滤出类型数据String typeName = type;if ("光伏".equals(typeName)) {typeName = "太阳能";}String finalTypeName = typeName;List<DayPlanArchiveVo> hyPowerList = dayPlanArchiveVoList.stream().filter(vo -> finalTypeName.equals(vo.getCategory())).collect(Collectors.toList());Map<String, String> rqjhMenuMap = rqjhMenu(type, date).getRqjhMenuMap();hyPowerList.forEach(vo -> rqjhMenuMap.entrySet().stream().filter(entry -> entry.getKey().equals(vo.getStationId())).findFirst().ifPresent(entry -> vo.setShortName(entry.getValue())));Map<String, Double> typeSumMap = hyPowerList.stream().collect(Collectors.groupingBy(vo -> SDF.format(vo.getDateTime()), TreeMap::new, Collectors.summingDouble(DayPlanArchiveVo::getOutput)));//集合转变成Map方便读取数据Map<String, Double> hyPowerMap = hyPowerList.stream().collect(Collectors.toMap(vo -> SDF.format(vo.getDateTime()) + vo.getShortName(), DayPlanArchiveVo::getOutput));Map<String, List<String>> head1Map = rqjhMenu(type, date).getHead1Map();List<String> sortRegionList = head1Map.keySet().stream().sorted(Comparator.comparingInt(sortList()::indexOf)).collect(Collectors.toList());//表头第一行List<String> header1StrList = new ArrayList<>();header1StrList.add("时间");header1StrList.add("全网");header1StrList.add(type);//表头第二行List<String> header2StrList = new ArrayList<>();header2StrList.add("");header2StrList.add("测试数据");header2StrList.add("测试数据");for (String s : sortRegionList) {header1StrList.add(s);List<String> stringList = head1Map.get(s);for (int i = 0; i < stringList.size(); i++) {header2StrList.add(stringList.get(i));header1StrList.add("");}//为地市合计header2StrList.add(s + "合计");}System.out.println("第一行表头赋值" + header1StrList);System.out.println("第二行表头赋值" + header2StrList);/** 第四步,创建标题 ,合并标题单元格 */// 行号int rowNum = 0;// 创建第一页的第一行,索引从0开始XSSFRow row0 = sheet.createRow(rowNum++);row0.setHeight((short) 600);// 设置行高//往第一行表头录入数据并合并单元格for (int i = 0; i < header1StrList.size(); i++) {XSSFCell c00 = row0.createCell(i);c00.setCellValue(header1StrList.get(i));//设置第一行表头样式//c00.setCellStyle(headerStyle);}// 合并单元格,参数依次为起始行,结束行,起始列,结束列(索引0开始)sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, 0));int startCol = 3;int endCol;for (String s : sortRegionList) {List<String> stringList = head1Map.get(s);//标题合并单元格操作endCol = startCol + stringList.size();sheet.addMergedRegion(new CellRangeAddress(0, 0, startCol, endCol));System.out.println("第一行表头索引" + startCol + ":" + endCol);startCol = endCol + 1;}//第二行XSSFRow row2 = sheet.createRow(rowNum++);row2.setHeight((short) 700);for (int i = 0; i < header2StrList.size(); i++) {XSSFCell tempCell = row2.createCell(i);tempCell.setCellValue(header2StrList.get(i));if (i > 0) {sheet.setColumnWidth(i, header2StrList.get(i).getBytes(StandardCharsets.UTF_8).length * 256);}}Map<String, Double> statisticsMap = hyPowerList.stream().collect(Collectors.groupingBy(DayPlanArchiveVo::getShortName, Collectors.summingDouble(DayPlanArchiveVo::getOutput)));statisticsMap.replaceAll((key, value) -> Math.floor(value / 4));double currentTypeSum = Math.floor(hyPowerList.stream().mapToDouble(DayPlanArchiveVo::getOutput).sum() / 4);List<String> header3StrList = new ArrayList<>();header3StrList.add("合计");header3StrList.add(String.valueOf(allTypeSum));header3StrList.add(String.valueOf(currentTypeSum));for (String s : sortRegionList) {Double cityTotal = 0.0;List<String> stringList = head1Map.get(s);for (int i = 0; i < stringList.size(); i++) {Double stationTotal = statisticsMap.get(stringList.get(i));if (stationTotal == null) {header3StrList.add("");cityTotal += 0.0;} else {header3StrList.add(String.valueOf(stationTotal));cityTotal += stationTotal;}}//为地市合计统计header3StrList.add(String.valueOf(cityTotal));}//第三行XSSFRow row3 = sheet.createRow(rowNum++);row3.setHeight((short) 700);for (int i = 0; i < header3StrList.size(); i++) {XSSFCell tempCell = row3.createCell(i);if (i > 0) {if (StringUtils.isNotEmpty(header3StrList.get(i))) {tempCell.setCellValue(Double.parseDouble(header3StrList.get(i)));} else {tempCell.setCellValue(header3StrList.get(i));}} else {tempCell.setCellValue(header3StrList.get(i));}}//业务数据List<List<String>> itemList = new ArrayList<>();dateList.forEach(dateStr -> {List<String> voList = new ArrayList<>();voList.add(dateStr);voList.add(String.valueOf(allTypeByTimeSumMap.get(dateStr)));voList.add(String.valueOf(typeSumMap.get(dateStr) == null ? "0" : typeSumMap.get(dateStr)));for (String key : sortRegionList) {Double totalByTime = 0.0;List<String> head2List = head1Map.get(key);for (String shortName : head2List) {Double output = hyPowerMap.get(dateStr + shortName);if (output != null) {Double aDouble = Math.floor(hyPowerMap.get(dateStr + shortName));totalByTime += aDouble;voList.add(String.valueOf(aDouble));} else {voList.add("");}//System.out.println(shortName + aDouble);}voList.add(String.valueOf(totalByTime));//System.out.println(key + "合计" + totalByTime);}itemList.add(voList);});for (List<String> stringList : itemList) {//业务数据录入XSSFRow row = sheet.createRow(rowNum++);row3.setHeight((short) 700);for (int i = 0; i < stringList.size(); i++) {XSSFCell tempCell = row.createCell(i);if (i > 0) {if (StringUtils.isEmpty(stringList.get(i))) {tempCell.setCellValue(stringList.get(i));} else {tempCell.setCellValue(Double.parseDouble(stringList.get(i)));}} else {tempCell.setCellValue(stringList.get(i));}}}}/*** sheet录入数据*/private void addHyPowerSheet(String type, String date, XSSFSheet sheet, List<DayPlanArchiveVo> dayPlanArchiveVoList, double allTypeSum, Map<String, Double> allTypeByTimeSumMap, List<String> dateList) {List<DayPlanArchiveVo> hyPowerList = dayPlanArchiveVoList.stream().filter(vo -> type.equals(vo.getCategory())).collect(Collectors.toList());Map<String, String> rqjhMenuMap = rqjhMenu(type, date).getRqjhMenuMap();hyPowerList.forEach(vo -> rqjhMenuMap.entrySet().stream().filter(entry -> entry.getKey().equals(vo.getStationId())).findFirst().ifPresent(entry -> vo.setShortName(entry.getValue())));Map<String, Double> typeSumMap = hyPowerList.stream().collect(Collectors.groupingBy(vo -> SDF.format(vo.getDateTime()), TreeMap::new, Collectors.summingDouble(DayPlanArchiveVo::getOutput)));//集合转变成Map方便读取数据Map<String, Double> hyPowerMap = hyPowerList.stream().collect(Collectors.toMap(vo -> SDF.format(vo.getDateTime()) + vo.getShortName(), DayPlanArchiveVo::getOutput));Map<String, List<String>> head1Map = new HashMap<>(rqjhMenu(type, date).getWaterHead1Map());List<String> sortRegionList = head1Map.keySet().stream().sorted(Comparator.comparingInt(sortList()::indexOf)).collect(Collectors.toList());//表头第一行List<String> header1StrList = new ArrayList<>();header1StrList.add("时间");header1StrList.add("全网");header1StrList.add(type);//表头第二行List<String> header2StrList = new ArrayList<>();header2StrList.add("");header2StrList.add("测试数据");header2StrList.add("测试数据");for (String s : sortRegionList) {header1StrList.add(s);List<String> stringList = head1Map.get(s);for (int i = 0; i < stringList.size(); i++) {header2StrList.add(stringList.get(i));header1StrList.add("");}//为地市合计header2StrList.add(s + "合计");}System.out.println("第一行表头赋值" + header1StrList);System.out.println("第二行表头赋值" + header2StrList);/** 创建标题 ,合并标题单元格 */// 行号int rowNum = 0;// 创建第一页的第一行,索引从0开始XSSFRow row0 = sheet.createRow(rowNum++);row0.setHeight((short) 600);// 设置行高//往第一行表头录入数据并合并单元格for (int i = 0; i < header1StrList.size(); i++) {XSSFCell c00 = row0.createCell(i);c00.setCellValue(header1StrList.get(i));//设置第一行表头样式//c00.setCellStyle(headerStyle);}// 合并单元格,参数依次为起始行,结束行,起始列,结束列(索引0开始)sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, 0));int startCol = 3;int endCol;for (String s : sortRegionList) {List<String> stringList = head1Map.get(s);//标题合并单元格操作endCol = startCol + stringList.size();sheet.addMergedRegion(new CellRangeAddress(0, 0, startCol, endCol));System.out.println("第一行表头索引" + startCol + ":" + endCol);startCol = endCol + 1;}//第二行XSSFRow row2 = sheet.createRow(rowNum++);row2.setHeight((short) 700);for (int i = 0; i < header2StrList.size(); i++) {XSSFCell tempCell = row2.createCell(i);tempCell.setCellValue(header2StrList.get(i));if (i > 0) {sheet.setColumnWidth(i, header2StrList.get(i).getBytes(StandardCharsets.UTF_8).length * 256);}}Map<String, Double> statisticsMap = hyPowerList.stream().collect(Collectors.groupingBy(DayPlanArchiveVo::getShortName, Collectors.summingDouble(DayPlanArchiveVo::getOutput)));statisticsMap.replaceAll((key, value) -> Math.floor(value / 4));double currentTypeSum = Math.floor(hyPowerList.stream().mapToDouble(DayPlanArchiveVo::getOutput).sum() / 4);List<String> header3StrList = new ArrayList<>();header3StrList.add("合计");header3StrList.add(String.valueOf(allTypeSum));header3StrList.add(String.valueOf(currentTypeSum));for (String s : sortRegionList) {Double cityTotal = 0.0;List<String> stringList = head1Map.get(s);for (int i = 0; i < stringList.size(); i++) {Double stationTotal = statisticsMap.get(stringList.get(i));if (stationTotal == null) {header3StrList.add("");cityTotal += 0.0;} else {header3StrList.add(String.valueOf(stationTotal));cityTotal += stationTotal;}}header3StrList.add(String.valueOf(cityTotal));}//第三行XSSFRow row3 = sheet.createRow(rowNum++);row3.setHeight((short) 700);for (int i = 0; i < header3StrList.size(); i++) {XSSFCell tempCell = row3.createCell(i);if (i > 0) {if (StringUtils.isNotEmpty(header3StrList.get(i))) {tempCell.setCellValue(Double.parseDouble(header3StrList.get(i)));} else {tempCell.setCellValue(header3StrList.get(i));}} else {tempCell.setCellValue(header3StrList.get(i));}}//业务数据List<List<String>> itemList = new ArrayList<>();dateList.forEach(dateStr -> {List<String> voList = new ArrayList<>();voList.add(dateStr);voList.add(String.valueOf(allTypeByTimeSumMap.get(dateStr)));voList.add(String.valueOf(typeSumMap.get(dateStr)));for (String key : sortRegionList) {Double totalByTime = 0.0;List<String> head2List = head1Map.get(key);for (String shortName : head2List) {Double output = hyPowerMap.get(dateStr + shortName);if (output != null) {Double aDouble = Math.floor(hyPowerMap.get(dateStr + shortName));totalByTime += aDouble;voList.add(String.valueOf(aDouble));} else {voList.add("");}//System.out.println(shortName + aDouble);}voList.add(String.valueOf(totalByTime));//System.out.println(key + "合计" + totalByTime);}itemList.add(voList);});for (List<String> stringList : itemList) {//业务数据录入XSSFRow row = sheet.createRow(rowNum++);row3.setHeight((short) 700);for (int i = 0; i < stringList.size(); i++) {XSSFCell tempCell = row.createCell(i);if (i > 0) {if (StringUtils.isEmpty(stringList.get(i))) {tempCell.setCellValue(stringList.get(i));} else {tempCell.setCellValue(Double.parseDouble(stringList.get(i)));}} else {tempCell.setCellValue(stringList.get(i));}}}}/*** sheet录入数据*/private void addTunePowerSheet(String type, String date, XSSFWorkbook wb, XSSFSheet sheet, List<CurrentPlanCityTunePowerVo> dayPlanArchiveVoList, double allTypeSum, Map<String, Double> allTypeByTimeSumMap, List<String> dateList) {List<CurrentPlanCityTunePowerVo> currentPlanCityTunePowerVoList = (List<CurrentPlanCityTunePowerVo>) SerializationUtils.clone((Serializable) dayPlanArchiveVoList);//过滤空List<CurrentPlanCityTunePowerVo> filterList = currentPlanCityTunePowerVoList.stream().filter(vo -> vo.getOutput() != null).collect(Collectors.toList());//集合转变成Map方便读取数据Map<String, Double> tunePowerMap = filterList.stream().collect(Collectors.toMap(vo -> vo.getDateTime() + vo.getAreaName() + vo.getType(), CurrentPlanCityTunePowerVo::getOutput));Map<String, List<String>> head1Map = dayPlanArchiveVoList.stream().filter(vo -> vo.getAreaName() != null).collect(Collectors.groupingBy(CurrentPlanCityTunePowerVo::getAreaName,Collectors.mapping(CurrentPlanCityTunePowerVo::getType, Collectors.collectingAndThen(Collectors.toList(), values -> values.stream().distinct().collect(Collectors.toList())))));List<String> sortRegionList = head1Map.keySet().stream().sorted(Comparator.comparingInt(sortList()::indexOf)).collect(Collectors.toList());//表头第一行List<String> header1StrList = new ArrayList<>();header1StrList.add("时间");header1StrList.add("全网");header1StrList.add(type);header1StrList.add("测试数据");header1StrList.add("测试数据");header1StrList.add("测试数据");//表头第二行List<String> header2StrList = new ArrayList<>();header2StrList.add("");header2StrList.add("测试数据");header2StrList.add("测试数据");header2StrList.add("测试数据");header2StrList.add("测试数据");header2StrList.add("测试数据");for (String s : sortRegionList) {header1StrList.add(s);List<String> stringList = head1Map.get(s);for (int i = 0; i < stringList.size(); i++) {header2StrList.add(s.substring(0, s.length() - 1) + stringList.get(i));header1StrList.add("");}//为地市合计header2StrList.add(s + "合计");}System.out.println("第一行表头赋值" + header1StrList);System.out.println("第二行表头赋值" + header2StrList);/** 创建标题 ,合并标题单元格 */// 行号int rowNum = 0;// 创建第一页的第一行,索引从0开始XSSFRow row0 = sheet.createRow(rowNum++);row0.setHeight((short) 600);// 设置行高//往第一行表头录入数据并合并单元格for (int i = 0; i < header1StrList.size(); i++) {XSSFCell c00 = row0.createCell(i);c00.setCellValue(header1StrList.get(i));}// 合并单元格,参数依次为起始行,结束行,起始列,结束列(索引0开始)sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, 0));int startCol = 6;int endCol;for (String s : sortRegionList) {List<String> stringList = head1Map.get(s);//标题合并单元格操作endCol = startCol + stringList.size();sheet.addMergedRegion(new CellRangeAddress(0, 0, startCol, endCol));System.out.println("第一行表头索引" + startCol + ":" + endCol);startCol = endCol + 1;}//第二行XSSFRow row2 = sheet.createRow(rowNum++);row2.setHeight((short) 700);for (int i = 0; i < header2StrList.size(); i++) {XSSFCell tempCell = row2.createCell(i);tempCell.setCellValue(header2StrList.get(i));if (i > 0) {sheet.setColumnWidth(i, header2StrList.get(i).getBytes(StandardCharsets.UTF_8).length * 256);}}Map<String, Map<String, Double>> cityTypeMap = filterList.stream().filter(vo -> vo.getAreaName() != null).collect(Collectors.groupingBy(CurrentPlanCityTunePowerVo::getAreaName, TreeMap::new, Collectors.groupingBy(CurrentPlanCityTunePowerVo::getType, Collectors.summingDouble(CurrentPlanCityTunePowerVo::getOutput))));List<String> header3StrList = new ArrayList<>();header3StrList.add("合计");header3StrList.add(String.valueOf(allTypeSum));double currentTypeSum = Math.floor(filterList.stream().mapToDouble(CurrentPlanCityTunePowerVo::getOutput).sum() / 4);header3StrList.add(String.valueOf(currentTypeSum));Map<String, Double> perfectrueMap = filterList.stream().filter(vo -> vo.getAreaName() == null).collect(Collectors.groupingBy(CurrentPlanCityTunePowerVo::getType, Collectors.summingDouble(CurrentPlanCityTunePowerVo::getOutput)));header3StrList.add(String.valueOf(perfectrueMap.get("测试数据")));header3StrList.add(String.valueOf(perfectrueMap.get("测试数据")));header3StrList.add(String.valueOf(perfectrueMap.get("测试数据")));for (String s : sortRegionList) {Double cityTotal = 0.0;List<String> stringList = head1Map.get(s);for (int i = 0; i < stringList.size(); i++) {Double stationTotal = cityTypeMap.get(s).get(stringList.get(i));if (stationTotal == null) {header3StrList.add("0");cityTotal += 0.0;} else {header3StrList.add(String.valueOf(stationTotal));cityTotal += stationTotal;}}//地市(网调省调)合计header3StrList.add(String.valueOf(cityTotal));}//第三行XSSFRow row3 = sheet.createRow(rowNum++);row3.setHeight((short) 700);for (int i = 0; i < header3StrList.size(); i++) {XSSFCell tempCell = row3.createCell(i);if (i > 0) {if (StringUtils.isNotEmpty(header3StrList.get(i))) {tempCell.setCellValue(Double.parseDouble(header3StrList.get(i)));} else {tempCell.setCellValue(header3StrList.get(i));}} else {tempCell.setCellValue(header3StrList.get(i));}}//业务数据Map<String, Double> typeSumMap = filterList.stream().filter(vo -> vo.getAreaName() != null).collect(Collectors.groupingBy(CurrentPlanCityTunePowerVo::getDateTime, TreeMap::new, Collectors.summingDouble(CurrentPlanCityTunePowerVo::getOutput)));Map<String, Map<String, Double>> tunePreFectureMap = filterList.stream().filter(vo -> vo.getAreaName() == null).collect(Collectors.groupingBy(CurrentPlanCityTunePowerVo::getDateTime, TreeMap::new, Collectors.groupingBy(CurrentPlanCityTunePowerVo::getType, Collectors.summingDouble(CurrentPlanCityTunePowerVo::getOutput))));List<List<String>> itemList = new ArrayList<>();dateList.forEach(dateStr -> {List<String> voList = new ArrayList<>();voList.add(dateStr);voList.add(String.valueOf(allTypeByTimeSumMap.get(dateStr)));voList.add(String.valueOf(typeSumMap.get(dateStr)));voList.add(String.valueOf(tunePreFectureMap.get(dateStr).get("测试数据")));voList.add(String.valueOf(tunePreFectureMap.get(dateStr).get("测试数据")));voList.add(String.valueOf(tunePreFectureMap.get(dateStr).get("测试数据")));for (String key : sortRegionList) {Double totalByTime = 0.0;List<String> head2List = head1Map.get(key);for (String shortName : head2List) {Double output = tunePowerMap.get(dateStr + key + shortName);if (output != null) {Double aDouble = Math.floor(tunePowerMap.get(dateStr + key + shortName));totalByTime += aDouble;voList.add(String.valueOf(aDouble));} else {voList.add("");}}voList.add(String.valueOf(totalByTime));}itemList.add(voList);});for (List<String> stringList : itemList) {//业务数据录入XSSFRow row = sheet.createRow(rowNum++);row3.setHeight((short) 700);for (int i = 0; i < stringList.size(); i++) {XSSFCell tempCell = row.createCell(i);if (i > 0) {if (StringUtils.isEmpty(stringList.get(i))) {tempCell.setCellValue(stringList.get(i));} else {tempCell.setCellValue(Double.parseDouble(stringList.get(i)));}} else {tempCell.setCellValue(stringList.get(i));}}}}

业务工具方法

/*** 类型*/private List<String> typeList() {return Arrays.asList("水电", "风电", "光伏", "储能", "小火电", "地调发电");}/*** 获取电站名称集合*/private DayPlanArchiveHeadVo rqjhMenu(String type, String date) {DayPlanArchiveHeadVo dayPlanArchiveHeadVo = new DayPlanArchiveHeadVo();List<PowerStationInfo> powerStationInfoList = powerStationWhService.rqjhMenu(jsonObject);Map<String, List<String>> head1Map = powerStationInfoList.stream().collect(Collectors.groupingBy(PowerStationInfo::getDispatchingAgency,Collectors.mapping(PowerStationInfo::getName, Collectors.collectingAndThen(Collectors.toList(), values -> values.stream().distinct().collect(Collectors.toList())))));Map<String, String> rqjhMenuMap = powerStationInfoList.stream().collect(Collectors.toMap(PowerStationInfo::getId, PowerStationInfo::getName));dayPlanArchiveHeadVo.setHead1Map(head1Map);dayPlanArchiveHeadVo.setRqjhMenuMap(rqjhMenuMap);if ("水电".equals(type)) {Map<String, List<String>> waterHead1Map = new HashMap<>();waterHead1Map.putAll(powerStationInfoList.stream().collect(Collectors.groupingBy(PowerStationInfo::getDispatchingAgency,Collectors.mapping(PowerStationInfo::getName, Collectors.collectingAndThen(Collectors.toList(), values -> values.stream().distinct().collect(Collectors.toList()))))));dayPlanArchiveHeadVo.setWaterHead1Map(waterHead1Map);}return dayPlanArchiveHeadVo;}/*** 按照指定顺序排序*/private List<String> sortList() {return Arrays.asList("网调", "省调", "长沙市", "湘潭市", "益阳市", "株洲市", "岳阳市", "常德市", "湘西州", "张家界市", "娄底市", "邵阳市", "怀化市", "衡阳市", "郴州市", "永州市");}

实现效果

在这里插入图片描述

这篇关于java导出excel动态加载多sheet多复杂表头的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/990510

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听