瀏覽代碼

fix定时报表导出

LLL 11 月之前
父節點
當前提交
082c15734e

+ 123 - 0
jeecg-module-interlock/src/main/java/org/jeecg/modules/history/quartz/ReportJob.java

@@ -0,0 +1,123 @@
+package org.jeecg.modules.history.quartz;
+
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.util.DateUtils;
+import org.jeecg.modules.history.dto.InterlockHistoryQueryDTO;
+import org.jeecg.modules.history.service.IInterlockDetailHistoryService;
+import org.jeecg.modules.history.vo.InterlockSummaryHistoryVO;
+import org.jeecg.modules.report.entity.InterlockDataReport;
+import org.jeecg.modules.report.service.IInterlockDataReportService;
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+/**
+ * 功能描述
+ *
+ * @author: nn
+ * @date: 2024年06月13日 10:37
+ */
+@Slf4j
+public class ReportJob implements Job {
+
+    @Autowired
+    private IInterlockDetailHistoryService interlockDetailHistoryService;
+    @Autowired
+    private IInterlockDataReportService reportService;
+    @Value("${jeecg.path.upload}")
+    private String upLoadPath;
+
+    /**
+     * 若参数变量名
+     */
+    private String parameter;
+
+    public void setParameter(String parameter) {
+        this.parameter = parameter;
+    }
+
+    @Override
+    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+        log.info(" Job Execution key:"+jobExecutionContext.getJobDetail().getKey());
+
+        String filePrex = this.parameter;
+
+        InterlockHistoryQueryDTO dto = new InterlockHistoryQueryDTO();
+        Calendar start = Calendar.getInstance();
+        start.set(Calendar.HOUR_OF_DAY, 0);
+        start.set(Calendar.MINUTE, 0);
+        start.set(Calendar.SECOND, 0);
+
+        Calendar end = Calendar.getInstance();
+        end.set(Calendar.HOUR_OF_DAY, 23);
+        end.set(Calendar.MINUTE, 59);
+        end.set(Calendar.SECOND, 59);
+
+        if(this.parameter.equals("day")) {
+            // 昨天凌晨00:00:00
+            start.add(Calendar.DAY_OF_MONTH, -1);
+            // 昨天晚上23:59:59
+            end.add(Calendar.DAY_OF_MONTH, -1);
+
+        }else if(this.parameter.equals("month")){
+            // 上个月的第一天凌晨00:00:00
+            start.add(Calendar.MONTH, -1);
+            start.set(Calendar.DAY_OF_MONTH, 1);
+            // 上个月的最后一天晚上23:59:59
+            end.set(Calendar.DAY_OF_MONTH, 1);
+            end.add(Calendar.DAY_OF_MONTH, -1);
+
+        }else if(this.parameter.equals("year")){
+            // 去年的第一天凌晨00:00:00
+            start.add(Calendar.YEAR, -1);
+            start.set(Calendar.MONTH, 0);
+            start.set(Calendar.DAY_OF_MONTH, 1);
+            // 去年的最后一天晚上23:59:59
+            end.set(Calendar.MONTH, 0);
+            end.set(Calendar.DAY_OF_MONTH, 1);
+            end.add(Calendar.DAY_OF_MONTH, -1);
+        }
+
+        Date beginTime = start.getTime();
+        Date endTime = end.getTime();
+
+        log.info(String.format(" **********导出" + filePrex + "历史数据**********  时间:" + beginTime + "——" + endTime));
+
+        dto.setBeginTime(beginTime);
+        dto.setEndTime(endTime);
+
+        // 文件路径,如"D:/ttt/opt/upFiles/"
+        String fileUrlPrex = upLoadPath + File.separator + filePrex + File.separator;
+        File saveFile = new File(fileUrlPrex);
+        if (!saveFile.exists()) {
+            saveFile.mkdirs();
+        }
+
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
+        String timestamp = dateFormat.format(new Date());
+        String fileName = String.format("联锁历史数据_" + filePrex + "报表_%s.xlsx", timestamp);
+
+        String filePath = fileUrlPrex  + fileName;
+
+        try {
+            if(1 == interlockDetailHistoryService.exportXlsToFile(dto, InterlockSummaryHistoryVO.class, "联锁历史数据", filePath)) return;
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        //新增报表记录
+        InterlockDataReport report = new InterlockDataReport();
+        report.setReportName(fileName);
+        report.setReportType("0"); // 0日报表1月报表2年报表
+        report.setReportUrl(filePath);
+        reportService.save(report);
+    }
+}

