Commit 387905ca authored by duwei's avatar duwei

指标导出接口开发-按字段导出

parent bc8d9c28
...@@ -3,12 +3,16 @@ package net.wanji.opt.common; ...@@ -3,12 +3,16 @@ package net.wanji.opt.common;
import com.alibaba.excel.EasyExcel; import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.wanji.opt.dto.export.utils.DynamicExportLaneDataElement;
import javax.servlet.ServletOutputStream; import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
/** /**
* @author duanruiming * @author duanruiming
...@@ -45,4 +49,68 @@ public class ExcelExportUtils { ...@@ -45,4 +49,68 @@ public class ExcelExportUtils {
throw new Exception("导出excel异常:" + e.getMessage(), e); throw new Exception("导出excel异常:" + e.getMessage(), e);
} }
} }
/**
* 动态导出excel
* @param response
* @param startStr
* @param endStr
* @param dataList
* @param sheetName
* @throws Exception
*/
public static void exportExcel(HttpServletResponse response, String startStr, String endStr,
List<DynamicExportLaneDataElement> dataList, String sheetName) throws Exception {
// 文件名 sheet名称添加日期
String fileName = sheetName.concat(startStr).concat("~").concat(endStr)
.replaceAll(":", " ").replaceAll(" ", "-").concat(".xlsx"); // 注意文件扩展名应为.xlsx,因为你设置了xlsx的MIME类型
// 设置响应头
response.setCharacterEncoding("UTF-8");
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20"));
// 使用EasyExcel进行导出
try (ServletOutputStream outputStream = response.getOutputStream()) {
// 手动提取表头(确保dataList不为空)
if (dataList.isEmpty()) {
log.error("{}导出excel异常:dataList为空", fileName);
return;
}
DynamicExportLaneDataElement de = dataList.get(0);
List<String> headerList = de.getFields().stream()
.map(DynamicExportLaneDataElement.DynamicField::getFieldName)
.collect(Collectors.toList());
// 构建表头结构(List<List<String>>)
List<List<String>> head = headerList.stream()
.map(Collections::singletonList)
.collect(Collectors.toList());
// 配置WriteSheet并绑定表头
WriteSheet writeSheet = EasyExcel.writerSheet(sheetName)
.head(head) // 关键:通过head()方法绑定表头
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 自动列宽
.build();
// 提取数据行(List<List<Object>>)
List<List<Object>> data = dataList.stream()
.map(element -> element.getFields().stream()
.map(DynamicExportLaneDataElement.DynamicField::getFieldValue)
.collect(Collectors.toList()))
.collect(Collectors.toList());
// 直接写入数据(无需单独写表头)
EasyExcel.write(outputStream)
.autoCloseStream(true)
.sheet(sheetName)
.head(head)
.doWrite(data);
} catch (Exception e) {
log.error("{}导出excel异常:", fileName, e);
throw new Exception("导出excel异常:" + e.getMessage(), e);
}
}
} }
package net.wanji.opt.dto.export;
import java.util.HashMap;
import java.util.Map;
/**
* 路口级别映射
*/
public class CrossMapping {
public static final Map<String, String> CYCLE_DATA_FIELD_MAPPING = new HashMap<>();
static {
// CycleDataElement 字段映射
CYCLE_DATA_FIELD_MAPPING.put("time", "time");
CYCLE_DATA_FIELD_MAPPING.put("allFlow", "allFlow");
CYCLE_DATA_FIELD_MAPPING.put("pedFlow", "pedFlow");
CYCLE_DATA_FIELD_MAPPING.put("nonMotorFlow", "nonMotorFlow");
CYCLE_DATA_FIELD_MAPPING.put("trafficFlowC", "trafficFlowC");
CYCLE_DATA_FIELD_MAPPING.put("trafficFlowB", "trafficFlowB");
CYCLE_DATA_FIELD_MAPPING.put("trafficFlowA", "trafficFlowA");
CYCLE_DATA_FIELD_MAPPING.put("speed", "speed");
CYCLE_DATA_FIELD_MAPPING.put("vehheadDist", "vehheadDist");
CYCLE_DATA_FIELD_MAPPING.put("vehheadTime", "vehheadTime");
CYCLE_DATA_FIELD_MAPPING.put("queueLength", "queueLength");
CYCLE_DATA_FIELD_MAPPING.put("stopTimes", "stopTimes");
CYCLE_DATA_FIELD_MAPPING.put("laneSort", "laneSort");
CYCLE_DATA_FIELD_MAPPING.put("delayTime", "delayTime");
CYCLE_DATA_FIELD_MAPPING.put("efficiencyIndex", "efficiencyIndex");
CYCLE_DATA_FIELD_MAPPING.put("efficiencyEvaluateLevel", "efficiencyEvaluateLevel");
CYCLE_DATA_FIELD_MAPPING.put("saturation", "saturation");
CYCLE_DATA_FIELD_MAPPING.put("congestionIndex", "congestionIndex");
CYCLE_DATA_FIELD_MAPPING.put("overflowIndex", "overflowIndex");
CYCLE_DATA_FIELD_MAPPING.put("imbalanceIndex", "imbalanceIndex");
CYCLE_DATA_FIELD_MAPPING.put("timeOccupancy", "timeOccupancy");
CYCLE_DATA_FIELD_MAPPING.put("vehicleNumsRatioMean", "vehicleNumsRatioMean");
CYCLE_DATA_FIELD_MAPPING.put("v85", "v85");
CYCLE_DATA_FIELD_MAPPING.put("serviceLevel", "serviceLevel");
CYCLE_DATA_FIELD_MAPPING.put("congestionTimes", "congestionTimes");
CYCLE_DATA_FIELD_MAPPING.put("overflowTimes", "overflowTimes");
CYCLE_DATA_FIELD_MAPPING.put("imbalanceTimes", "imbalanceTimes");
CYCLE_DATA_FIELD_MAPPING.put("freeFlowTimes", "freeFlowTimes");
CYCLE_DATA_FIELD_MAPPING.put("overflowRate", "overflowRate");
CYCLE_DATA_FIELD_MAPPING.put("conflictPoint", "conflictPoint");
CYCLE_DATA_FIELD_MAPPING.put("safetyCoefficient", "safetyCoefficient");
CYCLE_DATA_FIELD_MAPPING.put("safetyEvaluateLevel", "safetyEvaluateLevel");
CYCLE_DATA_FIELD_MAPPING.put("trafficEventNum", "trafficEventNum");
CYCLE_DATA_FIELD_MAPPING.put("trafficAccidentNum", "trafficAccidentNum");
CYCLE_DATA_FIELD_MAPPING.put("noStopPassRate", "noStopPassRate");
CYCLE_DATA_FIELD_MAPPING.put("oneStopPassRate", "oneStopPassRate");
CYCLE_DATA_FIELD_MAPPING.put("twoStopPassRate", "twoStopPassRate");
CYCLE_DATA_FIELD_MAPPING.put("crossNoClearRate", "crossNoClearRate");
CYCLE_DATA_FIELD_MAPPING.put("avgQueueLength", "avgQueueLength");
CYCLE_DATA_FIELD_MAPPING.put("greenLightEfficiency", "greenLightEfficiency");
CYCLE_DATA_FIELD_MAPPING.put("pedAvgPassTime", "pedAvgPassTime");
CYCLE_DATA_FIELD_MAPPING.put("pedCrossRedLightRate", "pedCrossRedLightRate");
CYCLE_DATA_FIELD_MAPPING.put("allVehiceleFlow", "allVehiceleFlow"); // 疑似拼写错误(应为 allVehicleFlow)
}
}
package net.wanji.opt.dto.export;
import java.util.HashMap;
import java.util.Map;
/**
* 方向级别映射
*/
public class DirMapping {
public static final Map<String, String> CYCLE_DATA_FIELD_MAPPING = new HashMap<>();
static {
// CycleDataElement 字段映射
CYCLE_DATA_FIELD_MAPPING.put("time", "time");
CYCLE_DATA_FIELD_MAPPING.put("dirName", "dirName");
CYCLE_DATA_FIELD_MAPPING.put("allFlow", "allFlow");
CYCLE_DATA_FIELD_MAPPING.put("pedFlow", "pedFlow");
CYCLE_DATA_FIELD_MAPPING.put("nonMotorFlow", "nonMotorFlow");
CYCLE_DATA_FIELD_MAPPING.put("trafficFlowC", "trafficFlowC");
CYCLE_DATA_FIELD_MAPPING.put("trafficFlowB", "trafficFlowB");
CYCLE_DATA_FIELD_MAPPING.put("trafficFlowA", "trafficFlowA");
CYCLE_DATA_FIELD_MAPPING.put("speed", "speed");
CYCLE_DATA_FIELD_MAPPING.put("vehheadDist", "vehheadDist");
CYCLE_DATA_FIELD_MAPPING.put("vehheadTime", "vehheadTime");
CYCLE_DATA_FIELD_MAPPING.put("queueLength", "queueLength");
CYCLE_DATA_FIELD_MAPPING.put("stopTimes", "stopTimes");
CYCLE_DATA_FIELD_MAPPING.put("laneSort", "laneSort");
CYCLE_DATA_FIELD_MAPPING.put("delayTime", "delayTime");
CYCLE_DATA_FIELD_MAPPING.put("efficiencyIndex", "efficiencyIndex");
CYCLE_DATA_FIELD_MAPPING.put("efficiencyEvaluateLevel", "efficiencyEvaluateLevel");
CYCLE_DATA_FIELD_MAPPING.put("saturation", "saturation");
CYCLE_DATA_FIELD_MAPPING.put("congestionIndex", "congestionIndex");
CYCLE_DATA_FIELD_MAPPING.put("overflowIndex", "overflowIndex");
CYCLE_DATA_FIELD_MAPPING.put("imbalanceIndex", "imbalanceIndex");
CYCLE_DATA_FIELD_MAPPING.put("timeOccupancy", "timeOccupancy");
CYCLE_DATA_FIELD_MAPPING.put("vehicleNumsRatioMean", "vehicleNumsRatioMean");
CYCLE_DATA_FIELD_MAPPING.put("v85", "v85");
CYCLE_DATA_FIELD_MAPPING.put("serviceLevel", "serviceLevel");
CYCLE_DATA_FIELD_MAPPING.put("congestionTimes", "congestionTimes");
CYCLE_DATA_FIELD_MAPPING.put("overflowTimes", "overflowTimes");
CYCLE_DATA_FIELD_MAPPING.put("imbalanceTimes", "imbalanceTimes");
CYCLE_DATA_FIELD_MAPPING.put("freeFlowTimes", "freeFlowTimes");
CYCLE_DATA_FIELD_MAPPING.put("overflowRate", "overflowRate");
CYCLE_DATA_FIELD_MAPPING.put("conflictPoint", "conflictPoint");
CYCLE_DATA_FIELD_MAPPING.put("safetyCoefficient", "safetyCoefficient");
CYCLE_DATA_FIELD_MAPPING.put("safetyEvaluateLevel", "safetyEvaluateLevel");
CYCLE_DATA_FIELD_MAPPING.put("trafficEventNum", "trafficEventNum");
CYCLE_DATA_FIELD_MAPPING.put("trafficAccidentNum", "trafficAccidentNum");
CYCLE_DATA_FIELD_MAPPING.put("noStopPassRate", "noStopPassRate");
CYCLE_DATA_FIELD_MAPPING.put("oneStopPassRate", "oneStopPassRate");
CYCLE_DATA_FIELD_MAPPING.put("twoStopPassRate", "twoStopPassRate");
CYCLE_DATA_FIELD_MAPPING.put("crossNoClearRate", "crossNoClearRate");
CYCLE_DATA_FIELD_MAPPING.put("avgQueueLength", "avgQueueLength");
CYCLE_DATA_FIELD_MAPPING.put("greenLightEfficiency", "greenLightEfficiency");
CYCLE_DATA_FIELD_MAPPING.put("pedAvgPassTime", "pedAvgPassTime");
CYCLE_DATA_FIELD_MAPPING.put("pedCrossRedLightRate", "pedCrossRedLightRate");
CYCLE_DATA_FIELD_MAPPING.put("allVehiceleFlow", "allVehiceleFlow"); // 注意:"allVehiceleFlow"疑似拼写错误(应为allVehicleFlow?)
}
}
package net.wanji.opt.dto.export;
import java.util.HashMap;
import java.util.Map;
/**
* 车道级别映射
*/
public class LaneMapping {
public static final Map<String, String> CYCLE_DATA_FIELD_MAPPING = new HashMap<>();
static {
// CycleDataElement 字段映射
CYCLE_DATA_FIELD_MAPPING.put("time", "time");
CYCLE_DATA_FIELD_MAPPING.put("dir", "dir");
CYCLE_DATA_FIELD_MAPPING.put("dirName", "dirName");
CYCLE_DATA_FIELD_MAPPING.put("turn", "turn");
CYCLE_DATA_FIELD_MAPPING.put("laneSort", "laneSort");
CYCLE_DATA_FIELD_MAPPING.put("flow", "flow");
CYCLE_DATA_FIELD_MAPPING.put("queueLength", "queueLength");
CYCLE_DATA_FIELD_MAPPING.put("delayTime", "delayTime");
CYCLE_DATA_FIELD_MAPPING.put("efficiencyIndex", "efficiencyIndex");
CYCLE_DATA_FIELD_MAPPING.put("efficiencyEvaluateLevel", "efficiencyEvaluateLevel");
CYCLE_DATA_FIELD_MAPPING.put("stopTimes", "stopTimes");
CYCLE_DATA_FIELD_MAPPING.put("vehheadTime", "vehheadTime");
CYCLE_DATA_FIELD_MAPPING.put("saturation", "saturation");
CYCLE_DATA_FIELD_MAPPING.put("congestionIndex", "congestionIndex");
CYCLE_DATA_FIELD_MAPPING.put("overflowIndex", "overflowIndex");
CYCLE_DATA_FIELD_MAPPING.put("imbalanceIndex", "imbalanceIndex");
CYCLE_DATA_FIELD_MAPPING.put("vehheadDist", "vehheadDist");
CYCLE_DATA_FIELD_MAPPING.put("timeOccupancy", "timeOccupancy");
CYCLE_DATA_FIELD_MAPPING.put("vehicleNumsRatioMean", "vehicleNumsRatioMean");
CYCLE_DATA_FIELD_MAPPING.put("v85", "v85");
CYCLE_DATA_FIELD_MAPPING.put("speed", "speed");
CYCLE_DATA_FIELD_MAPPING.put("trafficFlowA", "trafficFlowA");
CYCLE_DATA_FIELD_MAPPING.put("trafficFlowB", "trafficFlowB");
CYCLE_DATA_FIELD_MAPPING.put("trafficFlowC", "trafficFlowC");
CYCLE_DATA_FIELD_MAPPING.put("nonMotorFlow", "nonMotorFlow");
CYCLE_DATA_FIELD_MAPPING.put("pedFlow", "pedFlow");
CYCLE_DATA_FIELD_MAPPING.put("serviceLevel", "serviceLevel");
CYCLE_DATA_FIELD_MAPPING.put("congestionTimes", "congestionTimes");
CYCLE_DATA_FIELD_MAPPING.put("overflowTimes", "overflowTimes");
CYCLE_DATA_FIELD_MAPPING.put("imbalanceTimes", "imbalanceTimes");
CYCLE_DATA_FIELD_MAPPING.put("freeFlowTimes", "freeFlowTimes");
CYCLE_DATA_FIELD_MAPPING.put("overflowRate", "overflowRate");
CYCLE_DATA_FIELD_MAPPING.put("conflictPoint", "conflictPoint");
CYCLE_DATA_FIELD_MAPPING.put("safetyCoefficient", "safetyCoefficient");
CYCLE_DATA_FIELD_MAPPING.put("safetyEvaluateLevel", "safetyEvaluateLevel");
CYCLE_DATA_FIELD_MAPPING.put("trafficEventNum", "trafficEventNum");
CYCLE_DATA_FIELD_MAPPING.put("trafficAccidentNum", "trafficAccidentNum");
CYCLE_DATA_FIELD_MAPPING.put("noStopPassRate", "noStopPassRate");
CYCLE_DATA_FIELD_MAPPING.put("oneStopPassRate", "oneStopPassRate");
CYCLE_DATA_FIELD_MAPPING.put("twoStopPassRate", "twoStopPassRate");
CYCLE_DATA_FIELD_MAPPING.put("crossNoClearRate", "crossNoClearRate");
CYCLE_DATA_FIELD_MAPPING.put("avgQueueLength", "avgQueueLength");
CYCLE_DATA_FIELD_MAPPING.put("greenLightEfficiency", "greenLightEfficiency");
CYCLE_DATA_FIELD_MAPPING.put("pedAvgPassTime", "pedAvgPassTime");
CYCLE_DATA_FIELD_MAPPING.put("pedCrossRedLightRate", "pedCrossRedLightRate");
CYCLE_DATA_FIELD_MAPPING.put("allVehiceleFlow", "allVehiceleFlow");
CYCLE_DATA_FIELD_MAPPING.put("allFlow", "allFlow");
}
}
package net.wanji.opt.dto.export;
import java.util.HashMap;
import java.util.Map;
/**
* 转向级别映射
*/
public class TurnMapping {
public static final Map<String, String> CYCLE_DATA_FIELD_MAPPING = new HashMap<>();
static {
// CycleDataElement 字段映射
CYCLE_DATA_FIELD_MAPPING.put("time", "time");
CYCLE_DATA_FIELD_MAPPING.put("inDir", "inDir");
CYCLE_DATA_FIELD_MAPPING.put("inDirName", "inDirName");
CYCLE_DATA_FIELD_MAPPING.put("turnType", "turnType");
CYCLE_DATA_FIELD_MAPPING.put("turnTypeName", "turnTypeName");
CYCLE_DATA_FIELD_MAPPING.put("allFlow", "allFlow");
CYCLE_DATA_FIELD_MAPPING.put("pedFlow", "pedFlow");
CYCLE_DATA_FIELD_MAPPING.put("nonMotorFlow", "nonMotorFlow");
CYCLE_DATA_FIELD_MAPPING.put("trafficFlowC", "trafficFlowC");
CYCLE_DATA_FIELD_MAPPING.put("trafficFlowB", "trafficFlowB");
CYCLE_DATA_FIELD_MAPPING.put("trafficFlowA", "trafficFlowA");
CYCLE_DATA_FIELD_MAPPING.put("speed", "speed");
CYCLE_DATA_FIELD_MAPPING.put("vehheadDist", "vehheadDist");
CYCLE_DATA_FIELD_MAPPING.put("vehheadTime", "vehheadTime");
CYCLE_DATA_FIELD_MAPPING.put("queueLength", "queueLength");
CYCLE_DATA_FIELD_MAPPING.put("stopTimes", "stopTimes");
CYCLE_DATA_FIELD_MAPPING.put("laneSort", "laneSort");
CYCLE_DATA_FIELD_MAPPING.put("delayTime", "delayTime");
CYCLE_DATA_FIELD_MAPPING.put("efficiencyIndex", "efficiencyIndex");
CYCLE_DATA_FIELD_MAPPING.put("efficiencyEvaluateLevel", "efficiencyEvaluateLevel");
CYCLE_DATA_FIELD_MAPPING.put("saturation", "saturation");
CYCLE_DATA_FIELD_MAPPING.put("congestionIndex", "congestionIndex");
CYCLE_DATA_FIELD_MAPPING.put("overflowIndex", "overflowIndex");
CYCLE_DATA_FIELD_MAPPING.put("imbalanceIndex", "imbalanceIndex");
CYCLE_DATA_FIELD_MAPPING.put("timeOccupancy", "timeOccupancy");
CYCLE_DATA_FIELD_MAPPING.put("vehicleNumsRatioMean", "vehicleNumsRatioMean");
CYCLE_DATA_FIELD_MAPPING.put("v85", "v85");
CYCLE_DATA_FIELD_MAPPING.put("serviceLevel", "serviceLevel");
CYCLE_DATA_FIELD_MAPPING.put("congestionTimes", "congestionTimes");
CYCLE_DATA_FIELD_MAPPING.put("overflowTimes", "overflowTimes");
CYCLE_DATA_FIELD_MAPPING.put("imbalanceTimes", "imbalanceTimes");
CYCLE_DATA_FIELD_MAPPING.put("freeFlowTimes", "freeFlowTimes");
CYCLE_DATA_FIELD_MAPPING.put("overflowRate", "overflowRate");
CYCLE_DATA_FIELD_MAPPING.put("conflictPoint", "conflictPoint");
CYCLE_DATA_FIELD_MAPPING.put("safetyCoefficient", "safetyCoefficient");
CYCLE_DATA_FIELD_MAPPING.put("safetyEvaluateLevel", "safetyEvaluateLevel");
CYCLE_DATA_FIELD_MAPPING.put("trafficEventNum", "trafficEventNum");
CYCLE_DATA_FIELD_MAPPING.put("trafficAccidentNum", "trafficAccidentNum");
CYCLE_DATA_FIELD_MAPPING.put("noStopPassRate", "noStopPassRate");
CYCLE_DATA_FIELD_MAPPING.put("oneStopPassRate", "oneStopPassRate");
CYCLE_DATA_FIELD_MAPPING.put("twoStopPassRate", "twoStopPassRate");
CYCLE_DATA_FIELD_MAPPING.put("crossNoClearRate", "crossNoClearRate");
CYCLE_DATA_FIELD_MAPPING.put("avgQueueLength", "avgQueueLength");
CYCLE_DATA_FIELD_MAPPING.put("greenLightEfficiency", "greenLightEfficiency");
CYCLE_DATA_FIELD_MAPPING.put("pedAvgPassTime", "pedAvgPassTime");
CYCLE_DATA_FIELD_MAPPING.put("pedCrossRedLightRate", "pedCrossRedLightRate");
CYCLE_DATA_FIELD_MAPPING.put("allVehiceleFlow", "allVehiceleFlow");
}
}
package net.wanji.opt.dto.export.utils;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import net.wanji.opt.dto.export.LaneMapping;
import net.wanji.opt.vo.TableQueryVO;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 车道级数据导出元素
*/
@Slf4j
@Data
public class DynamicExportLaneDataElement {
private List<DynamicField> fields = new ArrayList<>();
@Data
public static class DynamicField {
@ExcelProperty
private String fieldName;
@ExcelProperty
private Object fieldValue;
public DynamicField(String fieldName, Object fieldValue) {
this.fieldName = fieldName;
this.fieldValue = fieldValue;
}
}
/**
* 提取数据元素的指定字段值,并转换为动态导出元素
*
* @param element 数据元素
* @param selectedFields 选中的字段
* @param fieldMapping 字段映射
* @param clazz 数据元素的类
* @return
*/
public static DynamicExportLaneDataElement fromCycleDataElement(Class clazz, Object element, List<String> selectedFields, Map<String, String> fieldMapping) {
DynamicExportLaneDataElement dynamicElement = new DynamicExportLaneDataElement();
for (String fieldName : selectedFields) {
String mappedFieldName = fieldMapping.get(fieldName);
if (mappedFieldName != null) {
try {
Field field = clazz.getDeclaredField(mappedFieldName);
field.setAccessible(true);
//提取@ExcelProperty("方向名称")注解的字段值
ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
if (excelProperty != null) {
if (field.get(element) == null) {
dynamicElement.getFields().add(new DynamicField(excelProperty.value()[0], "0"));
} else {
dynamicElement.getFields().add(new DynamicField(excelProperty.value()[0], field.get(element)));
}
} else {
dynamicElement.getFields().add(new DynamicField(fieldName, field.get(element)));
}
} catch (Exception e) {
log.error("Failed to get field value for field: " + mappedFieldName, e);
}
}
}
return dynamicElement;
}
}
package net.wanji.opt.dto.export.utils;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.CellData;
import com.alibaba.excel.write.handler.WriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import java.util.List;
public class DynamicFieldWriteHandler implements WriteHandler {
private final List<String> headerList;
public DynamicFieldWriteHandler(List<String> headerList) {
this.headerList = headerList;
}
public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
// 创建表头
Sheet sheet = writeSheetHolder.getSheet();
Row headRow = sheet.createRow(0);
for (int i = 0; i < headerList.size(); i++) {
Cell cell = headRow.createCell(i);
cell.setCellValue(headerList.get(i));
}
}
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
if (isHead) {
return;
}
DynamicExportLaneDataElement dataElement = (DynamicExportLaneDataElement) cellDataList.get(0).getData();
List<DynamicExportLaneDataElement.DynamicField> fields = dataElement.getFields();
Sheet sheet = writeSheetHolder.getSheet();
Row row = sheet.getRow(cell.getRowIndex());
for (int i = 0; i < fields.size(); i++) {
Cell fieldCell = row.createCell(i);
fieldCell.setCellValue(fields.get(i).getFieldValue().toString());
}
}
}
...@@ -38,12 +38,16 @@ import net.wanji.opt.dto.CrossEventDTO; ...@@ -38,12 +38,16 @@ import net.wanji.opt.dto.CrossEventDTO;
import net.wanji.opt.dto.CrossLaneSnapshotDataDTO; import net.wanji.opt.dto.CrossLaneSnapshotDataDTO;
import net.wanji.opt.dto.LineCongestion; import net.wanji.opt.dto.LineCongestion;
import net.wanji.opt.dto.LineSchemeDTO; import net.wanji.opt.dto.LineSchemeDTO;
import net.wanji.opt.dto.export.CrossMapping;
import net.wanji.opt.dto.export.DirMapping;
import net.wanji.opt.dto.export.LaneMapping;
import net.wanji.opt.dto.export.TurnMapping;
import net.wanji.opt.dto.export.utils.DynamicExportLaneDataElement;
import net.wanji.opt.dto.trend.AbnormalCrossListDTO; import net.wanji.opt.dto.trend.AbnormalCrossListDTO;
import net.wanji.opt.dto.trend.GreenwaveListDTO; import net.wanji.opt.dto.trend.GreenwaveListDTO;
import net.wanji.opt.po.base.CrossSchemeOptLogPO; import net.wanji.opt.po.base.CrossSchemeOptLogPO;
import net.wanji.opt.po.strategy.ScenePO; import net.wanji.opt.po.strategy.ScenePO;
import net.wanji.opt.po.strategy.StrategyPO; import net.wanji.opt.po.strategy.StrategyPO;
import net.wanji.opt.po.trend.AnalysisRidTurnIndicators;
import net.wanji.opt.po.trend.EventAlarmPO; import net.wanji.opt.po.trend.EventAlarmPO;
import net.wanji.opt.po.trend.HoloEventInfoPO; import net.wanji.opt.po.trend.HoloEventInfoPO;
import net.wanji.opt.service.TrendService; import net.wanji.opt.service.TrendService;
...@@ -2951,8 +2955,21 @@ public class TrendServiceImpl implements TrendService { ...@@ -2951,8 +2955,21 @@ public class TrendServiceImpl implements TrendService {
List<CrossLaneDataHistVOExt> poExtList = crossLaneDataHistMapper.selectByCrossIdAndTimeIds(crossId, start, end, granularity, idsList); List<CrossLaneDataHistVOExt> poExtList = crossLaneDataHistMapper.selectByCrossIdAndTimeIds(crossId, start, end, granularity, idsList);
List<TableQueryVO.CycleDataElement> dataList = buildLaneCycleData(crossId, poExtList); List<TableQueryVO.CycleDataElement> dataList = buildLaneCycleData(crossId, poExtList);
String crossName = crossInfoCache.getCrossName(crossId); // 判断是否需要导出全部字段
ExcelExportUtils.exportExcel(response, startStr, endStr, dataList, crossName.concat("车道周期数据"), TableQueryVO.CycleDataElement.class); if (CollectionUtil.isEmpty(lanePeriodVO.getSelectedFields())) {
String crossName = crossInfoCache.getCrossName(crossId);
ExcelExportUtils.exportExcel(response, startStr, endStr, dataList, crossName.concat("车道周期数据"), TableQueryVO.CycleDataElement.class);
}else {
// 动态构建导出数据
List<String> selectedFields = lanePeriodVO.getSelectedFields();
List<DynamicExportLaneDataElement> exportDataList = new ArrayList<>();
for (TableQueryVO.CycleDataElement element : dataList) {
exportDataList.add(DynamicExportLaneDataElement.fromCycleDataElement(TableQueryVO.CycleDataElement.class,element, selectedFields, LaneMapping.CYCLE_DATA_FIELD_MAPPING));
}
String crossName = crossInfoCache.getCrossName(crossId);
ExcelExportUtils.exportExcel(response, startStr, endStr, exportDataList, crossName.concat("车道周期数据"));
}
} }
/** /**
...@@ -3091,8 +3108,23 @@ public class TrendServiceImpl implements TrendService { ...@@ -3091,8 +3108,23 @@ public class TrendServiceImpl implements TrendService {
// 查询周期数据 // 查询周期数据
List<CrossTurnDataHistVO> vo = crossTurnDataHistMapper.selectByCrossIdTurn(crossId, start, end, granularity, turnTypeList, inDirList); List<CrossTurnDataHistVO> vo = crossTurnDataHistMapper.selectByCrossIdTurn(crossId, start, end, granularity, turnTypeList, inDirList);
List<CrossingTurnQueryVO.CycleDataElement> result = buildCrossingTurnCycleData(crossId, vo); List<CrossingTurnQueryVO.CycleDataElement> result = buildCrossingTurnCycleData(crossId, vo);
String crossName = crossInfoCache.getCrossName(crossId);
ExcelExportUtils.exportExcel(response, startStr, endStr, result, crossName.concat("转向周期数据"), CrossingTurnQueryVO.CycleDataElement.class); // 判断是否需要导出全部字段
if (CollectionUtil.isEmpty(turnVO.getSelectedFields())) {
String crossName = crossInfoCache.getCrossName(crossId);
ExcelExportUtils.exportExcel(response, startStr, endStr, result, crossName.concat("转向周期数据"), CrossingTurnQueryVO.CycleDataElement.class);
}else {
// 动态构建导出数据
List<String> selectedFields = turnVO.getSelectedFields();
List<DynamicExportLaneDataElement> exportDataList = new ArrayList<>();
for (CrossingTurnQueryVO.CycleDataElement element: result) {
exportDataList.add(DynamicExportLaneDataElement.fromCycleDataElement(CrossingTurnQueryVO.CycleDataElement.class, element, selectedFields, TurnMapping.CYCLE_DATA_FIELD_MAPPING));
}
String crossName = crossInfoCache.getCrossName(crossId);
ExcelExportUtils.exportExcel(response, startStr, endStr, exportDataList, crossName.concat("转向周期数据"));
}
} catch (Exception e) { } catch (Exception e) {
log.error("导出转向数据异常:", e); log.error("导出转向数据异常:", e);
throw new OptServiceException(e); throw new OptServiceException(e);
...@@ -3132,8 +3164,21 @@ public class TrendServiceImpl implements TrendService { ...@@ -3132,8 +3164,21 @@ public class TrendServiceImpl implements TrendService {
List<CrossDirDataHistVO> vo = crossDirDataHistMapper.selectByCrossIdAndStartEndDir(crossId, start, end, dirTypeList, granularity); List<CrossDirDataHistVO> vo = crossDirDataHistMapper.selectByCrossIdAndStartEndDir(crossId, start, end, dirTypeList, granularity);
List<CrossingDirectionQueryVO.CycleDataElement> result = buildCrossingDirectionCycleData(crossId, vo); List<CrossingDirectionQueryVO.CycleDataElement> result = buildCrossingDirectionCycleData(crossId, vo);
String crossName = crossInfoCache.getCrossName(crossId); // 判断是否需要导出全部字段
ExcelExportUtils.exportExcel(response, startStr, endStr, result, crossName.concat("方向周期数据"), CrossingDirectionQueryVO.CycleDataElement.class); if (CollectionUtil.isEmpty(directionVO.getSelectedFields())) {
String crossName = crossInfoCache.getCrossName(crossId);
ExcelExportUtils.exportExcel(response, startStr, endStr, result, crossName.concat("方向周期数据"), CrossingDirectionQueryVO.CycleDataElement.class);
}else {
// 动态构建导出数据
List<String> selectedFields = directionVO.getSelectedFields();
List<DynamicExportLaneDataElement> exportDataList = new ArrayList<>();
for (CrossingDirectionQueryVO.CycleDataElement element: result) {
exportDataList.add(DynamicExportLaneDataElement.fromCycleDataElement(CrossingDirectionQueryVO.CycleDataElement.class, element, selectedFields, DirMapping.CYCLE_DATA_FIELD_MAPPING));
}
String crossName = crossInfoCache.getCrossName(crossId);
ExcelExportUtils.exportExcel(response, startStr, endStr, exportDataList, crossName.concat("方向周期数据"));
}
} catch (Exception e) { } catch (Exception e) {
log.error("导出方向数据异常:", e); log.error("导出方向数据异常:", e);
throw new OptServiceException(e); throw new OptServiceException(e);
...@@ -3165,8 +3210,22 @@ public class TrendServiceImpl implements TrendService { ...@@ -3165,8 +3210,22 @@ public class TrendServiceImpl implements TrendService {
// 查询周期数据 // 查询周期数据
List<CrossDataHistVO> vo = crossDataHistMapper.selectByCrossIdAndStartEndStat(crossId, start, end, granularity); List<CrossDataHistVO> vo = crossDataHistMapper.selectByCrossIdAndStartEndStat(crossId, start, end, granularity);
List<CrossingQueryVO.CycleDataElement> result = buildCrossingCycleData(crossId, vo); List<CrossingQueryVO.CycleDataElement> result = buildCrossingCycleData(crossId, vo);
String crossName = crossInfoCache.getCrossName(crossId);
ExcelExportUtils.exportExcel(response, startStr, endStr, result, crossName.concat("路口周期数据"), CrossingQueryVO.CycleDataElement.class); // 判断是否需要导出全部字段
if (CollectionUtil.isEmpty(crossingVO.getSelectedFields())) {
String crossName = crossInfoCache.getCrossName(crossId);
ExcelExportUtils.exportExcel(response, startStr, endStr, result, crossName.concat("路口周期数据"), CrossingQueryVO.CycleDataElement.class);
}else {
// 动态构建导出数据
List<String> selectedFields = crossingVO.getSelectedFields();
List<DynamicExportLaneDataElement> exportDataList = new ArrayList<>();
for (CrossingQueryVO.CycleDataElement element: result) {
exportDataList.add(DynamicExportLaneDataElement.fromCycleDataElement(CrossingQueryVO.CycleDataElement.class, element, selectedFields, CrossMapping.CYCLE_DATA_FIELD_MAPPING));
}
String crossName = crossInfoCache.getCrossName(crossId);
ExcelExportUtils.exportExcel(response, startStr, endStr, exportDataList, crossName.concat("路口周期数据"));
}
} catch (Exception e) { } catch (Exception e) {
log.error("导出路口数据异常:", e); log.error("导出路口数据异常:", e);
throw new OptServiceException(e); throw new OptServiceException(e);
......
...@@ -5,6 +5,8 @@ import io.swagger.annotations.ApiModelProperty; ...@@ -5,6 +5,8 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.util.List;
/** /**
* @author duanruiming * @author duanruiming
* @date 2024/05/17 9:00 * @date 2024/05/17 9:00
...@@ -25,4 +27,9 @@ public class LanePeriodTurnVO extends CommonCrossIdDateTimeVO { ...@@ -25,4 +27,9 @@ public class LanePeriodTurnVO extends CommonCrossIdDateTimeVO {
*/ */
@ApiModelProperty(value = "驶入方向") @ApiModelProperty(value = "驶入方向")
private String inDir; private String inDir;
/**
* 选中的要导出的字段
*/
private List<String> selectedFields;
} }
package net.wanji.opt.vo; package net.wanji.opt.vo;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.apache.commons.compress.utils.Lists;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import java.util.ArrayList;
import java.util.List;
/** /**
* @author duanruiming * @author duanruiming
...@@ -21,5 +25,14 @@ public class LanePeriodVO extends CommonCrossIdDateTimeVO { ...@@ -21,5 +25,14 @@ public class LanePeriodVO extends CommonCrossIdDateTimeVO {
@ApiModelProperty(value = "车道IDs") @ApiModelProperty(value = "车道IDs")
@NotBlank(message = "车道ids不能为空") @NotBlank(message = "车道ids不能为空")
private String ids; private String ids;
/**
* 选中的要导出的字段
*/
private List<String> selectedFields;
public static void main(String[] args) {
List<String> selectedFields = Lists.newArrayList();
selectedFields.add("laneId");
System.out.println(JSON.toJSONString(selectedFields));
}
} }
...@@ -5,6 +5,8 @@ import io.swagger.annotations.ApiModelProperty; ...@@ -5,6 +5,8 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.util.List;
/** /**
* 路口级 * 路口级
*/ */
...@@ -14,4 +16,9 @@ import lombok.NoArgsConstructor; ...@@ -14,4 +16,9 @@ import lombok.NoArgsConstructor;
public class PeriodCrossingVO extends CommonCrossIdDateTimeVO { public class PeriodCrossingVO extends CommonCrossIdDateTimeVO {
@ApiModelProperty(value = "分析粒度【5m:五分钟 10m:10分钟 30m:30分钟 1h:一小时】") @ApiModelProperty(value = "分析粒度【5m:五分钟 10m:10分钟 30m:30分钟 1h:一小时】")
private String granularity; private String granularity;
/**
* 选中的要导出的字段
*/
private List<String> selectedFields;
} }
...@@ -5,6 +5,8 @@ import io.swagger.annotations.ApiModelProperty; ...@@ -5,6 +5,8 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.util.List;
/** /**
* 方向级 * 方向级
*/ */
...@@ -19,4 +21,9 @@ public class PeriodDirectionVO extends CommonCrossIdDateTimeVO { ...@@ -19,4 +21,9 @@ public class PeriodDirectionVO extends CommonCrossIdDateTimeVO {
*/ */
@ApiModelProperty(value = "路口方向类型:1北;2东北;3东;4东南;5南;6西南;7西;8西北") @ApiModelProperty(value = "路口方向类型:1北;2东北;3东;4东南;5南;6西南;7西;8西北")
private String direction; private String direction;
/**
* 选中的要导出的字段
*/
private List<String> selectedFields;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment