台账模版导入功能修复

This commit is contained in:
hzj
2026-05-20 15:58:48 +08:00
parent 11750a4f3a
commit 7eef16599f
5 changed files with 175 additions and 60 deletions

View File

@@ -239,18 +239,47 @@ public class ExcelUtil {
* @param strings 下拉内容
*/
public static void selectList(Workbook workbook, int firstCol, int lastCol, String[] strings) {
Sheet sheet = workbook.getSheetAt(0);
// 生成下拉列表
// 只对(xx)单元格有效
CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(2, 65535, firstCol, lastCol);
// 生成下拉框内容
DataValidationHelper dvHelper = sheet.getDataValidationHelper();
XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint)
dvHelper.createExplicitListConstraint(strings);
XSSFDataValidation validation = (XSSFDataValidation) dvHelper.createValidation(
dvConstraint, cellRangeAddressList);
// 对sheet页生效
sheet.addValidationData(validation);
// Sheet sheet = workbook.getSheetAt(0);
// // 生成下拉列表
// // 只对(xx)单元格有效
// CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(2, 65535, firstCol, lastCol);
// // 生成下拉框内容
// DataValidationHelper dvHelper = sheet.getDataValidationHelper();
// XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint)
// dvHelper.createExplicitListConstraint(strings);
// XSSFDataValidation validation = (XSSFDataValidation) dvHelper.createValidation(
// dvConstraint, cellRangeAddressList);
// // 对sheet页生效
// sheet.addValidationData(validation);
Sheet targetSheet = workbook.getSheetAt(0);
// ===================== 关键每个下拉用唯一名称的隐藏Sheet =====================
String uniqueHiddenName = "dropdown_" + firstCol + "_" + lastCol + "_" + System.currentTimeMillis();
Sheet hiddenSheet = workbook.createSheet(uniqueHiddenName);
// 隐藏数据源Sheet
workbook.setSheetHidden(workbook.getSheetIndex(hiddenSheet), true);
// 写入选项到隐藏Sheet
for (int i = 0; i < strings.length; i++) {
Row row = hiddenSheet.createRow(i);
Cell cell = row.createCell(0);
cell.setCellValue(strings[i]);
}
// 构造引用公式(无长度限制)
String formula = uniqueHiddenName + "!$A$1:$A$" + strings.length;
// 下拉作用范围第3行 ~ 65536行
CellRangeAddressList range = new CellRangeAddressList(2, 65535, firstCol, lastCol);
DataValidationHelper helper = targetSheet.getDataValidationHelper();
DataValidationConstraint constraint = helper.createFormulaListConstraint(formula);
DataValidation validation = helper.createValidation(constraint, range);
// 必加:防止下拉冲突、不显示
validation.setShowErrorBox(true);
validation.setShowPromptBox(true);
targetSheet.addValidationData(validation);
}
/**

View File

@@ -4,13 +4,15 @@ import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.CharsetUtil;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.net.URLEncoder;
import java.util.Objects;
/**
* @author hongawen
@@ -76,6 +78,59 @@ public class PoiUtil {
fileName = URLEncoder.encode(fileName, CharsetUtil.UTF_8);
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
response.setContentType("application/octet-stream;charset=" + CharsetUtil.UTF_8);
//将带*号的列变成红色
Sheet sheetAt = workbook.getSheetAt(0);
//获取列数
int physicalNumberOfCells = sheetAt.getRow(0).getPhysicalNumberOfCells();
//没有表格标题,只有表格头
for (int i = 0; i < 2; i++) {
//获取行
Row row = sheetAt.getRow(i);
if (Objects.isNull(row)) {
continue;
}
for (int j = 0; j < physicalNumberOfCells; j++) {
//获取单元格对象
Cell cell = row.getCell(j);
//获取单元格样式对象
CellStyle cellStyle = workbook.createCellStyle();
//获取单元格内容对象
Font font = workbook.createFont();
font.setFontHeightInPoints((short) 12);
//一定要装入 样式中才会生效
cellStyle.setFont(font);
//设置居中对齐
cellStyle.setAlignment(HorizontalAlignment.CENTER);
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
//设置单元格字体颜色
cell.setCellStyle(cellStyle);
//获取当前值
String stringCellValue = cell.getStringCellValue();
if (stringCellValue.contains("*")) {
// 创建一个富文本
XSSFRichTextString xssfRichTextString = new XSSFRichTextString(stringCellValue);
int startIndex = stringCellValue.indexOf("*");
int entIndex = stringCellValue.lastIndexOf("*");
if (entIndex != 0) {
Font font3 = workbook.createFont();
font3.setFontHeightInPoints((short) 12);
font3.setColor(Font.COLOR_NORMAL);
xssfRichTextString.applyFont(0, entIndex, font3);
}
//设置带*样式
Font font1 = workbook.createFont();
font1.setFontHeightInPoints((short) 12);
font1.setColor(Font.COLOR_RED);
xssfRichTextString.applyFont(startIndex, entIndex + 1, font1);
//其他样式
Font font2 = workbook.createFont();
font2.setFontHeightInPoints((short) 12);
font2.setColor(Font.COLOR_NORMAL);
xssfRichTextString.applyFont(entIndex + 1, stringCellValue.length(), font2);
cell.setCellValue(xssfRichTextString);
}
}
}
workbook.write(outputStream);
} catch (Exception e) {
e.printStackTrace();

View File

@@ -22,65 +22,65 @@ import java.math.BigDecimal;
public class TerminalBaseExcel implements Serializable {
@Excel(name = "项目", width = 15)
@Excel(name = "*项目", width = 15)
@NotBlank(message = DeviceValidMessage.PROJECT_NAME_NOT)
@Pattern(regexp = PatternRegex.DEPT_NAME_REGEX, message = DeviceValidMessage.PROJECT_NAME_RULE)
private String projectName;
@Excel(name = "工程", width = 15)
@Excel(name = "*省份", width = 15)
@NotBlank(message = DeviceValidMessage.PROVINCE_NAME_NOT)
private String provinceName;
@Excel(name = "单位", width = 15)
@Excel(name = "*供电公司", width = 15)
@NotBlank(message = "供电公司名称")
@Pattern(regexp = PatternRegex.DEV_NAME_REGEX, message = "供电公司名称违规")
private String gdName;
@Excel(name = "部门", width = 15)
@Excel(name = "*变电站", width = 15)
@NotBlank(message = "变电站名称不可为空")
@Pattern(regexp = PatternRegex.DEV_NAME_REGEX, message = "变电站名称违规")
private String substationName;
@Excel(name = "部门电压等级", width = 15)
@NotBlank(message = "电压等级不可为空")
@Excel(name = "*变电站电压等级", width = 15)
@NotBlank(message = "变电站电压等级不可为空")
private String subStationScale;
@Excel(name = "经度", width = 15)
@Excel(name = "*经度", width = 15)
private BigDecimal lng;
@Excel(name = "纬度", width = 15)
@Excel(name = "*纬度", width = 15)
private BigDecimal lat;
@Excel(name = "终端", width = 15)
@Pattern(regexp = PatternRegex.DEV_NAME_REGEX, message = "设备名称违规")
@Excel(name = "*装置名称", width = 15)
@Pattern(regexp = PatternRegex.DEV_NAME_REGEX, message = "装置名称违规")
private String deviceName;
@Excel(name = "终端模型", replace = {"虚拟设备_0", "实际设备_1", "离线设备_2"}, width = 15)
@Excel(name = "*终端模型", replace = {"虚拟设备_0", "实际设备_1", "离线设备_2"}, width = 15)
@NotNull(message = "设备模型不能为空")
private Integer devModel;
@Excel(name = "数据类型", replace = {"暂态系统_0", "稳态系统_1", "双系统_2"}, width = 15)
@Excel(name = "*数据类型", replace = {"暂态系统_0", "稳态系统_1", "双系统_2"}, width = 15)
@NotNull(message = "数据类型不能为空")
private Integer devDataType;
@Excel(name = "运行状态", replace = {"投运_0", "热备用_1", "停运_2"}, width = 15)
@Excel(name = "*运行状态", replace = {"投运_0", "热备用_1", "停运_2"}, width = 15)
@NotNull(message = "运行状态不能为空")
private Integer runFlag;
@Excel(name = "终端厂家", width = 15)
@Excel(name = "*终端厂家", width = 15)
@NotBlank(message = "终端厂家不能为空")
private String manufacturer;
@Excel(name = "设备型号", width = 15)
@Excel(name = "*设备型号", width = 15)
@NotBlank(message = "设备型号不能为空")
private String devType;
@Excel(name = "网络参数", width = 15)
@Excel(name = "*网络参数", width = 15)
@NotBlank(message = "设备网络参数不能为空")
private String ip;
@Excel(name = "端口", width = 15)
@Excel(name = "*端口", width = 15)
@Range(min = 1, max = 100000, message = "端口号违规")
@NotNull(message = "设备端口号不能为空")
private Integer port;
@@ -91,15 +91,15 @@ public class TerminalBaseExcel implements Serializable {
@Excel(name = "终端秘钥", width = 15)
private String devKey;
@Excel(name = "召唤标志",replace = {"周期触发_0", "变为触发_1"}, width = 15)
@Excel(name = "*召唤标志",replace = {"周期触发_0", "变为触发_1"}, width = 15)
@NotNull(message = "召唤标志不为空")
private Integer callFlag;
@Excel(name = "前置名称", width = 15)
@Excel(name = "*前置名称", width = 15)
@NotBlank(message = "前置名称不能为空")
private String nodeName;
@Excel(name = "前置类型", width = 15)
@Excel(name = "*前置类型", width = 15)
@NotBlank(message = "前置类型不能为空")
private String frontType;
@@ -109,71 +109,71 @@ public class TerminalBaseExcel implements Serializable {
@Excel(name = "SIM卡号", width = 15)
private String sim;
@Excel(name = "母线", width = 15)
@Excel(name = "*母线", width = 15)
@NotBlank(message = "母线名称不能为空")
private String subvName;
@Excel(name = "母线号", width = 15)
@Excel(name = "*母线号", width = 15)
@NotNull(message = "母线号不为空")
private Integer subvNum;
@Excel(name = "母线电压等级", width = 15)
@Excel(name = "*母线电压等级", width = 15)
@NotBlank(message = "母线电压等级不能为空")
private String subvScale;
@Excel(name = "母线模型", replace = {"虚拟母线_0", "实际母线_1"}, width = 15)
@Excel(name = "*母线模型", replace = {"虚拟母线_0", "实际母线_1"}, width = 15)
@NotNull(message = "母线模型不为空")
private Integer subvModel;
@Excel(name = "监测点名称", width = 15)
@Excel(name = "*监测点名称", width = 15)
@NotBlank(message = "监测点名称不能为空")
private String lineName;
@Excel(name = "监测点线路号", width = 15)
@Excel(name = "*监测点线路号", width = 15)
@NotNull(message = "监测点线路号不为空")
private Integer lineNum;
@Excel(name = "监测点等级", width = 15)
@Excel(name = "*监测点等级", width = 15)
private String lineGrade;
@Excel(name = "pt", width = 20)
@Excel(name = "*pt(格式pt1/pt2)", width = 20)
@NotBlank(message = "pt不能为空")
private String pt;
@Excel(name = "ct", width = 20)
@Excel(name = "*ct(格式ct1/ct2)", width = 20)
@NotBlank(message = "ct不能为空")
private String ct;
@Excel(name = "设备容量", width = 15)
@Excel(name = "*设备容量", width = 15)
@NotNull(message = "设备容量不为空")
private Float devCapacity;
@Excel(name = "短路容量", width = 15)
@Excel(name = "*短路容量", width = 15)
@NotNull(message = "短路容量不为空")
private Float shortCapacity;
@Excel(name = "基准容量", width = 15)
@Excel(name = "*基准容量", width = 15)
@NotNull(message = "基准容量不为空")
private Float standardCapacity;
@Excel(name = "协议容量", width = 15)
@Excel(name = "*协议容量", width = 15)
@NotNull(message = "协议容量不为空")
private Float dealCapacity;
@Excel(name = "接线方式", replace = {"星型接法_0", "三角型接法_1", "开口三角型接法_2"}, width = 15)
@Excel(name = "*接线方式", replace = {"星型接法_0", "三角型接法_1", "开口三角型接法_2"}, width = 15)
@NotNull(message = "接线方式不为空")
private Integer ptType;
@Excel(name = "测量间隔", width = 15)
@Excel(name = "*测量间隔", width = 15)
@NotNull(message = "测量间隔不为空")
private Integer timeInterval;
@Excel(name = "干扰源类型", width = 15)
@Excel(name = "*干扰源类型", width = 15)
@NotBlank(message = "干扰源类型不为空")
private String loadType;
@Excel(name = "行业类型", width = 15)
@Excel(name = "*行业类型", width = 15)
@NotBlank(message = "行业类型不为空")
private String businessType;
@@ -183,11 +183,11 @@ public class TerminalBaseExcel implements Serializable {
@Excel(name = "监测点对象名称", width = 15)
private String objName;
@Excel(name = "电网侧标志", replace = {"电网侧_0", "非电网侧_1"}, width = 15)
@Excel(name = "*电网侧标志", replace = {"电网侧_0", "非电网侧_1"}, width = 15)
@NotNull(message = "电网侧标志不为空")
private Integer powerFlag;
@Excel(name = "人为干预统计", replace = {"不参与统计_0", "参与统计_1"}, width = 15)
@Excel(name = "*人为干预统计", replace = {"不参与统计_0", "参与统计_1"}, width = 15)
@NotNull(message = "统计标志不为空")
private Integer statFlag;

View File

@@ -37,6 +37,7 @@ import com.njcn.device.device.mapper.DeviceMapper;
import com.njcn.device.device.service.DeviceBakService;
import com.njcn.device.device.service.DeviceProcessService;
import com.njcn.device.device.service.NodeDeviceService;
import com.njcn.device.device.service.PqDevTypeService;
import com.njcn.device.line.mapper.DeptLineMapper;
import com.njcn.device.line.mapper.LineDetailMapper;
import com.njcn.device.line.mapper.LineMapper;
@@ -74,6 +75,8 @@ import com.njcn.oss.utils.FileStorageUtil;
import com.njcn.poi.excel.ExcelUtil;
import com.njcn.poi.util.PoiUtil;
import com.njcn.redis.utils.RedisUtil;
import com.njcn.supervision.pojo.param.user.UserReportParam;
import com.njcn.supervision.pojo.po.user.UserReportPO;
import com.njcn.supervision.pojo.vo.user.UserLedgerVO;
import com.njcn.system.api.AreaFeignClient;
import com.njcn.system.api.DicDataFeignClient;
@@ -140,6 +143,7 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
private final DeviceProcessService deviceProcessService;
private final ProduceFeignClient produceFeignClient;
private final UserLedgerService userLedgerService;
private final PqDevTypeService pqDevTypeService;
@Value("${oracle.isSync}")
private Boolean isSync;
@@ -1731,18 +1735,24 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
List<DictData> businessList = dicDataFeignClient.getDicDataByTypeName(DicDataTypeEnum.BUSINESS_TYPE.getName()).getData();
List<DictData> loadTypeList = dicDataFeignClient.getDicDataByTypeName(DicDataTypeEnum.INTERFERENCE_SOURCE_TYPE.getName()).getData();
List<DictData> manufacturerList = dicDataFeignClient.getDicDataByTypeName(DicDataTypeEnum.DEV_MANUFACTURER.getName()).getData();
List<DictData> devTypeList = dicDataFeignClient.getDicDataByTypeName(DicDataTypeEnum.DEV_TYPE.getName()).getData();
// List<DictData> devTypeList = dicDataFeignClient.getDicDataByTypeName(DicDataTypeEnum.DEV_TYPE.getName()).getData();
List<PqDevType> devTypeList = pqDevTypeService.list(new LambdaQueryWrapper<PqDevType>()
.eq(PqDevType::getState, DataStateEnum.ENABLE.getCode())
.orderByDesc(PqDevType::getCreateTime));
List<DictData> frontList = dicDataFeignClient.getDicDataByTypeName(DicDataTypeEnum.FRONT_TYPE.getName()).getData();
List<DictData> scaleList = dicDataFeignClient.getDicDataByTypeName(DicDataTypeEnum.DEV_VOLTAGE_STAND.getName()).getData();
List<UserLedgerVO> userLedgerVOS = userLedgerService.selectUserList(new UserReportParam());
List<Node> nodeList = nodeService.nodeAllList();
ExcelUtil.selectList(workbook, 4, 4, scaleList.stream().map(DictData::getName).collect(Collectors.toList()).toArray(new String[]{}));
ExcelUtil.selectList(workbook, 40, 40, userLedgerVOS.stream().map(UserLedgerVO::getProjectName).collect(Collectors.toList()).toArray(new String[]{}));
//这里是自己加的 带下拉框的代码
ExcelUtil.selectList(workbook, 8, 8, new String[]{"虚拟设备", "实际设备", "离线设备"});
ExcelUtil.selectList(workbook, 9, 9, new String[]{"暂态系统", "稳态系统", "双系统"});
ExcelUtil.selectList(workbook, 10, 10, new String[]{"投运", "热备用", "停运"});
ExcelUtil.selectList(workbook, 11, 11, manufacturerList.stream().map(DictData::getName).collect(Collectors.toList()).toArray(new String[]{}));
ExcelUtil.selectList(workbook, 12, 12, devTypeList.stream().map(DictData::getName).collect(Collectors.toList()).toArray(new String[]{}));
ExcelUtil.selectList(workbook, 12, 12, devTypeList.stream().map(PqDevType::getName).collect(Collectors.toList()).toArray(new String[]{}));
ExcelUtil.selectList(workbook, 17, 17, new String[]{"周期触发", "变为触发"});
ExcelUtil.selectList(workbook, 18, 18, nodeList.stream().map(Node::getName).collect(Collectors.toList()).toArray(new String[]{}));
ExcelUtil.selectList(workbook, 19, 19, frontList.stream().map(DictData::getName).collect(Collectors.toList()).toArray(new String[]{}));
@@ -1760,6 +1770,8 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
ExcelUtil.selectList(workbook, 41, 41, new String[]{"电网侧", "非电网侧"});
ExcelUtil.selectList(workbook, 42, 42, new String[]{"不参与统计", "参与统计"});
PoiUtil.exportFileByWorkbook(workbook, "台账导入模板.xlsx", response);
}
@Override
@@ -2729,6 +2741,7 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
* @author cdf
* @date 2022/5/18
*/
@Transactional(rollbackFor = Exception.class)
private void saveTerminalBase(List<TerminalBaseExcel> terminalBaseExcels) {
List<TerminalBaseExcel.TerminalBaseExcelMsg> terminalBaseExcelMsgs = new ArrayList<>();
//任意集合数据为空,不处理
@@ -2844,9 +2857,15 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
}
//处理终端类型
DictData devTypeDicData = dicDataFeignClient.getDicDataByName(terminalBaseExcel.getDevType()).getData();
PqDevType one = new PqDevType();
if (Objects.isNull(devTypeDicData)) {
terminalBaseExcelMsgs.add(assembleBaseMsg(terminalBaseExcel, "字典装置型号不存在"));
continue;
//上边逻辑不删兼容旧版本新版本查询pq_dev_type
one = pqDevTypeService.lambdaQuery().eq(PqDevType::getName, terminalBaseExcel.getDevType()).eq(PqDevType::getState, DataStateEnum.ENABLE.getCode()).one();
if(Objects.isNull(one)){
terminalBaseExcelMsgs.add(assembleBaseMsg(terminalBaseExcel, "字典装置型号不存在"));
continue;
}
}
this.baseMapper.insert(temp);
Device device = new Device();
@@ -2856,7 +2875,7 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
device.setIp(terminalBaseExcel.getIp());
device.setNodeId(node.getId());
device.setFrontType(frontTypeDicData.getId());
device.setDevType(devTypeDicData.getId());
device.setDevType(Objects.isNull(devTypeDicData)?one.getId():devTypeDicData.getId());
device.setComFlag(0);
device.setCheckFlag(1);
device.setLoginTime(LocalDate.now());
@@ -2866,6 +2885,8 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
device.setElectroplate(0);
device.setOnTime(1);
deviceMapper.insert(device);
//分配前置进程
nodeDeviceService.oneKeyDistribution(node.getId());
}
//添加终端索引
pids.add(temp.getId());
@@ -2892,6 +2913,7 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
}
//处理电压等级字典表
DictData subvScale = dicDataFeignClient.getDicDataByNameAndType(terminalBaseExcel.getSubvScale(), DicDataTypeEnum.DEV_VOLTAGE_STAND.getName()).getData();
if (Objects.isNull(subvScale)) {
terminalBaseExcelMsgs.add(assembleBaseMsg(terminalBaseExcel, "字典电压等级:" + terminalBaseExcel.getSubStationScale() + "不存在"));
continue;
@@ -2969,8 +2991,17 @@ public class TerminalBaseServiceImpl extends ServiceImpl<LineMapper, Line> imple
lineDetail.setPt2(Float.valueOf(pt[1]));
lineDetail.setCt1(Float.valueOf(ct[0]));
lineDetail.setCt2(Float.valueOf(ct[1]));
if(StringUtils.isNoneBlank(terminalBaseExcel.getObjName())){
UserReportPO one = userLedgerService.lambdaQuery().eq(UserReportPO::getProjectName, terminalBaseExcel.getObjName())
.eq(UserReportPO::getState, DataStateEnum.ENABLE.getCode()).one();
if(Objects.nonNull(one)){
lineDetail.setObjId(one.getId());
DictData dictData = dicDataFeignClient.getDicDataByNameAndTypeName(terminalBaseExcel.getSubvScale(), DicDataTypeEnum.DEV_VOLTAGE_STAND.getName()).getData();
}
}
DictData dictData = dicDataFeignClient.getDicDataByNameAndType(terminalBaseExcel.getSubvScale(), DicDataTypeEnum.DEV_VOLTAGE_STAND.getName()).getData();
lineDetailMapper.insert(lineDetail);
Overlimit overlimit = COverlimitUtil.globalAssemble(Float.parseFloat(dictData.getValue()), terminalBaseExcel.getDealCapacity(), terminalBaseExcel.getDevCapacity(), terminalBaseExcel.getShortCapacity(), null, null);

View File

@@ -187,14 +187,14 @@ public class TerminalMaintainServiceImpl implements TerminalMaintainService {
if (device.getRunFlag() == 0) {
newFlag = "投运";
} else if (device.getRunFlag() == 1) {
newFlag = "热备用";
newFlag = "检修";
} else if (device.getRunFlag() == 2) {
newFlag = "停运";
}
if (device1.getRunFlag() == 0) {
oldFlag = "投运";
} else if (device1.getRunFlag() == 1) {
oldFlag = "热备用";
oldFlag = "检修";
} else if (device1.getRunFlag() == 2) {
oldFlag = "停运";
}