+ 6 - 0
jeecg-module-interlock/src/main/java/org/jeecg/modules/history/service/IInterlockDetailHistoryService.java

@@ -10,6 +10,7 @@ import org.jeecg.modules.history.vo.InterlockDetailHistoryQueryVO;
 import org.jeecg.modules.history.vo.InterlockSummaryHistoryVO;
 import org.springframework.web.servlet.ModelAndView;
 
+import java.io.IOException;
 import java.util.List;
 
 /**
@@ -41,4 +42,9 @@ public interface IInterlockDetailHistoryService extends IService<InterlockDetail
      */
     ModelAndView exportXls1(InterlockHistoryQueryDTO dto, Class<InterlockSummaryHistoryVO> clazz, String title);
 
+    /**
+     * 导定时任务导出excel
+     */
+    public Integer exportXlsToFile(InterlockHistoryQueryDTO dto, Class<InterlockSummaryHistoryVO> clazz, String title, String filePath) throws IOException;
+
 }

+ 283 - 58
jeecg-module-interlock/src/main/java/org/jeecg/modules/history/service/impl/InterlockDetailHistoryServiceImpl.java

@@ -1,53 +1,39 @@
 package org.jeecg.modules.history.service.impl;
 
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import org.apache.poi.ss.usermodel.Cell;
-import org.apache.poi.ss.usermodel.Row;
-import org.apache.poi.ss.usermodel.Sheet;
-import org.apache.poi.ss.usermodel.Workbook;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.apache.shiro.SecurityUtils;
-import org.jeecg.common.system.query.QueryGenerator;
 import org.jeecg.common.system.vo.LoginUser;
-import org.jeecg.common.util.oConvertUtils;
-import org.jeecg.modules.base.entity.InterlockBase;
 import org.jeecg.modules.base.mapper.InterlockBaseMapper;
 import org.jeecg.modules.detail.dto.InterlockDetailQueryDTO;
 import org.jeecg.modules.history.convert.InterlockSummaryHistoryConvert;
 import org.jeecg.modules.history.dto.InterlockHistoryQueryDTO;
 import org.jeecg.modules.history.entity.InterlockDetailHistory;
-import org.jeecg.modules.history.entity.InterlockSummaryHistory;
 import org.jeecg.modules.history.mapper.InterlockDetailHistoryMapper;
 import org.jeecg.modules.history.mapper.InterlockSummaryHistoryMapper;
 import org.jeecg.modules.history.service.IInterlockDetailHistoryService;
 import org.jeecg.modules.history.vo.InterlockDetailHistoryQueryVO;
 import org.jeecg.modules.history.vo.InterlockHistoryDistinctZZXTVO;
 import org.jeecg.modules.history.vo.InterlockSummaryHistoryVO;
-import org.jeecg.modules.summary.entity.InterlockSummary;
-import org.jeecg.modules.summary.mapper.InterlockSummaryMapper;
-import org.jeecg.modules.summary.vo.InterlockSummaryVO;
 import org.jeecgframework.poi.excel.def.NormalExcelConstants;
 import org.jeecgframework.poi.excel.entity.ExportParams;
 import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
-
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.springframework.web.servlet.ModelAndView;
 
-import javax.servlet.http.HttpServletRequest;
-import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.text.DateFormat;
-import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 /**
@@ -98,6 +84,7 @@ public class InterlockDetailHistoryServiceImpl extends ServiceImpl<InterlockDeta
      */
     public ModelAndView exportXls1(InterlockHistoryQueryDTO dto, Class<InterlockSummaryHistoryVO> clazz, String title) {
         LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         String formattedBeginTime = "";
         String formattedEndTime = "";
@@ -108,47 +95,50 @@ public class InterlockDetailHistoryServiceImpl extends ServiceImpl<InterlockDeta
         List<Map<String, Object>> list = new ArrayList<>();
         List<InterlockHistoryDistinctZZXTVO> zzxtvoList = summaryHistoryMapper.getDistinctZZXTSummaryList(dto);
 
-        for (InterlockHistoryDistinctZZXTVO zzxtvo : zzxtvoList){
-            dto.setInterlockSystemId(zzxtvo.getInterlockSystemId());//系统id
-            List<InterlockSummaryHistoryVO> exportList = interlockDetailHistoryMapper.getForExport(dto);
-
-            String sheetName = zzxtvo.getInterlockApparatusName()+ "-"+zzxtvo.getInterlockSystemName();
-
-            Map<String, Object> map = new HashMap<>();
-            map.put(NormalExcelConstants.CLASS, InterlockSummaryHistoryVO.class);
-
-            // 计算投用率
-            InterlockHistoryQueryDTO dto1 = InterlockSummaryHistoryConvert.INSTANCE.toInterlockStatus(dto,"1"); // 1投用
-            int ty = summaryHistoryMapper.cocuntTYOrHL(dto1);
-            dto1.setInterlockStatus("0"); // 0未投用
-            int wty = summaryHistoryMapper.cocuntTYOrHL(dto1);
-            int total = ty + wty; // 总数量
-            double tyl = (double) ty / total * 100;
-
-            // 总回路数
-            InterlockHistoryQueryDTO dto2 = InterlockSummaryHistoryConvert.INSTANCE.toLoopHealthLevel(dto,"A");
-            int loopHealthLevelA = summaryHistoryMapper.cocuntTYOrHL(dto2);
-            dto2.setLoopHealthLevel("B");
-            int loopHealthLevelB = summaryHistoryMapper.cocuntTYOrHL(dto2);
-            dto2.setLoopHealthLevel("C");
-            int loopHealthLevelC = summaryHistoryMapper.cocuntTYOrHL(dto2);
-            int loopHealthLevel = loopHealthLevelA*3 + loopHealthLevelB*2 + loopHealthLevelC*1;
-
-            String secondTitle = "  投用率:" + tyl + "%"  + "  总回路数:" + loopHealthLevel + "  导出人:" + sysUser.getRealname();
-            if(dto.getBeginTime() !=null && dto.getEndTime() == null){
-                secondTitle = "起始时间:" + formattedBeginTime + secondTitle;
-            }else if(dto.getBeginTime() ==null && dto.getEndTime() != null){
-                secondTitle = "结束时间:" + formattedEndTime + secondTitle;
-            }else if(dto.getBeginTime() !=null && dto.getEndTime() != null){
-                secondTitle = "起始时间:" + formattedBeginTime + "  结束时间:" + formattedEndTime + secondTitle;
+        if(zzxtvoList!=null){
+            for (InterlockHistoryDistinctZZXTVO zzxtvo : zzxtvoList){
+                dto.setInterlockSystemId(zzxtvo.getInterlockSystemId());//系统id
+                List<InterlockSummaryHistoryVO> exportList = interlockDetailHistoryMapper.getForExport(dto);
+
+                String sheetName = zzxtvo.getInterlockApparatusName()+ "-"+zzxtvo.getInterlockSystemName();
+
+                Map<String, Object> map = new HashMap<>();
+                map.put(NormalExcelConstants.CLASS, InterlockSummaryHistoryVO.class);
+
+                // 计算投用率
+                InterlockHistoryQueryDTO dto1 = InterlockSummaryHistoryConvert.INSTANCE.toInterlockStatus(dto,"1"); // 1投用
+                int ty = summaryHistoryMapper.cocuntTYOrHL(dto1);
+                dto1.setInterlockStatus("0"); // 0未投用
+                int wty = summaryHistoryMapper.cocuntTYOrHL(dto1);
+                int total = ty + wty; // 总数量
+                double tyl = (double) ty / total * 100;
+
+                // 总回路数
+                InterlockHistoryQueryDTO dto2 = InterlockSummaryHistoryConvert.INSTANCE.toLoopHealthLevel(dto,"A");
+                int loopHealthLevelA = summaryHistoryMapper.cocuntTYOrHL(dto2);
+                dto2.setLoopHealthLevel("B");
+                int loopHealthLevelB = summaryHistoryMapper.cocuntTYOrHL(dto2);
+                dto2.setLoopHealthLevel("C");
+                int loopHealthLevelC = summaryHistoryMapper.cocuntTYOrHL(dto2);
+                int loopHealthLevel = loopHealthLevelA*3 + loopHealthLevelB*2 + loopHealthLevelC*1;
+
+                String secondTitle = "  投用率:" + tyl + "%"  + "  总回路数:" + loopHealthLevel + "  导出人:" + sysUser.getRealname();
+                if(dto.getBeginTime() !=null && dto.getEndTime() == null){
+                    secondTitle = "起始时间:" + formattedBeginTime + secondTitle;
+                }else if(dto.getBeginTime() ==null && dto.getEndTime() != null){
+                    secondTitle = "结束时间:" + formattedEndTime + secondTitle;
+                }else if(dto.getBeginTime() !=null && dto.getEndTime() != null){
+                    secondTitle = "起始时间:" + formattedBeginTime + "  结束时间:" + formattedEndTime + secondTitle;
+                }
+                ExportParams  exportParams=new ExportParams(title + "报表", secondTitle, sheetName);
+                exportParams.setImageBasePath(upLoadPath);
+                map.put(NormalExcelConstants.PARAMS, exportParams);
+                map.put(NormalExcelConstants.DATA_LIST, exportList);
+                list.add(map);
             }
-            ExportParams  exportParams=new ExportParams(title + "报表", secondTitle, sheetName);
-            exportParams.setImageBasePath(upLoadPath);
-            map.put(NormalExcelConstants.PARAMS, exportParams);
-            map.put(NormalExcelConstants.DATA_LIST, exportList);
-            list.add(map);
         }
 
+
         ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
         mv.addObject(NormalExcelConstants.FILE_NAME, title);//此处设置的filename无效 ,前端会重更新设置一下
         mv.addObject(NormalExcelConstants.MAP_LIST, list);
@@ -156,6 +146,241 @@ public class InterlockDetailHistoryServiceImpl extends ServiceImpl<InterlockDeta
     }
 
 
+    /**
+     * 导定时任务导出excel
+     */
+    public Integer exportXlsToFile(InterlockHistoryQueryDTO dto, Class<InterlockSummaryHistoryVO> clazz, String title, String filePath) throws IOException {
+
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        String formattedBeginTime = dto.getBeginTime() != null ? sdf.format(dto.getBeginTime()) : "";
+        String formattedEndTime = dto.getEndTime() != null ? sdf.format(dto.getEndTime()) : "";
+
+        List<InterlockHistoryDistinctZZXTVO> zzxtvoList = summaryHistoryMapper.getDistinctZZXTSummaryList(dto);
+
+        if(zzxtvoList == null) return 0;
+
+        Workbook workbook = new XSSFWorkbook();
+
+        // 创建居中对齐的样式
+        CellStyle centerAlignStyle = workbook.createCellStyle();
+        centerAlignStyle.setAlignment(HorizontalAlignment.CENTER);
+        centerAlignStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+
+        // 创建居右对齐的样式
+        CellStyle rightAlignStyle = workbook.createCellStyle();
+        rightAlignStyle.setAlignment(HorizontalAlignment.RIGHT);
+        rightAlignStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+
+        if (zzxtvoList != null) {
+            for (InterlockHistoryDistinctZZXTVO zzxtvo : zzxtvoList) {
+                dto.setInterlockSystemId(zzxtvo.getInterlockSystemId()); // 系统id
+                List<InterlockSummaryHistoryVO> exportList = interlockDetailHistoryMapper.getForExport(dto);
+
+                if(exportList != null) {
+                    exportList.stream().map(this::zh).collect(Collectors.toList());
+                }
+
+                String sheetName = zzxtvo.getInterlockApparatusName() + "-" + zzxtvo.getInterlockSystemName();
+                Sheet sheet = workbook.createSheet(sheetName);
+
+                // 设置默认行高为 24.6 点
+                sheet.setDefaultRowHeightInPoints(24.6f);
+                // 设置列宽——30或15个字符宽度
+                int[] columnWidths = {30, 30, 30, 15, 15, 15, 15, 15};
+                for (int j = 0; j < columnWidths.length; j++) {
+                    sheet.setColumnWidth(j, columnWidths[j] * 256);
+                }
+
+                // 计算投用率
+                InterlockHistoryQueryDTO dto1 = InterlockSummaryHistoryConvert.INSTANCE.toInterlockStatus(dto, "1"); // 1投用
+                int ty = summaryHistoryMapper.cocuntTYOrHL(dto1);
+                dto1.setInterlockStatus("0"); // 0未投用
+                int wty = summaryHistoryMapper.cocuntTYOrHL(dto1);
+                int total = ty + wty; // 总数量
+                double tyl = (double) ty / total * 100;
+
+                // 总回路数
+                InterlockHistoryQueryDTO dto2 = InterlockSummaryHistoryConvert.INSTANCE.toLoopHealthLevel(dto, "A");
+                int loopHealthLevelA = summaryHistoryMapper.cocuntTYOrHL(dto2);
+                dto2.setLoopHealthLevel("B");
+                int loopHealthLevelB = summaryHistoryMapper.cocuntTYOrHL(dto2);
+                dto2.setLoopHealthLevel("C");
+                int loopHealthLevelC = summaryHistoryMapper.cocuntTYOrHL(dto2);
+                int loopHealthLevel = loopHealthLevelA * 3 + loopHealthLevelB * 2 + loopHealthLevelC * 1;
+
+                String secondTitle = "  投用率:" + tyl + "%" + "  总回路数:" + loopHealthLevel;
+                if (dto.getBeginTime() != null && dto.getEndTime() == null) {
+                    secondTitle = "起始时间:" + formattedBeginTime + secondTitle;
+                } else if (dto.getBeginTime() == null && dto.getEndTime() != null) {
+                    secondTitle = "结束时间:" + formattedEndTime + secondTitle;
+                } else if (dto.getBeginTime() != null && dto.getEndTime() != null) {
+                    secondTitle = "起始时间:" + formattedBeginTime + "  结束时间:" + formattedEndTime + secondTitle;
+                }
+
+                //标题行
+                int rowNum = 0;
+                Row titleRow = sheet.createRow(rowNum++);
+                Cell titleCell = titleRow.createCell(0);
+                titleCell.setCellValue(title + "报表");
+                titleCell.setCellStyle(centerAlignStyle); // 应用居中对齐的样式
+
+                //第二行标题行
+                Row secondTitleRow = sheet.createRow(rowNum++);
+                Cell secondTitleCell = secondTitleRow.createCell(0);
+                secondTitleCell.setCellValue(secondTitle);
+                secondTitleCell.setCellStyle(rightAlignStyle); // 应用居右对齐的样式
+
+                //第三行列名
+                Row columnRow= sheet.createRow(rowNum++);
+                int column = 0;
+                createCellWithValueStyle(columnRow, column++, "采集时间", centerAlignStyle);
+                createCellWithValueStyle(columnRow, column++, "联锁名称", centerAlignStyle);
+                createCellWithValueStyle(columnRow, column++, "联锁条件点位", centerAlignStyle);
+                createCellWithValueStyle(columnRow, column++, "仪表状态", centerAlignStyle);
+                createCellWithValueStyle(columnRow, column++, "联锁状态", centerAlignStyle);
+                createCellWithValueStyle(columnRow, column++, "旁路状态", centerAlignStyle);
+                createCellWithValueStyle(columnRow, column++, "控制系统状态", centerAlignStyle);
+                createCellWithValueStyle(columnRow, column++, "回路健康级别", centerAlignStyle);
+
+                // 分别合并第一行、第二行的前8列
+                sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 7));
+                sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, 7));
+
+                // 创建单元格、设置格式、填充数据
+                int startTagTimeRow = 0;
+                int startInterlockNameRow = 0;
+                int startInterlockStatusRow = 0;
+                int startLoopHealthLevelRow = 0;
+
+                for (int idx = 0; idx < exportList.size(); idx++)  {
+                    InterlockSummaryHistoryVO record = exportList.get(idx);
+
+                    int i = 0;
+                    Row row = sheet.createRow(rowNum);
+                    createCellWithValueStyle(row, i++, record.getTagTime(), centerAlignStyle);
+                    createCellWithValueStyle(row, i++, record.getInterlockname(), centerAlignStyle);
+                    createCellWithValueStyle(row, i++, record.getInterlockConditionTag(), centerAlignStyle);
+                    createCellWithValueStyle(row, i++, record.getInstrumentStatus(), centerAlignStyle);
+                    createCellWithValueStyle(row, i++, record.getInterlockStatus(), centerAlignStyle);
+                    createCellWithValueStyle(row, i++, record.getBypass(), centerAlignStyle);
+                    createCellWithValueStyle(row, i++, record.getControlSystemStatus(), centerAlignStyle);
+                    createCellWithValueStyle(row, i++, record.getLoopHealthLevel(), centerAlignStyle);
+
+
+                    // 合并 "采集时间" 列单元格
+                    if (idx == 0 || !record.getTagTime().equals(exportList.get(idx - 1).getTagTime())) {
+                        if (idx > 0 && (rowNum - startTagTimeRow) > 1) {
+                            sheet.addMergedRegion(new CellRangeAddress(startTagTimeRow, rowNum - 1, 0, 0));
+                        }
+                        startTagTimeRow = rowNum;
+                    }
+
+                    // 合并 "联锁名称" 列单元格
+                    if (idx == 0 || !record.getInterlockname().equals(exportList.get(idx - 1).getInterlockname())) {
+                        if (idx > 0 && (rowNum - startInterlockNameRow) > 1) {
+                            sheet.addMergedRegion(new CellRangeAddress(startInterlockNameRow, rowNum - 1, 1, 1));
+                        }
+                        startInterlockNameRow = rowNum;
+                    }
+
+                    // 合并 "联锁状态" 列单元格,基于 "采集时间"
+                    if (idx == 0 || !record.getTagTime().equals(exportList.get(idx - 1).getTagTime())) {
+                        if (idx > 0 && (rowNum - startInterlockStatusRow) > 1) {
+                            sheet.addMergedRegion(new CellRangeAddress(startInterlockStatusRow, rowNum - 1, 4, 4));
+                        }
+                        startInterlockStatusRow = rowNum;
+                    }
+
+                    // 合并 "回路健康状态" 列单元格,基于 "采集时间"
+                    if (idx == 0 || !record.getTagTime().equals(exportList.get(idx - 1).getTagTime())) {
+                        if (idx > 0 && (rowNum - startLoopHealthLevelRow) > 1) {
+                            sheet.addMergedRegion(new CellRangeAddress(startLoopHealthLevelRow, rowNum - 1, 7, 7));
+                        }
+                        startLoopHealthLevelRow = rowNum;
+                    }
+
+                    rowNum++;
+                }
+
+                // 最后一组合并区域的处理
+                if ((rowNum - startTagTimeRow) > 1) {
+                    sheet.addMergedRegion(new CellRangeAddress(startTagTimeRow, rowNum - 1, 0, 0));
+                }
+                if ((rowNum - startInterlockNameRow) > 1) {
+                    sheet.addMergedRegion(new CellRangeAddress(startInterlockNameRow, rowNum - 1, 1, 1));
+                }
+                if ((rowNum - startInterlockStatusRow) > 1) {
+                    sheet.addMergedRegion(new CellRangeAddress(startInterlockStatusRow, rowNum - 1, 4, 4));
+                }
+                if ((rowNum - startLoopHealthLevelRow) > 1) {
+                    sheet.addMergedRegion(new CellRangeAddress(startLoopHealthLevelRow, rowNum - 1, 7, 7));
+                }
+
+            }
+        }
+
+        try (FileOutputStream fileOut = new FileOutputStream(filePath)) {
+            workbook.write(fileOut);
+        } catch (IOException e) {
+            // 处理异常
+            e.printStackTrace();
+        } finally {
+            try {
+                if (workbook != null) {
+                    workbook.close();
+                }
+            } catch (IOException e) {
+                // 处理关闭 workbook 时可能发生的异常
+                e.printStackTrace();
+            }
+        }
+
+        return 1;
+
+    }
+
+
+    // 创建单元格
+    private static void createCellWithValueStyle(Row row, int col, Object value, CellStyle style) {
+
+        Cell cell = row.createCell(col++); // 单元格在第几列
+
+        // 单元格内容
+        if (value instanceof String) {
+            cell.setCellValue((String) value);
+        } else if (value instanceof Number) {
+            cell.setCellValue(((Number) value).doubleValue());
+        } else if (value instanceof Boolean) {
+            cell.setCellValue((Boolean) value);
+        } else if (value != null) {
+            cell.setCellValue(value.toString());
+        }
 
+        cell.setCellStyle(style); //单元格样式
+    }
+
+    private InterlockSummaryHistoryVO zh(InterlockSummaryHistoryVO vo){
+        //仪表状态 0正常1故障
+        if(vo.getInstrumentStatus()!=null){
+            if(vo.getInstrumentStatus().equals("0")) vo.setInstrumentStatus("正常");
+            else if(vo.getInstrumentStatus().equals("1")) vo.setInstrumentStatus("故障");
+        }
+        //控制系统状态 0正常1非正常
+        if(vo.getControlSystemStatus()!=null){
+            if(vo.getControlSystemStatus().equals("0")) vo.setControlSystemStatus("正常");
+            else if(vo.getControlSystemStatus().equals("1")) vo.setControlSystemStatus("非正常");
+        }
+        //联锁状态 0未投用1投用
+        if(vo.getInterlockStatus()!=null){
+            if(vo.getInterlockStatus().equals("0")) vo.setInterlockStatus("未投用");
+            else if(vo.getInterlockStatus().equals("1")) vo.setInterlockStatus("投用");
+        }
+        //旁路状态 1是0否
+        if(vo.getBypass()!=null){
+            if(vo.getBypass().equals("0")) vo.setBypass("是");
+            else if(vo.getBypass().equals("1")) vo.setBypass("否");
+        }
+        return vo;
+    }
 
 }