From 2121a293cb840567be565ea2b6e501c868bbfc94 Mon Sep 17 00:00:00 2001 From: hongawen <83944980@qq.com> Date: Tue, 9 Sep 2025 09:43:44 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E8=B0=83=E6=95=B4=E9=83=A8?= =?UTF-8?q?=E5=88=86=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- detection/pom.xml | 7 + .../plan/service/impl/AdPlanServiceImpl.java | 2 +- .../report/controller/ReportController.java | 2 +- .../service/impl/PqReportServiceImpl.java | 381 +++++------ .../gather/report/utils/BookmarkUtil.java | 295 --------- .../report/utils/Docx4jInsertParagraph.java | 44 -- .../njcn/gather/report/utils/WordUtil.java | 144 ----- .../main/resources/model/report_table.docx | Bin 27934 -> 27950 bytes .../pojo/param/SingleNonHarmParam.java | 1 - tools/report-generator/PROJECT_SUMMARY.md | 184 ------ tools/report-generator/pom.xml | 28 +- .../controller/ReportGeneratorController.java | 392 ------------ .../report/engine/DocumentProcessor.java | 63 -- .../report/engine/WordDocumentProcessor.java | 253 -------- .../tools/report/model/ProcessOptions.java | 175 ----- .../tools/report/model/ProcessResult.java | 232 ------- .../tools/report/model/TemplateRequest.java | 184 ------ .../tools/report/model/TemplateSource.java | 114 ---- .../model}/constant/ReportConstant.java | 2 +- .../model/{ => enums}/ReportResponseEnum.java | 2 +- .../model/{ => enums}/TemplateType.java | 2 +- .../report/service/IWordReportService.java | 25 + .../service/ReportGeneratorService.java | 52 -- .../impl/ReportGeneratorServiceImpl.java | 216 ------- .../service/impl/WordReportServiceImpl.java | 50 ++ .../tools/report/util/BookmarkUtil.java | 172 +++++ .../tools/report/util/Docx4jAdvancedUtil.java | 603 ------------------ .../gather/tools/report/util}/Docx4jUtil.java | 152 ++--- .../tools/report/util/DocxMergeUtil.java | 407 ++++++++++++ .../tools/report/util/PlaceholderUtil.java | 262 ++++++++ .../report/util/ReportExceptionUtil.java | 88 +-- .../tools/report/util/WordDocumentUtil.java | 440 +++++-------- .../tools/report/ReportGeneratorTest.java | 103 --- 33 files changed, 1275 insertions(+), 3802 deletions(-) delete mode 100644 detection/src/main/java/com/njcn/gather/report/utils/BookmarkUtil.java delete mode 100644 detection/src/main/java/com/njcn/gather/report/utils/Docx4jInsertParagraph.java delete mode 100644 detection/src/main/java/com/njcn/gather/report/utils/WordUtil.java delete mode 100644 tools/report-generator/PROJECT_SUMMARY.md delete mode 100644 tools/report-generator/src/main/java/com/njcn/gather/tools/report/controller/ReportGeneratorController.java delete mode 100644 tools/report-generator/src/main/java/com/njcn/gather/tools/report/engine/DocumentProcessor.java delete mode 100644 tools/report-generator/src/main/java/com/njcn/gather/tools/report/engine/WordDocumentProcessor.java delete mode 100644 tools/report-generator/src/main/java/com/njcn/gather/tools/report/model/ProcessOptions.java delete mode 100644 tools/report-generator/src/main/java/com/njcn/gather/tools/report/model/ProcessResult.java delete mode 100644 tools/report-generator/src/main/java/com/njcn/gather/tools/report/model/TemplateRequest.java delete mode 100644 tools/report-generator/src/main/java/com/njcn/gather/tools/report/model/TemplateSource.java rename {detection/src/main/java/com/njcn/gather/report/pojo => tools/report-generator/src/main/java/com/njcn/gather/tools/report/model}/constant/ReportConstant.java (85%) rename tools/report-generator/src/main/java/com/njcn/gather/tools/report/model/{ => enums}/ReportResponseEnum.java (97%) rename tools/report-generator/src/main/java/com/njcn/gather/tools/report/model/{ => enums}/TemplateType.java (96%) create mode 100644 tools/report-generator/src/main/java/com/njcn/gather/tools/report/service/IWordReportService.java delete mode 100644 tools/report-generator/src/main/java/com/njcn/gather/tools/report/service/ReportGeneratorService.java delete mode 100644 tools/report-generator/src/main/java/com/njcn/gather/tools/report/service/impl/ReportGeneratorServiceImpl.java create mode 100644 tools/report-generator/src/main/java/com/njcn/gather/tools/report/service/impl/WordReportServiceImpl.java create mode 100644 tools/report-generator/src/main/java/com/njcn/gather/tools/report/util/BookmarkUtil.java delete mode 100644 tools/report-generator/src/main/java/com/njcn/gather/tools/report/util/Docx4jAdvancedUtil.java rename {detection/src/main/java/com/njcn/gather/report/utils => tools/report-generator/src/main/java/com/njcn/gather/tools/report/util}/Docx4jUtil.java (81%) create mode 100644 tools/report-generator/src/main/java/com/njcn/gather/tools/report/util/DocxMergeUtil.java create mode 100644 tools/report-generator/src/main/java/com/njcn/gather/tools/report/util/PlaceholderUtil.java delete mode 100644 tools/report-generator/src/test/java/com/njcn/gather/tools/report/ReportGeneratorTest.java diff --git a/detection/pom.xml b/detection/pom.xml index dc7afcc6..bf1f5825 100644 --- a/detection/pom.xml +++ b/detection/pom.xml @@ -126,12 +126,19 @@ + com.njcn.gather wave-comtrade 1.0.0 + + + com.njcn.gather + report-generator + 1.0.0 + diff --git a/detection/src/main/java/com/njcn/gather/plan/service/impl/AdPlanServiceImpl.java b/detection/src/main/java/com/njcn/gather/plan/service/impl/AdPlanServiceImpl.java index 8e461226..1c53cb9d 100644 --- a/detection/src/main/java/com/njcn/gather/plan/service/impl/AdPlanServiceImpl.java +++ b/detection/src/main/java/com/njcn/gather/plan/service/impl/AdPlanServiceImpl.java @@ -61,7 +61,6 @@ import com.njcn.gather.plan.service.IAdPlanSourceService; import com.njcn.gather.plan.service.IAdPlanStandardDevService; import com.njcn.gather.plan.service.IAdPlanTestConfigService; import com.njcn.gather.pojo.enums.DetectionResponseEnum; -import com.njcn.gather.report.pojo.constant.ReportConstant; import com.njcn.gather.report.pojo.po.PqReport; import com.njcn.gather.report.service.IPqReportService; import com.njcn.gather.script.pojo.po.PqScript; @@ -82,6 +81,7 @@ import com.njcn.gather.system.dictionary.pojo.po.DictType; import com.njcn.gather.system.dictionary.service.IDictDataService; import com.njcn.gather.system.dictionary.service.IDictTreeService; import com.njcn.gather.system.dictionary.service.IDictTypeService; +import com.njcn.gather.tools.report.model.constant.ReportConstant; import com.njcn.gather.type.pojo.po.DevType; import com.njcn.gather.type.service.IDevTypeService; import com.njcn.gather.user.user.pojo.po.SysUser; diff --git a/detection/src/main/java/com/njcn/gather/report/controller/ReportController.java b/detection/src/main/java/com/njcn/gather/report/controller/ReportController.java index 17d92530..042594eb 100644 --- a/detection/src/main/java/com/njcn/gather/report/controller/ReportController.java +++ b/detection/src/main/java/com/njcn/gather/report/controller/ReportController.java @@ -160,7 +160,7 @@ public class ReportController extends BaseController { @OperateInfo @PostMapping("/uploadReportToCloud") @ApiOperation("批量上传检测报告到云端") - @ApiImplicitParam(name = "deviceIds", value = "被检设备ID列表,为空时上传所有已生成报告的设备", required = false) + @ApiImplicitParam(name = "deviceIds", value = "被检设备ID列表,为空时上传所有已生成报告的设备") public HttpResult uploadReportToCloud(@RequestBody(required = false) List deviceIds) { String methodDescribe = getMethodDescribe("uploadReportToCloud"); LogUtil.njcnDebug(log, "{},设备ID列表为:{}", methodDescribe, deviceIds); diff --git a/detection/src/main/java/com/njcn/gather/report/service/impl/PqReportServiceImpl.java b/detection/src/main/java/com/njcn/gather/report/service/impl/PqReportServiceImpl.java index 6ab6dd82..759c0e28 100644 --- a/detection/src/main/java/com/njcn/gather/report/service/impl/PqReportServiceImpl.java +++ b/detection/src/main/java/com/njcn/gather/report/service/impl/PqReportServiceImpl.java @@ -12,7 +12,6 @@ import cn.hutool.extra.qrcode.QrCodeUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSON; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -21,7 +20,6 @@ import com.njcn.common.pojo.constant.PatternRegex; import com.njcn.common.pojo.enums.common.DataStateEnum; import com.njcn.common.pojo.exception.BusinessException; import com.njcn.common.utils.images.ImageConverter; -import com.njcn.gather.detection.handler.SocketDevResponseService; import com.njcn.gather.detection.pojo.constant.DetectionCommunicateConstant; import com.njcn.gather.detection.pojo.enums.DetectionCodeEnum; import com.njcn.gather.detection.pojo.enums.SourceOperateCodeEnum; @@ -29,10 +27,7 @@ import com.njcn.gather.detection.pojo.param.PreDetectionParam; import com.njcn.gather.detection.pojo.vo.DetectionData; import com.njcn.gather.detection.pojo.vo.SocketMsg; import com.njcn.gather.detection.util.socket.SocketManager; -import com.njcn.gather.detection.util.socket.cilent.NettyClient; -import com.njcn.gather.detection.util.socket.cilent.NettyDevClientHandler; import com.njcn.gather.device.mapper.PqDevMapper; -import com.njcn.gather.device.mapper.PqDevSubMapper; import com.njcn.gather.device.pojo.enums.CheckStateEnum; import com.njcn.gather.device.pojo.enums.DevReportStateEnum; import com.njcn.gather.device.pojo.param.PqDevParam; @@ -48,20 +43,15 @@ import com.njcn.gather.pojo.enums.DetectionResponseEnum; import com.njcn.gather.report.mapper.PqReportMapper; import com.njcn.gather.report.pojo.DevReportParam; import com.njcn.gather.report.pojo.constant.PowerConstant; -import com.njcn.gather.report.pojo.constant.ReportConstant; import com.njcn.gather.report.pojo.enums.*; import com.njcn.gather.report.pojo.param.ReportParam; import com.njcn.gather.report.pojo.po.PqReport; import com.njcn.gather.report.pojo.result.SingleTestResult; import com.njcn.gather.report.pojo.vo.PqReportVO; import com.njcn.gather.report.service.IPqReportService; -import com.njcn.gather.report.utils.BookmarkUtil; -import com.njcn.gather.report.utils.Docx4jUtil; -import com.njcn.gather.report.utils.WordUtil; import com.njcn.gather.result.service.IResultService; import com.njcn.gather.script.pojo.vo.PqScriptDtlDataVO; import com.njcn.gather.script.service.IPqScriptDtlsService; -import com.njcn.gather.storage.pojo.param.SingleNonHarmParam; import com.njcn.gather.storage.pojo.po.SimAndDigHarmonicResult; import com.njcn.gather.storage.pojo.po.SimAndDigNonHarmonicResult; import com.njcn.gather.storage.service.SimAndDigHarmonicService; @@ -70,6 +60,12 @@ import com.njcn.gather.system.cfg.pojo.enums.SceneEnum; import com.njcn.gather.system.cfg.service.ISysTestConfigService; import com.njcn.gather.system.dictionary.pojo.po.DictData; import com.njcn.gather.system.dictionary.service.IDictDataService; +import com.njcn.gather.tools.report.model.constant.ReportConstant; +import com.njcn.gather.tools.report.service.IWordReportService; +import com.njcn.gather.tools.report.util.BookmarkUtil; +import com.njcn.gather.tools.report.util.Docx4jUtil; +import com.njcn.gather.tools.report.util.DocxMergeUtil; +import com.njcn.gather.tools.report.util.WordDocumentUtil; import com.njcn.gather.type.pojo.po.DevType; import com.njcn.gather.type.service.IDevTypeService; import com.njcn.http.util.RestTemplateUtil; @@ -80,13 +76,11 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPReply; -import org.apache.poi.xwpf.usermodel.*; import org.docx4j.jaxb.Context; import org.docx4j.openpackaging.packages.WordprocessingMLPackage; import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart; import org.docx4j.wml.*; import org.springframework.beans.BeanUtils; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.ClassPathResource; import org.springframework.http.ResponseEntity; @@ -94,6 +88,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; +import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import javax.xml.bind.JAXBElement; import java.awt.*; @@ -108,14 +103,11 @@ import java.nio.file.Paths; import java.util.List; import java.util.*; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; import java.util.stream.Collectors; /** - * @author makejava + * @author caozehui * @date 2025-03-19 */ @Slf4j @@ -161,37 +153,20 @@ public class PqReportServiceImpl extends ServiceImpl i private final IPqDevService iPqDevService; private final PqDevMapper pqDevMapper; private final IPqDevSubService iPqDevSubService; - private final IDictDataService dictDataService; - private final IAdPlanService adPlanService; - private final IPqScriptDtlsService pqScriptDtlsService; - private final SimAndDigNonHarmonicService adNonHarmonicService; - private final SimAndDigHarmonicService adHarmonicService; - private final IDevTypeService devTypeService; - private final IResultService resultService; - private final ISysTestConfigService sysTestConfigService; - - private final SocketDevResponseService socketDevResponseService; private final SocketManager socketManager; + private final IWordReportService wordReportService; - @Autowired + @Resource private RestTemplateUtil restTemplateUtil; - private final ThreadPoolExecutor executor = new ThreadPoolExecutor( - 4, 8, 30, TimeUnit.SECONDS, - new LinkedBlockingQueue<>(100), - // 队列满时由主线程执行 - new ThreadPoolExecutor.CallerRunsPolicy() - ); - - private final long FILE_SIZE_LIMIT = 5 * 1024 * 1024; @Override public Page list(ReportParam.QueryParam queryParam) { @@ -309,22 +284,23 @@ public class PqReportServiceImpl extends ServiceImpl i /** * 上传文件,并设置pqReport的basePath和detailPath属性 * - * @param reportParam - * @param pqReport - * @param isAdd + * @param reportParam 报告参数 + * @param pqReport 报告信息 + * @param isAdd 是否添加 */ private void uploadFile(ReportParam reportParam, PqReport pqReport, boolean isAdd) { MultipartFile baseFile = reportParam.getBaseFile(); MultipartFile detailFile = reportParam.getDetailFile(); String newDir = templatePath + File.separator + reportParam.getName() + File.separator + reportParam.getVersion() + File.separator; + long FILE_SIZE_LIMIT = 5 * 1024 * 1024; if (isAdd) { if (ObjectUtil.isNotNull(baseFile) && !baseFile.isEmpty() && ObjectUtil.isNotNull(detailFile) && !detailFile.isEmpty()) { String baseOriginalFilename = baseFile.getOriginalFilename(); String detailOriginalFilename = detailFile.getOriginalFilename(); - if (!baseOriginalFilename.endsWith(".docx") || !detailOriginalFilename.endsWith(".docx")) { + if (!baseOriginalFilename.endsWith(ReportConstant.DOCX) || !detailOriginalFilename.endsWith(ReportConstant.DOCX)) { throw new BusinessException(ReportResponseEnum.FILE_SUFFIX_ERROR); } if (baseOriginalFilename.equals(detailOriginalFilename)) { @@ -351,7 +327,7 @@ public class PqReportServiceImpl extends ServiceImpl i String baseFileOriginalFilename = ""; if (ObjectUtil.isNotNull(baseFile) && !baseFile.isEmpty()) { baseFileOriginalFilename = baseFile.getOriginalFilename(); - if (!baseFileOriginalFilename.endsWith(".docx")) { + if (!baseFileOriginalFilename.endsWith(ReportConstant.DOCX)) { throw new BusinessException(ReportResponseEnum.FILE_SUFFIX_ERROR); } if (baseFile.getSize() > FILE_SIZE_LIMIT) { @@ -362,7 +338,7 @@ public class PqReportServiceImpl extends ServiceImpl i String detailFileOriginalFilename = ""; if (ObjectUtil.isNotNull(detailFile) && !detailFile.isEmpty()) { detailFileOriginalFilename = detailFile.getOriginalFilename(); - if (!detailFileOriginalFilename.endsWith(".docx")) { + if (!detailFileOriginalFilename.endsWith(ReportConstant.DOCX)) { throw new BusinessException(ReportResponseEnum.FILE_SUFFIX_ERROR); } if (detailFile.getSize() > FILE_SIZE_LIMIT) { @@ -370,17 +346,17 @@ public class PqReportServiceImpl extends ServiceImpl i } } - if (!"".equals(baseFileOriginalFilename) && !"".equals(detailFileOriginalFilename)) { + if (!baseFileOriginalFilename.isEmpty() && !detailFileOriginalFilename.isEmpty()) { if (baseFileOriginalFilename.equals(detailFileOriginalFilename)) { throw new BusinessException(ReportResponseEnum.FILE_NAME_SAME_ERROR); } } - if (!"".equals(baseFileOriginalFilename)) { + if (!baseFileOriginalFilename.isEmpty()) { if (baseFileOriginalFilename.equals(oldPqReport.getDetailPath().substring(oldPqReport.getDetailPath().lastIndexOf(File.separator) + 1))) { throw new BusinessException(ReportResponseEnum.FILE_NAME_SAME_ERROR); } } - if (!"".equals(detailFileOriginalFilename)) { + if (!detailFileOriginalFilename.isEmpty()) { if (detailFileOriginalFilename.equals(oldPqReport.getBasePath().substring(oldPqReport.getBasePath().lastIndexOf(File.separator) + 1))) { throw new BusinessException(ReportResponseEnum.FILE_NAME_SAME_ERROR); } @@ -422,13 +398,13 @@ public class PqReportServiceImpl extends ServiceImpl i } } - if (!"".equals(baseFileOriginalFilename)) { + if (!baseFileOriginalFilename.isEmpty()) { pqReport.setBasePath(newDir + baseFileOriginalFilename); Paths.get(oldPqReport.getBasePath()).toFile().delete(); Paths.get(newDir + oldPqReport.getBasePath().substring(oldPqReport.getBasePath().lastIndexOf(File.separator) + 1)).toFile().delete(); this.uploadFile(baseFile, pqReport.getBasePath()); } - if (!"".equals(detailFileOriginalFilename)) { + if (!detailFileOriginalFilename.isEmpty()) { pqReport.setDetailPath(newDir + detailFileOriginalFilename); Paths.get(oldPqReport.getDetailPath()).toFile().delete(); Paths.get(newDir + oldPqReport.getDetailPath().substring(oldPqReport.getDetailPath().lastIndexOf(File.separator) + 1)).toFile().delete(); @@ -560,10 +536,11 @@ public class PqReportServiceImpl extends ServiceImpl i @Override public void generateReport(DevReportParam devReportParam) { AdPlan plan = adPlanService.getById(devReportParam.getPlanId()); + // 0 - 模板占位符更新, 1 - 根据配置模版动态组合生产的报告 if (plan.getAssociateReport() == 1) { this.generateReportByPlan(plan, devReportParam); } else if (plan.getAssociateReport() == 0) { - this.generateReportByDevType(plan, devReportParam); + this.generateReportByDevType(devReportParam); } } @@ -572,14 +549,13 @@ public class PqReportServiceImpl extends ServiceImpl i * 根据设备类型生成报告 * 注:该方法目前仅支持楼下出厂检测场景,属于模板占位符替换方式,后期可能会有调整 * - * @param plan 计划信息 * @param devReportParam 被检设备信息 */ - private void generateReportByDevType(AdPlan plan, DevReportParam devReportParam) { + private void generateReportByDevType(DevReportParam devReportParam) { devReportParam.getDevIdList().forEach(devId -> { - devReportParam.setDevId(devId); // 根据设备类型找到报告模板 - PqDevVO pqDevVO = iPqDevService.getPqDevById(devReportParam.getDevId()); + PqDevVO pqDevVO = iPqDevService.getPqDevById(devId); + devReportParam.setDevId(devId); if (Objects.isNull(pqDevVO)) { throw new BusinessException(ReportResponseEnum.DEVICE_NOT_EXIST); } @@ -595,34 +571,30 @@ public class PqReportServiceImpl extends ServiceImpl i // 读取模板文件 ClassPathResource resource = new ClassPathResource("/model/" + reportName.getCode() + ReportConstant.DOCX); try (InputStream inputStream = resource.getInputStream()) { - // 加载Word文档 - XWPFDocument baseModelDocument = new XWPFDocument(inputStream); // 处理基础模版中的信息 - Map baseModelDataMap = dealBaseModelData(pqDevVO, devType, "${", "}"); - // 替换模板中的信息,避免信息丢失,段落和表格均参与替换 - WordUtil.replacePlaceholders(baseModelDocument, baseModelDataMap); + Map baseModelDataMap = dealBaseModelData(pqDevVO, devType); + InputStream wordFinishInputStream = wordReportService.replacePlaceholders(inputStream, baseModelDataMap); + List wordFileInputStreams = new ArrayList<>(); + wordFileInputStreams.add(wordFinishInputStream); // 处理数据页中的信息 - dealDataModel(baseModelDocument, devReportParam, pqDevVO); + dealDataModel(wordFileInputStreams, devReportParam, pqDevVO); + // 合并文档 + InputStream finalWordStream = DocxMergeUtil.mergeDocuments(wordFileInputStreams); // 处理需要输出的目录地址 基础路径+设备类型+装置编号.docx // 最终文件输出的路径 // String dirPath = reportPath.concat(File.separator).concat(devType.getName()); String dirPath = reportPath; // 确保目录存在 ensureDirectoryExists(dirPath); - String reportFullPath = dirPath.concat(File.separator).concat(pqDevVO.getCreateId()).concat(".docx"); - FileOutputStream out = new FileOutputStream(reportFullPath); + String reportFullPath = dirPath.concat(File.separator).concat(pqDevVO.getCreateId()).concat(ReportConstant.DOCX); // 4. 保存新的Word文档 - try { - baseModelDocument.write(out); - } catch (IOException e) { - throw new BusinessException(ReportResponseEnum.GENERATE_REPORT_ERROR); - } - out.close(); - this.updateDevAndPlanState(devReportParam.getDevId(), devReportParam.getPlanId()); + WordprocessingMLPackage wordPackage = WordprocessingMLPackage.load(finalWordStream); + wordPackage.save(new File(reportFullPath)); + this.updateDevAndPlanState(devId, devReportParam.getPlanId()); // 异步将有效的二维码下装到被检设备 CompletableFuture.runAsync(() -> { try { - sendQrToDevice(pqDevVO.getIp(), pqDevVO.getCreateId() + ".docx"); + sendQrToDevice(pqDevVO.getIp(), pqDevVO.getCreateId() + ReportConstant.DOCX); log.info("二维码下装成功,设备IP: {}", pqDevVO.getIp()); } catch (Exception e) { log.error("二维码下装失败,设备IP: {}", pqDevVO.getIp(), e); @@ -643,7 +615,7 @@ public class PqReportServiceImpl extends ServiceImpl i } } }); - } catch (IOException e) { + } catch (Exception e) { log.error(ReportResponseEnum.GENERATE_REPORT_ERROR.getMessage(), e); throw new BusinessException(ReportResponseEnum.GENERATE_REPORT_ERROR); } @@ -694,7 +666,7 @@ public class PqReportServiceImpl extends ServiceImpl i data.set("file", base64String); sendFileMsg.setData(data.toString()); String msg = JSON.toJSONString(sendFileMsg); - Channel channel = SocketManager.getChannelByUserId(RequestUtil.getLoginName()+ DetectionCommunicateConstant.DEV); + Channel channel = SocketManager.getChannelByUserId(RequestUtil.getLoginName() + DetectionCommunicateConstant.DEV); if (Objects.isNull(channel) || !channel.isActive()) { // 进行源通信连接 PreDetectionParam preDetectionParam = new PreDetectionParam(); @@ -769,13 +741,14 @@ public class PqReportServiceImpl extends ServiceImpl i * @param devReportParam 设备信息 */ private void generateReportByPlan(AdPlan plan, DevReportParam devReportParam) { + // 支持批量生成报告 devReportParam.getDevIdList().forEach(devId -> { - devReportParam.setDevId(devId); // 准备被检设备的基础信息 - PqDevVO pqDevVO = iPqDevService.getPqDevById(devReportParam.getDevId()); + PqDevVO pqDevVO = iPqDevService.getPqDevById(devId); if (Objects.isNull(pqDevVO)) { throw new BusinessException(ReportResponseEnum.DEVICE_NOT_EXIST); } + devReportParam.setDevId(devId); // 获取设备型号 DevType devType = devTypeService.getById(pqDevVO.getDevType()); if (Objects.isNull(devType)) { @@ -785,24 +758,27 @@ public class PqReportServiceImpl extends ServiceImpl i if (Objects.isNull(report)) { throw new BusinessException(ReportResponseEnum.REPORT_TEMPLATE_NOT_EXIST); } - try { - WordprocessingMLPackage baseModelDocument = WordprocessingMLPackage.load(new File(report.getBasePath())); - WordprocessingMLPackage detailModelDocument = WordprocessingMLPackage.load(new File(report.getDetailPath())); + Path basePath = Paths.get(report.getBasePath()); + Path detailPath = Paths.get(report.getDetailPath()); + try (InputStream baseInputStream = Files.newInputStream(basePath); + InputStream detailInputStream = Files.newInputStream(detailPath)) { + WordprocessingMLPackage detailModelDocument = WordprocessingMLPackage.load(detailInputStream); // 获取文档基础部分,并替换占位符 + Map baseModelDataMap = dealBaseModelData(pqDevVO, devType); + InputStream wordFinishInputStream = wordReportService.replacePlaceholders(baseInputStream, baseModelDataMap); + WordprocessingMLPackage baseModelDocument = WordprocessingMLPackage.load(wordFinishInputStream); MainDocumentPart baseDocumentPart = baseModelDocument.getMainDocumentPart(); - Map baseModelDataMap = dealBaseModelData(pqDevVO, devType, "", ""); - baseDocumentPart.variableReplace(baseModelDataMap); + // 获取数据模版页内容,根据脚本动态组装数据页内容 MainDocumentPart detailDocumentPart = detailModelDocument.getMainDocumentPart(); -// dealDataModelScattered(baseDocumentPart, detailDocumentPart, devReportParam, pqDevVO); dealDataModelScatteredByBookmark(baseDocumentPart, detailDocumentPart, devReportParam, pqDevVO); + // 保存新的文档 String dirPath = reportPath.concat(File.separator).concat(devType.getName()); // 确保目录存在 ensureDirectoryExists(dirPath); baseModelDocument.save(new File(dirPath.concat(File.separator).concat(pqDevVO.getCreateId()).concat(ReportConstant.DOCX))); - - this.updateDevAndPlanState(devReportParam.getDevId(), devReportParam.getPlanId()); + this.updateDevAndPlanState(devId, devReportParam.getPlanId()); } catch (Exception e) { log.error(ReportResponseEnum.GENERATE_REPORT_ERROR.getMessage(), e); throw new BusinessException(ReportResponseEnum.GENERATE_REPORT_ERROR); @@ -847,8 +823,8 @@ public class PqReportServiceImpl extends ServiceImpl i Collections.sort(bookmarkEnums); // 定义个结果,以便存在结果信息的书签 Map> resultMap = new HashMap<>(); - List todoInsertList = new ArrayList<>(); - BookmarkUtil.BookmarkInfo bookmarkInfo = null; + List todoInsertList; + BookmarkUtil.BookmarkInfo bookmarkInfo; // 书签在文档的位置 for (int i = 0; i < bookmarkEnums.size(); i++) { BookmarkEnum bookmarkEnum = bookmarkEnums.get(i); @@ -983,13 +959,13 @@ public class PqReportServiceImpl extends ServiceImpl i cellValues.add(total); break; case TEST_RESULT_LINE: - for (int i = 0; i < value.size(); i++) { - cellValues.add(value.get(i) ? "合格" : "不合格"); + for (Boolean aBoolean : value) { + cellValues.add(aBoolean ? "合格" : "不合格"); } break; case TEST_RESULT_DETAIL: - for (int i = 0; i < value.size(); i++) { - cellValues.add(value.get(i) ? "合格" : "不合格"); + for (Boolean aBoolean : value) { + cellValues.add(aBoolean ? "合格" : "不合格"); } cellValues.add(total); break; @@ -1028,8 +1004,13 @@ public class PqReportServiceImpl extends ServiceImpl i for (int i = 0; i < devChns; i++) { // 回路标题 P titleParagraph = factory.createP(); - Integer lineNo = i + 1; - Docx4jUtil.createTitle(factory, titleParagraph, "测量回路" + lineNo, 28, true); + // 如果回路只有一个,则不需要加编号 + int lineNo = i + 1; + if (devChns > 1) { + Docx4jUtil.createTitle(factory, titleParagraph, "测量回路" + lineNo, 28, true); + } else { + Docx4jUtil.createTitle(factory, titleParagraph, "测量回路", 28, true); + } todoInsertList.add(titleParagraph); // 依次处理大项文档内容 Iterator>> iterator = scriptMap.entrySet().iterator(); @@ -1314,9 +1295,9 @@ public class PqReportServiceImpl extends ServiceImpl i StringBuilder filePath = new StringBuilder(reportPath.concat(File.separator)); if (SceneEnum.LEAVE_FACTORY_TEST.getValue().equals(currrentScene)) { - filePath.append(pqDevVO.getCreateId()).append(".docx"); + filePath.append(pqDevVO.getCreateId()).append(ReportConstant.DOCX); } else { - filePath.append(devType.getName()).append(File.separator).append(pqDevVO.getCreateId()).append(".docx"); + filePath.append(devType.getName()).append(File.separator).append(pqDevVO.getCreateId()).append(ReportConstant.DOCX); } File reportFile = new File(filePath.toString()); if (!reportFile.exists()) { @@ -1329,7 +1310,7 @@ public class PqReportServiceImpl extends ServiceImpl i // 设置响应头 response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document"); - String fileName = pqDevVO.getCreateId() + ".docx"; + String fileName = pqDevVO.getCreateId() + ReportConstant.DOCX; response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\""); // 将文件内容写入响应输出流 @@ -1349,7 +1330,7 @@ public class PqReportServiceImpl extends ServiceImpl i } @Override - @Transactional + @Transactional(rollbackFor = Exception.class) public boolean documented(List ids) { if (CollUtil.isNotEmpty(ids)) { List pqDevVOList = pqDevMapper.listByDevIds(ids); @@ -1401,66 +1382,66 @@ public class PqReportServiceImpl extends ServiceImpl i * 处理基础模版中的信息,非数据页报告 * 此处为什么要抽出拼接的前缀&后缀,是因为Docx4j工具包替换时会默认增加${},故在使用docx4j时前后缀必须为空 */ - private Map dealBaseModelData(PqDevVO pqDevVO, DevType devType, String prefix, String suffix) { + private Map dealBaseModelData(PqDevVO pqDevVO, DevType devType) { // 首先获取非数据页中需要的信息 Map baseModelMap = new HashMap<>(32); // 获取设备型号 - baseModelMap.put(prefix + BaseReportKeyEnum.DEV_TYPE.getKey() + suffix, devType.getName()); + baseModelMap.put(BaseReportKeyEnum.DEV_TYPE.getKey(), devType.getName()); // 检测员 - baseModelMap.put(prefix + BaseReportKeyEnum.INSPECTOR.getKey() + suffix, pqDevVO.getCheckBy() + ""); + baseModelMap.put(BaseReportKeyEnum.INSPECTOR.getKey(), pqDevVO.getCheckBy() + ""); // 调试日期 if (pqDevVO.getCheckTime() != null) { - baseModelMap.put(prefix + BaseReportKeyEnum.TEST_DATE.getKey() + suffix, DateUtil.format(pqDevVO.getCheckTime(), DatePattern.CHINESE_DATE_PATTERN)); + baseModelMap.put(BaseReportKeyEnum.TEST_DATE.getKey(), DateUtil.format(pqDevVO.getCheckTime(), DatePattern.CHINESE_DATE_PATTERN)); } else { - baseModelMap.put(prefix + BaseReportKeyEnum.TEST_DATE.getKey() + suffix, DateUtil.format(new Date(), DatePattern.CHINESE_DATE_PATTERN)); + baseModelMap.put(BaseReportKeyEnum.TEST_DATE.getKey(), DateUtil.format(new Date(), DatePattern.CHINESE_DATE_PATTERN)); } // 装置编码 - baseModelMap.put(prefix + BaseReportKeyEnum.DEV_CODE.getKey() + suffix, pqDevVO.getCreateId()); + baseModelMap.put(BaseReportKeyEnum.DEV_CODE.getKey(), pqDevVO.getCreateId()); // 工作电源 - baseModelMap.put(prefix + BaseReportKeyEnum.POWER.getKey() + suffix, devType.getPower()); + baseModelMap.put(BaseReportKeyEnum.POWER.getKey(), devType.getPower()); // 额定电流 - baseModelMap.put(prefix + BaseReportKeyEnum.DEV_CURR.getKey() + suffix, pqDevVO.getDevCurr().toString().concat(PowerConstant.CURRENT_UNIT)); + baseModelMap.put(BaseReportKeyEnum.DEV_CURR.getKey(), pqDevVO.getDevCurr().toString().concat(PowerConstant.CURRENT_UNIT)); // 额定电压 - baseModelMap.put(prefix + BaseReportKeyEnum.DEV_VOLT.getKey() + suffix, pqDevVO.getDevVolt().toString().concat(PowerConstant.VOLTAGE_UNIT)); + baseModelMap.put(BaseReportKeyEnum.DEV_VOLT.getKey(), pqDevVO.getDevVolt().toString().concat(PowerConstant.VOLTAGE_UNIT)); // 通道数 - baseModelMap.put(prefix + BaseReportKeyEnum.COUNT.getKey() + suffix, pqDevVO.getDevChns().toString()); + baseModelMap.put(BaseReportKeyEnum.COUNT.getKey(), pqDevVO.getDevChns().toString()); // 制造厂家 DictData dictData = dictDataService.getDictDataById(pqDevVO.getManufacturer()); if (ObjectUtil.isNotNull(dictData)) { - baseModelMap.put(prefix + BaseReportKeyEnum.MANUFACTURER.getKey() + suffix, dictData.getName()); + baseModelMap.put(BaseReportKeyEnum.MANUFACTURER.getKey(), dictData.getName()); } else { - baseModelMap.put(prefix + BaseReportKeyEnum.MANUFACTURER.getKey() + suffix, StrPool.TAB); + baseModelMap.put(BaseReportKeyEnum.MANUFACTURER.getKey(), StrPool.TAB); } // 委托方 String delegate = pqDevVO.getDelegate(); if (StrUtil.isNotBlank(delegate)) { DictData delegateDictData = dictDataService.getDictDataById(pqDevVO.getManufacturer()); if (ObjectUtil.isNotNull(delegateDictData)) { - baseModelMap.put(prefix + BaseReportKeyEnum.DELEGATE.getKey() + suffix, dictData.getName()); + baseModelMap.put(BaseReportKeyEnum.DELEGATE.getKey(), dictData.getName()); } else { - baseModelMap.put(prefix + BaseReportKeyEnum.DELEGATE.getKey() + suffix, StrPool.TAB); + baseModelMap.put(BaseReportKeyEnum.DELEGATE.getKey(), StrPool.TAB); } } else { - baseModelMap.put(prefix + BaseReportKeyEnum.DELEGATE.getKey() + suffix, StrPool.TAB); + baseModelMap.put(BaseReportKeyEnum.DELEGATE.getKey(), StrPool.TAB); } // 实验室温度 - baseModelMap.put(prefix + BaseReportKeyEnum.TEMPERATURE.getKey() + suffix, Objects.isNull(pqDevVO.getTemperature()) ? StrPool.TAB : pqDevVO.getTemperature().toString()); + baseModelMap.put(BaseReportKeyEnum.TEMPERATURE.getKey(), Objects.isNull(pqDevVO.getTemperature()) ? StrPool.TAB : pqDevVO.getTemperature().toString()); // 实验室湿度 - baseModelMap.put(prefix + BaseReportKeyEnum.HUMIDITY.getKey() + suffix, Objects.isNull(pqDevVO.getHumidity()) ? StrPool.TAB : pqDevVO.getHumidity().toString()); + baseModelMap.put(BaseReportKeyEnum.HUMIDITY.getKey(), Objects.isNull(pqDevVO.getHumidity()) ? StrPool.TAB : pqDevVO.getHumidity().toString()); // 样品编号 - baseModelMap.put(prefix + BaseReportKeyEnum.SAMPLE_ID.getKey() + suffix, StrUtil.isEmpty(pqDevVO.getSampleId()) ? StrPool.TAB : pqDevVO.getSampleId()); + baseModelMap.put(BaseReportKeyEnum.SAMPLE_ID.getKey(), StrUtil.isEmpty(pqDevVO.getSampleId()) ? StrPool.TAB : pqDevVO.getSampleId()); // 收样日期 - baseModelMap.put(prefix + BaseReportKeyEnum.ARRIVED_DATE.getKey() + suffix, Objects.isNull(pqDevVO.getArrivedDate()) ? StrPool.TAB : String.valueOf(pqDevVO.getArrivedDate())); + baseModelMap.put(BaseReportKeyEnum.ARRIVED_DATE.getKey(), Objects.isNull(pqDevVO.getArrivedDate()) ? StrPool.TAB : String.valueOf(pqDevVO.getArrivedDate())); // 检测日期 - baseModelMap.put(prefix + BaseReportKeyEnum.TEST_DATE.getKey() + suffix, Objects.isNull(pqDevVO.getCheckTime()) ? StrPool.TAB : String.valueOf(pqDevVO.getCheckTime()).substring(0, 10)); - baseModelMap.put(prefix + BaseReportKeyEnum.TEMPERATURE.getKey() + suffix, Objects.isNull(pqDevVO.getTemperature()) ? StrPool.TAB : pqDevVO.getTemperature().toString()); - baseModelMap.put(prefix + BaseReportKeyEnum.HUMIDITY.getKey() + suffix, Objects.isNull(pqDevVO.getHumidity()) ? StrPool.TAB : pqDevVO.getHumidity().toString()); - baseModelMap.put(prefix + BaseReportKeyEnum.YEAR.getKey() + suffix, DateUtil.format(new Date(), DatePattern.NORM_YEAR_PATTERN)); - baseModelMap.put(prefix + BaseReportKeyEnum.MONTH.getKey() + suffix, DateUtil.format(new Date(), DatePattern.SIMPLE_MONTH_PATTERN).substring(4)); - baseModelMap.put(prefix + BaseReportKeyEnum.DAY.getKey() + suffix, DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN).substring(6)); - baseModelMap.put(prefix + BaseReportKeyEnum.YEAR_MONTH_DAY.getKey() + suffix, DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN)); + baseModelMap.put(BaseReportKeyEnum.TEST_DATE.getKey(), Objects.isNull(pqDevVO.getCheckTime()) ? StrPool.TAB : String.valueOf(pqDevVO.getCheckTime()).substring(0, 10)); + baseModelMap.put(BaseReportKeyEnum.TEMPERATURE.getKey(), Objects.isNull(pqDevVO.getTemperature()) ? StrPool.TAB : pqDevVO.getTemperature().toString()); + baseModelMap.put(BaseReportKeyEnum.HUMIDITY.getKey(), Objects.isNull(pqDevVO.getHumidity()) ? StrPool.TAB : pqDevVO.getHumidity().toString()); + baseModelMap.put(BaseReportKeyEnum.YEAR.getKey(), DateUtil.format(new Date(), DatePattern.NORM_YEAR_PATTERN)); + baseModelMap.put(BaseReportKeyEnum.MONTH.getKey(), DateUtil.format(new Date(), DatePattern.SIMPLE_MONTH_PATTERN).substring(4)); + baseModelMap.put(BaseReportKeyEnum.DAY.getKey(), DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN).substring(6)); + baseModelMap.put(BaseReportKeyEnum.YEAR_MONTH_DAY.getKey(), DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN)); return baseModelMap; } @@ -1468,37 +1449,24 @@ public class PqReportServiceImpl extends ServiceImpl i /** * 获取数据页的信息 * - * @param baseModelDocument 非数据页的内容 - * @param devReportParam 查询参数 + * @param devReportParam 查询参数 */ - private void dealDataModel(XWPFDocument baseModelDocument, DevReportParam devReportParam, PqDevVO pqDevVO) throws IOException { - //AdPlan adPlan = adPlanService.getById(devReportParam.getPlanId()); - //String scriptId = adPlan.getScriptId(); + private void dealDataModel(List wordFileInputStreams, DevReportParam devReportParam, PqDevVO pqDevVO) throws Exception { Integer devChns = pqDevVO.getDevChns(); for (int i = 1; i <= devChns; i++) { ClassPathResource resource = new ClassPathResource("/model/report_table.docx"); - XWPFDocument dataModelDocumentTemp = new XWPFDocument(resource.getInputStream()); - - SingleNonHarmParam singleNonHarmParam = new SingleNonHarmParam(); - singleNonHarmParam.setPlanCode(devReportParam.getPlanCode()); - singleNonHarmParam.setDevId(pqDevVO.getId()); - singleNonHarmParam.setChannelNo(i); - // 获取数据 - Map dataModelMap = new HashMap<>(); - dataModelMap.put("${CreateId}", pqDevVO.getCreateId()); - dataModelMap.put("${total}", pqDevVO.getDevChns().toString()); - dataModelMap.put("${count}", i + ""); - + Map dataModelMap = new HashMap<>(16); // 读取模板文件中的占位符 - List allMarkList = getAllKeys(dataModelDocumentTemp); + Set allMarkList = WordDocumentUtil.extractPlaceholders(resource.getInputStream(), false, Arrays.asList("CreateId", "total", "count")); Map> indexKeysMap = allMarkList.stream() .collect(Collectors.groupingBy( - obj -> obj.split("#")[0].replace("${", ""), + obj -> obj.split("#")[0], Collectors.mapping(obj -> { int index1 = obj.indexOf("#") + 1; return obj.substring(index1, obj.indexOf("#", index1)); - }, Collectors.toSet()))); //key为index,value为该index下所有测试项对应的code + //key为index,value为该index下所有测试项对应的code + }, Collectors.toSet()))); List simAndDigNonHarmonicResultList = adNonHarmonicService.listSimAndDigBaseResult(devReportParam.getScriptId(), devReportParam.getPlanCode(), devReportParam.getDevId() + "_" + i); List adHarmonicResultList = adHarmonicService.listAllResultData(devReportParam.getScriptId(), devReportParam.getPlanCode(), devReportParam.getDevId() + "_" + i); @@ -1518,21 +1486,21 @@ public class PqReportServiceImpl extends ServiceImpl i } } }); - + dataModelMap.put("CreateId", pqDevVO.getCreateId()); + dataModelMap.put("total", pqDevVO.getDevChns().toString()); + dataModelMap.put("count", i + ""); // 替换文档内容 - WordUtil.replacePlaceholdersInParagraphs(dataModelDocumentTemp, dataModelMap); - WordUtil.replacePlaceholdersInTables(dataModelDocumentTemp, dataModelMap); - WordUtil.appendDocument(baseModelDocument, dataModelDocumentTemp); + wordFileInputStreams.add(wordReportService.replacePlaceholders(resource.getInputStream(), dataModelMap)); } } /** * 填充数据(ABC相) * - * @param allNonHarmonicResultList - * @param dataModelMap - * @param keys - * @param index + * @param allNonHarmonicResultList 结果数据 + * @param dataModelMap 替换数据 + * @param keys keys + * @param index index */ private void fillMapValueABC(List allNonHarmonicResultList, Map dataModelMap, Set keys, String index) { keys.forEach(key -> { @@ -1540,9 +1508,9 @@ public class PqReportServiceImpl extends ServiceImpl i if (CollectionUtil.isNotEmpty(resultList)) { SimAndDigNonHarmonicResult adNonHarmonicResult = resultList.get(0); if (ObjectUtil.isNotNull(adNonHarmonicResult)) { - dataModelMap.put("${" + index + "#" + key + "#A}", devValue(adNonHarmonicResult.getAValue(), 1, 1)); - dataModelMap.put("${" + index + "#" + key + "#B}", devValue(adNonHarmonicResult.getBValue(), 1, 1)); - dataModelMap.put("${" + index + "#" + key + "#C}", devValue(adNonHarmonicResult.getCValue(), 1, 1)); + dataModelMap.put(index + "#" + key + "#A", devValue(adNonHarmonicResult.getAValue(), 1, 1)); + dataModelMap.put(index + "#" + key + "#B", devValue(adNonHarmonicResult.getBValue(), 1, 1)); + dataModelMap.put(index + "#" + key + "#C", devValue(adNonHarmonicResult.getCValue(), 1, 1)); } } }); @@ -1551,10 +1519,10 @@ public class PqReportServiceImpl extends ServiceImpl i /** * 填充数据(T相) * - * @param allNonHarmonicResultList - * @param dataModelMap - * @param keys - * @param index + * @param allNonHarmonicResultList 结果数据 + * @param dataModelMap 替换数据 + * @param keys key + * @param index index */ private void fillMapValueT(List allNonHarmonicResultList, Map dataModelMap, Set keys, String index) { keys.forEach(key -> { @@ -1562,7 +1530,7 @@ public class PqReportServiceImpl extends ServiceImpl i if (CollectionUtil.isNotEmpty(resultList)) { SimAndDigNonHarmonicResult adNonHarmonicResult = resultList.get(0); if (ObjectUtil.isNotNull(adNonHarmonicResult)) { - dataModelMap.put("${" + index + "#" + key + "#T}", devValue(adNonHarmonicResult.getTValue(), 1, 1)); + dataModelMap.put(index + "#" + key + "#T", devValue(adNonHarmonicResult.getTValue(), 1, 1)); } } }); @@ -1571,10 +1539,10 @@ public class PqReportServiceImpl extends ServiceImpl i /** * 填充数据(谐波类) * - * @param allHarmonicResultList - * @param dataModelMap - * @param keys - * @param index + * @param allHarmonicResultList 结果数据 + * @param dataModelMap 替换数据 + * @param keys key + * @param index index */ private void fillMapValueHarm(List allHarmonicResultList, Map dataModelMap, Set keys, String index) { keys.forEach(key -> { @@ -1609,9 +1577,9 @@ public class PqReportServiceImpl extends ServiceImpl i String aBase = devValue(adHarmonicResult.getAValue1(), 1, 1); String bBase = devValue(adHarmonicResult.getBValue1(), 1, 1); String cBase = devValue(adHarmonicResult.getCValue1(), 1, 1); - dataModelMap.put("${" + index + "#" + key + "#A#1}", aBase); - dataModelMap.put("${" + index + "#" + key + "#B#1}", bBase); - dataModelMap.put("${" + index + "#" + key + "#C#1}", cBase); + dataModelMap.put(index + "#" + key + "#A#1", aBase); + dataModelMap.put(index + "#" + key + "#B#1", bBase); + dataModelMap.put(index + "#" + key + "#C#1", cBase); // 基波 double aBaseValue = baseValue; @@ -1629,71 +1597,39 @@ public class PqReportServiceImpl extends ServiceImpl i } } - dataModelMap.put("${" + index + "#" + key + "#A#2}", devValue(adHarmonicResult.getAValue2(), aBaseValue, percent)); - dataModelMap.put("${" + index + "#" + key + "#B#2}", devValue(adHarmonicResult.getBValue2(), bBaseValue, percent)); - dataModelMap.put("${" + index + "#" + key + "#C#2}", devValue(adHarmonicResult.getCValue2(), cBaseValue, percent)); + dataModelMap.put(index + "#" + key + "#A#2", devValue(adHarmonicResult.getAValue2(), aBaseValue, percent)); + dataModelMap.put(index + "#" + key + "#B#2", devValue(adHarmonicResult.getBValue2(), bBaseValue, percent)); + dataModelMap.put(index + "#" + key + "#C#2", devValue(adHarmonicResult.getCValue2(), cBaseValue, percent)); - dataModelMap.put("${" + index + "#" + key + "#A#5}", devValue(adHarmonicResult.getAValue5(), aBaseValue, percent)); - dataModelMap.put("${" + index + "#" + key + "#B#5}", devValue(adHarmonicResult.getBValue5(), bBaseValue, percent)); - dataModelMap.put("${" + index + "#" + key + "#C#5}", devValue(adHarmonicResult.getCValue5(), cBaseValue, percent)); + dataModelMap.put(index + "#" + key + "#A#5", devValue(adHarmonicResult.getAValue5(), aBaseValue, percent)); + dataModelMap.put(index + "#" + key + "#B#5", devValue(adHarmonicResult.getBValue5(), bBaseValue, percent)); + dataModelMap.put(index + "#" + key + "#C#5", devValue(adHarmonicResult.getCValue5(), cBaseValue, percent)); - dataModelMap.put("${" + index + "#" + key + "#A#7}", devValue(adHarmonicResult.getAValue7(), aBaseValue, percent)); - dataModelMap.put("${" + index + "#" + key + "#B#7}", devValue(adHarmonicResult.getBValue7(), bBaseValue, percent)); - dataModelMap.put("${" + index + "#" + key + "#C#7}", devValue(adHarmonicResult.getCValue7(), cBaseValue, percent)); + dataModelMap.put(index + "#" + key + "#A#7", devValue(adHarmonicResult.getAValue7(), aBaseValue, percent)); + dataModelMap.put(index + "#" + key + "#B#7", devValue(adHarmonicResult.getBValue7(), bBaseValue, percent)); + dataModelMap.put(index + "#" + key + "#C#7", devValue(adHarmonicResult.getCValue7(), cBaseValue, percent)); - dataModelMap.put("${" + index + "#" + key + "#A#11}", devValue(adHarmonicResult.getAValue11(), aBaseValue, percent)); - dataModelMap.put("${" + index + "#" + key + "#B#11}", devValue(adHarmonicResult.getBValue11(), bBaseValue, percent)); - dataModelMap.put("${" + index + "#" + key + "#C#11}", devValue(adHarmonicResult.getCValue11(), cBaseValue, percent)); + dataModelMap.put(index + "#" + key + "#A#11", devValue(adHarmonicResult.getAValue11(), aBaseValue, percent)); + dataModelMap.put(index + "#" + key + "#B#11", devValue(adHarmonicResult.getBValue11(), bBaseValue, percent)); + dataModelMap.put(index + "#" + key + "#C#11", devValue(adHarmonicResult.getCValue11(), cBaseValue, percent)); - dataModelMap.put("${" + index + "#" + key + "#A#23}", devValue(adHarmonicResult.getAValue23(), aBaseValue, percent)); - dataModelMap.put("${" + index + "#" + key + "#B#23}", devValue(adHarmonicResult.getBValue23(), bBaseValue, percent)); - dataModelMap.put("${" + index + "#" + key + "#C#23}", devValue(adHarmonicResult.getCValue23(), cBaseValue, percent)); + dataModelMap.put(index + "#" + key + "#A#23", devValue(adHarmonicResult.getAValue23(), aBaseValue, percent)); + dataModelMap.put(index + "#" + key + "#B#23", devValue(adHarmonicResult.getBValue23(), bBaseValue, percent)); + dataModelMap.put(index + "#" + key + "#C#23", devValue(adHarmonicResult.getCValue23(), cBaseValue, percent)); - dataModelMap.put("${" + index + "#" + key + "#A#35}", devValue(adHarmonicResult.getAValue35(), aBaseValue, percent)); - dataModelMap.put("${" + index + "#" + key + "#B#35}", devValue(adHarmonicResult.getBValue35(), bBaseValue, percent)); - dataModelMap.put("${" + index + "#" + key + "#C#35}", devValue(adHarmonicResult.getCValue35(), cBaseValue, percent)); + dataModelMap.put(index + "#" + key + "#A#35", devValue(adHarmonicResult.getAValue35(), aBaseValue, percent)); + dataModelMap.put(index + "#" + key + "#B#35", devValue(adHarmonicResult.getBValue35(), bBaseValue, percent)); + dataModelMap.put(index + "#" + key + "#C#35", devValue(adHarmonicResult.getCValue35(), cBaseValue, percent)); - dataModelMap.put("${" + index + "#" + key + "#A#43}", devValue(adHarmonicResult.getAValue43(), aBaseValue, percent)); - dataModelMap.put("${" + index + "#" + key + "#B#43}", devValue(adHarmonicResult.getBValue43(), bBaseValue, percent)); - dataModelMap.put("${" + index + "#" + key + "#C#43}", devValue(adHarmonicResult.getCValue43(), cBaseValue, percent)); + dataModelMap.put(index + "#" + key + "#A#43", devValue(adHarmonicResult.getAValue43(), aBaseValue, percent)); + dataModelMap.put(index + "#" + key + "#B#43", devValue(adHarmonicResult.getBValue43(), bBaseValue, percent)); + dataModelMap.put(index + "#" + key + "#C#43", devValue(adHarmonicResult.getCValue43(), cBaseValue, percent)); - dataModelMap.put("${" + index + "#" + key + "#A#50}", devValue(adHarmonicResult.getAValue50(), aBaseValue, percent)); - dataModelMap.put("${" + index + "#" + key + "#B#50}", devValue(adHarmonicResult.getBValue50(), bBaseValue, percent)); - dataModelMap.put("${" + index + "#" + key + "#C#50}", devValue(adHarmonicResult.getCValue50(), cBaseValue, percent)); + dataModelMap.put(index + "#" + key + "#A#50", devValue(adHarmonicResult.getAValue50(), aBaseValue, percent)); + dataModelMap.put(index + "#" + key + "#B#50", devValue(adHarmonicResult.getBValue50(), bBaseValue, percent)); + dataModelMap.put(index + "#" + key + "#C#50", devValue(adHarmonicResult.getCValue50(), cBaseValue, percent)); } - /** - * 获取文件所有表格中的占位符 - * - * @param dataModelDocumentTemp - * @return - */ - private List getAllKeys(XWPFDocument dataModelDocumentTemp) { - List allMarkList = new ArrayList<>(); - List tables = dataModelDocumentTemp.getTables(); - - for (XWPFTable table : tables) { - List rows = table.getRows(); - for (XWPFTableRow row : rows) { - List cells = row.getTableCells(); - for (XWPFTableCell cell : cells) { - List paragraphs = cell.getParagraphs(); - for (XWPFParagraph paragraph : paragraphs) { - List runs = paragraph.getRuns(); - for (XWPFRun run : runs) { - String text = run.getText(0); - if (StrUtil.isNotBlank(text) && text.startsWith("$")) { - allMarkList.add(text); - } - } - } - } - } - } - return allMarkList.stream().sorted(Comparator.comparing(String::toString)).collect(Collectors.toList()); - } - - private String devValue(String dataJson, double baseValue, Integer percent) { DetectionData tempA = JSONUtil.toBean(dataJson, DetectionData.class); if (Objects.nonNull(tempA) && Objects.nonNull(tempA.getData())) { @@ -1752,21 +1688,16 @@ public class PqReportServiceImpl extends ServiceImpl i @Override public void uploadReportToCloud(List deviceIds) { log.info("开始批量上传检测报告到云端,设备ID列表:{}", deviceIds); - - List deviceSubs = iPqDevSubService.lambdaQuery() .eq(PqDevSub::getReportState, DevReportStateEnum.GENERATED.getValue()) - .in(CollUtil.isNotEmpty(deviceIds),PqDevSub::getDevId, deviceIds).list(); + .in(CollUtil.isNotEmpty(deviceIds), PqDevSub::getDevId, deviceIds).list(); List devIds = deviceSubs.stream().map(PqDevSub::getDevId).collect(Collectors.toList()); - List devices = iPqDevService.lambdaQuery() - .in(CollUtil.isNotEmpty(devIds), PqDev::getId, devIds).list(); - + .in(CollUtil.isNotEmpty(devIds), PqDev::getId, devIds).list(); if (CollUtil.isEmpty(devices)) { log.warn("未找到符合条件的设备,无需上传"); return; } - log.info("找到{}台设备需要上传报告", devices.size()); String dirPath = reportPath; // 确保目录存在 @@ -1776,8 +1707,8 @@ public class PqReportServiceImpl extends ServiceImpl i for (PqDev device : devices) { try { // 构建报告文件路径 - String fileName = device.getCreateId() + ".docx"; - String reportFullPath = dirPath.concat(File.separator).concat(device.getCreateId()).concat(".docx"); + String fileName = device.getCreateId() + ReportConstant.DOCX; + String reportFullPath = dirPath.concat(File.separator).concat(device.getCreateId()).concat(ReportConstant.DOCX); File reportFile = new File(reportFullPath); if (!reportFile.exists()) { diff --git a/detection/src/main/java/com/njcn/gather/report/utils/BookmarkUtil.java b/detection/src/main/java/com/njcn/gather/report/utils/BookmarkUtil.java deleted file mode 100644 index 1cd1018c..00000000 --- a/detection/src/main/java/com/njcn/gather/report/utils/BookmarkUtil.java +++ /dev/null @@ -1,295 +0,0 @@ -package com.njcn.gather.report.utils; - - -import com.njcn.gather.report.pojo.enums.BookmarkEnum; -import com.njcn.gather.report.pojo.enums.PowerIndexEnum; -import org.docx4j.openpackaging.packages.WordprocessingMLPackage; -import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart; -import org.docx4j.wml.*; - -import javax.xml.bind.JAXBElement; -import java.util.*; - - -/** - * 递归查找所有书签,并在书签处插入内容 - */ -public class BookmarkUtil { - - - /** - * 书签信息 - */ - public static class BookmarkInfo { - public CTBookmark bookmark; - public P parentParagraph; - public ContentAccessor parentContainer; - } - - /** - * 递归查找所有书签 - */ - public static List findAllBookmarks(ContentAccessor contentAccessor) { - List result = new ArrayList<>(); - for (Object obj : contentAccessor.getContent()) { - Object realObj = (obj instanceof JAXBElement) ? ((JAXBElement>) obj).getValue() : obj; - if (realObj instanceof P) { - P p = (P) realObj; - for (Object o2 : p.getContent()) { - Object realO2 = (o2 instanceof JAXBElement) ? ((JAXBElement>) o2).getValue() : o2; - if (realO2 instanceof CTBookmark) { - BookmarkInfo info = new BookmarkInfo(); - info.bookmark = (CTBookmark) realO2; - info.parentParagraph = p; - info.parentContainer = contentAccessor; - result.add(info); - } - } - } else if (realObj instanceof ContentAccessor) { - result.addAll(findAllBookmarks((ContentAccessor) realObj)); - } - } - return result; - } - - - /** - * 在书签后插入段落 - */ - public static void insertParagraphsAfter(BookmarkInfo info, P paragraph) { - List parentContent = info.parentContainer.getContent(); - int idx = parentContent.indexOf(info.parentParagraph); - parentContent.add(idx + 1, paragraph); - } - - /** - * 在书签后插入表格 - */ - public static void insertTableAfter(BookmarkInfo info, Tbl table) { - List parentContent = info.parentContainer.getContent(); - int idx = parentContent.indexOf(info.parentParagraph); - parentContent.add(idx + 1, table); - } - - /** - * 在书签后插入元素,可能是段落、表格、图片、书签等 - */ - public static void insertElement(BookmarkInfo info, List elements) { - List parentContent = info.parentContainer.getContent(); - int idx = parentContent.indexOf(info.parentParagraph); - // 遍历元素,如果是通道回路这种大标题需要新起一个空的文档页 - for (int i = 0; i < elements.size(); i++) { - Object element = elements.get(i); - if (element instanceof P) { - P p = (P) element; - String textFromP = Docx4jUtil.getTextFromP(p); - if (textFromP.contains("测量回路")) { - if (!textFromP.contains("1")) { - // 另起一页 - P pagePara = Docx4jUtil.getPageBreak(); - idx = idx + 1; - parentContent.add(idx, pagePara); - } - idx = idx + 1; - parentContent.add(idx, p); - } - else if (textFromP.startsWith(PowerIndexEnum.IMBV.getDesc()) - || textFromP.startsWith(PowerIndexEnum.HV.getDesc()) - || textFromP.startsWith(PowerIndexEnum.HI.getDesc()) - - ) { - // 另起一页 - P pagePara = Docx4jUtil.getPageBreak(); - idx = idx + 1; - parentContent.add(idx, pagePara); - idx = idx + 1; - parentContent.add(idx, element); - }else if(textFromP.startsWith("注:基波电流幅值5.000A,基波频率50.0Hz,各次间谐波电流含有率均为3.0%。")){ - idx = idx + 1; - parentContent.add(idx, element); - P pagePara = Docx4jUtil.getPageBreak(); - idx = idx + 1; - parentContent.add(idx, pagePara); - } - else { - idx = idx + 1; - parentContent.add(idx, element); - } - } else { - idx = idx + 1; - parentContent.add(idx, element); - } - } - } - - /** - * 删除文档中的空白页 - * @param docx 要处理的Word文档 - */ - public static void removeBlankPages(MainDocumentPart mainDocumentPart) { - // 获取文档主体 - Document document = mainDocumentPart.getJaxbElement(); - Body body = document.getBody(); - - // 获取所有段落 - List paragraphs = body.getContent(); - - // 用于标记是否在空白页中 - boolean inBlankPage = false; - // 用于存储要删除的段落 - List paragraphsToRemove = new ArrayList<>(); - - for (Object paragraph : paragraphs) { - if (paragraph instanceof P){ - P paragraphtemp = (P) paragraph; - // 检查段落是否为空 - boolean isEmpty = isParagraphEmpty(paragraphtemp); - - if (isEmpty) { - if (!inBlankPage) { - inBlankPage = true; - } - paragraphsToRemove.add(paragraphtemp); - } else { - inBlankPage = false; - } - } - } - - // 删除空白段落 - for (P paragraph : paragraphsToRemove) { - body.getContent().remove(paragraph); - } - } - - /** - * 检查段落是否为空 - * @param paragraph 要检查的段落 - * @return 如果段落为空返回true,否则返回false - */ - private static boolean isParagraphEmpty(P paragraph) { - // 检查段落是否包含分节符 - if (paragraph.getPPr() != null && paragraph.getPPr().getSectPr() != null) { - return false; - } - - // 检查段落中的文本内容 - for (Object obj : paragraph.getContent()) { - if (obj instanceof R) { - R run = (R) obj; - // 在3.3.4版本中,使用getContent()获取文本内容 - for (Object runContent : run.getContent()) { - if (runContent instanceof Text) { - Text text = (Text) runContent; - if (text.getValue() != null && !text.getValue().trim().isEmpty()) { - return false; - } - } - } - } - } - return true; - } - - - /** - * 在插入前检查目标位置是否有分页符 - * - * @param position 目标位置 - * @return 是否包含分页符 - */ - private static boolean hasPageBreak(Object position) { - if (position instanceof P) { - P paragraph = (P) position; - for (Object run : paragraph.getContent()) { - if (run instanceof R) { - R r = (R) run; - for (Object element : r.getContent()) { - if (element instanceof Br && ((Br) element).getType() != null - && ((Br) element).getType().equals("page")) { - return true; - } - } - } - } - return false; - } - return false; - } - - /** - * 删除书签 - * - * @param bookmarkInfo 书签信息 - */ - public static void removeBookmark(BookmarkUtil.BookmarkInfo bookmarkInfo) { - try { - // 获取书签所在的段落 - P paragraph = bookmarkInfo.parentParagraph; - - // 遍历段落内容,找到并删除书签开始和结束标记 - List paragraphContent = new ArrayList<>(paragraph.getContent()); - for (Object obj : paragraphContent) { - if (obj instanceof JAXBElement) { - JAXBElement> element = (JAXBElement>) obj; - Object value = element.getValue(); - - // 删除书签开始标记 - if (value instanceof CTBookmark) { - paragraph.getContent().remove(obj); - } - // 删除书签结束标记 - else if (value instanceof CTMarkupRange) { - paragraph.getContent().remove(obj); - } - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - /** - * 使用 ObjectFactory 创建表格 - * - * @param factory ObjectFactory 实例 - * @param data 二维数组,表格内容 - * @return Tbl 表格对象 - */ - public static Tbl createTable(ObjectFactory factory, String[][] data) { - Tbl table = factory.createTbl(); - for (String[] rowData : data) { - Tr row = factory.createTr(); - for (String cellData : rowData) { - Tc cell = factory.createTc(); - P para = factory.createP(); - R run = factory.createR(); - Text text = factory.createText(); - text.setValue(cellData); - run.getContent().add(text); - para.getContent().add(run); - cell.getContent().add(para); - row.getContent().add(cell); - } - table.getContent().add(row); - } - return table; - } - - /** - * 获取指定标签的标签信息 - * - * @param key 标签名 - * @param bookmarks 所有标签信息 - */ - public static BookmarkInfo getBookmarkInfo(String key, List bookmarks) { - BookmarkUtil.BookmarkInfo bookmarkInfo = null; - for (BookmarkUtil.BookmarkInfo info : bookmarks) { - String name = info.bookmark.getName(); - if (key.equalsIgnoreCase(name)) { - bookmarkInfo = info; - } - } - return bookmarkInfo; - } -} \ No newline at end of file diff --git a/detection/src/main/java/com/njcn/gather/report/utils/Docx4jInsertParagraph.java b/detection/src/main/java/com/njcn/gather/report/utils/Docx4jInsertParagraph.java deleted file mode 100644 index fdc8cc5c..00000000 --- a/detection/src/main/java/com/njcn/gather/report/utils/Docx4jInsertParagraph.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.njcn.gather.report.utils; - -/** - * @author hongawen - * @version 1.0 - * @data 2025/3/25 19:37 - */ -import org.docx4j.openpackaging.packages.WordprocessingMLPackage; -import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart; -import org.docx4j.wml.*; - -import java.io.File; -import java.math.BigInteger; -import java.util.List; - -public class Docx4jInsertParagraph { - public static void main(String[] args) throws Exception { - // 加载现有的 Word 文档 - WordprocessingMLPackage wordPackage = WordprocessingMLPackage.load(new File("C:\\Users\\hongawen\\Desktop\\base_template.docx")); - MainDocumentPart documentPart = wordPackage.getMainDocumentPart(); - - // 获取文档中的所有段落 - List paragraphs = documentPart.getContent(); - - // 在中间插入一个新段落 - int insertIndex = paragraphs.size() / 2; - P newParagraph = createParagraph("This is a new paragraph inserted in the middle."); - paragraphs.add(insertIndex, newParagraph); - - // 保存修改后的文档 - wordPackage.save(new File("example_modified.docx")); - } - - private static P createParagraph(String text) { - ObjectFactory factory = new ObjectFactory(); - P paragraph = factory.createP(); - R run = factory.createR(); - Text t = factory.createText(); - t.setValue(text); - run.getContent().add(t); - paragraph.getContent().add(run); - return paragraph; - } -} \ No newline at end of file diff --git a/detection/src/main/java/com/njcn/gather/report/utils/WordUtil.java b/detection/src/main/java/com/njcn/gather/report/utils/WordUtil.java deleted file mode 100644 index 450add31..00000000 --- a/detection/src/main/java/com/njcn/gather/report/utils/WordUtil.java +++ /dev/null @@ -1,144 +0,0 @@ -package com.njcn.gather.report.utils; - -import org.apache.poi.xwpf.usermodel.*; -import org.apache.xmlbeans.XmlCursor; -import org.docx4j.openpackaging.packages.WordprocessingMLPackage; -import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * @author hongawen - * @version 1.0 - * @data 2025/1/9 20:52 - */ -public class WordUtil { - - - /** - * 将源文档的内容(包括段落、表格等)追加到目标文档中 - * - * @param target 目标文档 - * @param source 源文档 - */ - public static void appendDocument(XWPFDocument target, XWPFDocument source) { - // 在追加内容之前,插入分页符 -// insertPageBreak(target); - // 遍历源文档的所有块(段落、表格等) - source.getBodyElements().forEach(bodyElement -> { - switch (bodyElement.getElementType()) { - case PARAGRAPH: - // 处理段落 - XWPFParagraph sourceParagraph = (XWPFParagraph) bodyElement; - XWPFParagraph newParagraph = target.createParagraph(); - newParagraph.getCTP().set(sourceParagraph.getCTP()); - break; - case TABLE: - // 处理表格 - XWPFTable sourceTable = (XWPFTable) bodyElement; - XWPFTable newTable = target.createTable(); - newTable.getCTTbl().set(sourceTable.getCTTbl()); - break; - default: - // 针对其他类型(如图片、页眉页脚等)可以扩展处理逻辑 - System.out.println("未处理的内容类型:" + bodyElement.getElementType()); - break; - } - }); - } - - - /** - * 替换表格中的占位符 - * @param document 文档 - * @param placeholders 待替换的占位符 - */ - public static void replacePlaceholdersInTables(XWPFDocument document, Map placeholders) { - for (XWPFTable table : document.getTables()) { - for (XWPFTableRow row : table.getRows()) { - for (XWPFTableCell cell : row.getTableCells()) { - for (XWPFParagraph paragraph : cell.getParagraphs()) { - List runs = paragraph.getRuns(); - if (runs != null) { - for (XWPFRun run : runs) { - String text = run.getText(0); - if (text != null) { - for (Map.Entry entry : placeholders.entrySet()) { - text = text.replace(entry.getKey(), entry.getValue()); - } - run.setText(text, 0); - } - } - } - } - } - } - } - } - - - /** - * 替换段落中的占位符 - * @param document 文档 - * @param placeholders 待替换的占位符 - */ - public static void replacePlaceholdersInParagraphs(XWPFDocument document, Map placeholders) { - for (XWPFParagraph paragraph : document.getParagraphs()) { - List runs = paragraph.getRuns(); - if (runs != null) { - for (XWPFRun run : runs) { - String text = run.getText(0); - if (text != null) { - for (Map.Entry entry : placeholders.entrySet()) { - text = text.replace(entry.getKey(), entry.getValue()); - } - run.setText(text, 0); - } - } - } - } - } - - /** - * 替换文档中的占位符 - * @param document 文档 - * @param placeholders 待替换的占位符 - */ - public static void replacePlaceholders(XWPFDocument document, Map placeholders) { - replacePlaceholdersInParagraphs(document,placeholders); - replacePlaceholdersInTables(document,placeholders); - } - - - public static List findHeadingLevel5Paragraphs(XWPFDocument document) { - List headingLevel5Paragraphs = new ArrayList<>(); - for (XWPFParagraph paragraph : document.getParagraphs()) { - String style = paragraph.getStyle(); - if ("5".equals(style)) { - headingLevel5Paragraphs.add(paragraph); - } - } - return headingLevel5Paragraphs; - } - - - /** - * 获取段落的位置(通过遍历bodyElements) - */ - public static int getBodyElementPosition(XWPFDocument document, XWPFParagraph paragraph) { - List bodyElements = document.getBodyElements(); - for (int i = 0; i < bodyElements.size(); i++) { - if (bodyElements.get(i) instanceof XWPFParagraph && bodyElements.get(i).equals(paragraph)) { - return i; - } - } - return -1; - } - - - -} diff --git a/entrance/src/main/resources/model/report_table.docx b/entrance/src/main/resources/model/report_table.docx index ded22ce67a26289d7f3a62c9c29358848735e73e..f6d53866d1a93774af8bbdd926c017df7276e4e4 100644 GIT binary patch delta 19381 zcmYJaWmH{Vuq+C}-Q5Gh-Q9z`yE_|qT_L!;TX5L8yF&=UJ-EAT@Laxg-o5Yd+GDIS zcg^lz)m_zjE08rSkO^D}9$gcBc90Mdeu=_gfJk|{=oYCj(^%i-Q0^iatyguZS}Z#? zU;K!p#M@j~GwY>yNe164?29P%Xqxqge6ofy=nL#C9-<$s^}aOny5?18wd!qu7A}gu zT)xMts^+%omc)ZW+Q)U-?QW+Wii8!om?f|Lan^L+hBkc>xp7|HC(VRPLa%I-rihRy z2!IJshmgarhp#V={@Lr<&m6j4E-Z)iA=95Jj0rWQ3oB(Wu6T*U;x78f$L)(ULxGyB zNf@X($kQ=?hv_r>|G_SLy2Jey@y)v8`II1G4EvRFQ{OSmxr2uUU1R08C5fcLpA-`r zp8I>NPS`wXL_b_KFmmJHTz96N$b-}44Dc_h=$rm=cI@_N$-<{9d}$KdI?mG6?=RDW zt2I0`r(ObNe2RlSGIUHwujZ*Dibv-XnbXHz3XarYa~W^HQ|qeY@+>os*|bBmdwy5B zgdOge1FTFb%<;L|QpS5AROF$cu^}KJ;32}5c0?79*UYRxfDicu0fF)H)WXReP;qr~ zc4IMja(c60?oLch#wHxa|Y$QagH=aSI{t%>ch4b zID0lIs3_5c!7-UBwn$4_M0G~r03`Y(S2_;9EI%i;7?SMZVrDQg7_)3e?xb>dvaaAP zaT0lX~My18p<~gdyLIT32PC3Rr4KMKvT~ zRNg_V-A&SvLtI@fE~jNh3_Xt6RYT9Y({DJ4X5+E=AFeKfYm0hz;bqJPm4Db@tqHEm z&sUW9Nu2jTtcw_BKzJSXBwJepVZtG_QlpF+Rw6+Qx#<{nD@oZWJf|i7TGEBPl=fhh zRM>#o-BLdlJtg$Jg!96n_H76XG?)V57B_4%dQfC#YZHX{yR&ruFj%dfS@|vvlcLf~ ztEm^)OMAk!2M^@a9PsA`nc4fHZQpC+vtfUi4spv1$z*itXf*QS%dn~L-kG}VIcC%G zlCd^u^ng{_E1-ua-pAMEo<8bbzI|K1-KW84>C;Hi;Y%Y1X-6Xkafi!}wQd@ATq$J? z%O}CNgF+DmzC&$q-}zCN#%pL4WQ0rYQePSv2#BwZa2S4&kPnT)m~NkdtKIVr7t^~q zrfZLLlTCS5e8R4u!asTMT!WP&*i$a0Igk7ZQ9BHYj$uxdb(DO4Yga0yON*H#6}8ZO zVW7xX%F&f&CvXGBOs{5_awLoy$M1d3ex-3LqPp3e#>mdn#1<#~yl>*n`kyRMYvF`6X%p$wxX$!9l~3=AsBt`CiXtQKO_@ggXJrZXj~m8i1@0*h!s)Fu59NA%oy8z2bdhK?x17_) zK7rBV_ZdM&d>=jfX8iuI>mOS3H8f!|swG0B39bk%@U46II#Lt@qKy>hf9jT(ldA>G zNAdD-uyl0)uWX$M7$)y(`ECS&Z^%l0xivfSC?Vl^A2U`Q@r1oPeyh>h-5 zy8Bqnw_|L$F}Ai4-wIINH^3gOAlXUm@~@m%$=Dt*9&1GU>#iR zooG1QXlcB&ywCcwHjxTudF_5>;PHWdFZP0pH}f0_ozq;4x!wCQX6j1z=QdYp;f5eP zr_MX0t5fyfkB7c{1bJ@@-hXNN@m1pC7BR3| zr0Yb{cjPb}PIATp6O8-s*Mb1nLnN@&>vemj>*Vb{4QGs}h`M3Xn@a^aDH&Th4T!zQ z9wRyFy{=~;mu*}7$^~xRAtyTvMlECD1*`gdqu-a-bCBF6CFfqNKa31sQwfv}{FC2! zC(nwx*=#hn1Wpc2{qLTqfcpjD@um`ZeyRQUC|wIYTh|8Ok7|qjd%RE254c}GWa)h! zT>_rSdY`jK17O@Y^c+R?2cSz$$yO#_2cm@3uC+@JPurTYHvK2bbZw+{p7e z%})&8Bxm<}jK=!D4FdsBMZo(T9-!GKf5m#32UIFMT^Bl%8d?9%a7Y*|ze`xwdUEz% zI32|7&61q6xnbnz?VwqP*%TyxkWy}B!Hgx%$s_Ko1XYlc0$pw1Tiu4wcG8=Vc|4K6 zF7E#C(n$gN?Ip8kkU6m=-ylKwmnh6d$K9<(*?yOC zEPh3M<&E=hfF+H*|MJ?BpzqW5Kcfe9?f|;;KVqKxhh)M0e#mdpGhQ#dr>ZAy4a!rb z-?KJ$amd75CesCB+OC(&P|=J6A4V^GUfq|IE4oMuwQ%EiH=HXXJ$8?A*KSH#d^Wgy zo)7=szp%XDo&t~ITufB@kPbCikRuEivobSju!mD~z}K#=$zMu(m|mm;4zhGVnF{h2 zJqhZHzoP`Dx=0e{qhwBnk|CUg0ocen)ME&NZ^GWQ*@IB}+U@4?B3))Lr?=QjQxGSD zDdB?#5KW>%S0e0_rVfbhTPegrWTbaByKMTqb9mu!{Qsmsb*sG!#N^ej=U$FflKOGS zQEXrc0a?2aGr@30$6JEFO&iHjj1|4tKgCb`EyggPt>^{EAuv101uaJH-&W~F0 zFV7hwblxk(a;c;q&x~7!nvk#z0=hleH!p^6{+`nIN(lyDfo!8={w{&m?7Y_Y$8@iE zKP4VdoeA}oyN$M6!FH>o=?rgr%6OXBOOnbuU|eH@aO z%W4B}Xjnv^clP7o=d^oYSy+HuuiC)(nabYxuQ15_(R?mssY)T2dvy(RM#Uzyk*nS7 zJK(DBki}ySOn>Sf2KG&nKk5htE>R8Agc)e*x9SJ@plh^Aywu zz8sIm1CX6@5xF+7)pc07&AA5muIOn$v)W$9o$cN(iug(q8d$QFdBzVHj9(w_H{W5$ z53}QYznF-{;PuB!fr@6{RO*3LaduIUwJ=@>Bg@eJ7B%#hMXB58vfi-rgTKbFqrLv` zAK9bPr={@|x3C_b0IA-<&;<&sHPsQsa0<%`jqlEhL!mw+!~!2_^`pXlP-79%B%`?L z(6iy!C0EQ{#kl|^3dT20>c)O>6635BF1RjSWV`sLn7k@0!Ta=B>pMWMqGKs1f(K_H-FMP?h( zfAc0TrO6{rYPdeB3VFI)D|HRwI?~*B`!!4Kgjzm09g0u%Oe5RAkE&%Z4?eW0WyDKM zX9)Gz?59PG=eP^C&03&^+EaN}k|L$@FiNrScZ+zi+U@nfx8#2nuh9w2-9FtY)$~lg zoXB6V1)KXx7Z92_81}Mid1vvT60rkwA7+yZhxI6#uE_-H8G&WB651TcU0EH)h8;v8gHH^GUYWmsGW zMhhKgAx^25jW6t%yf6hP=?tU#KUH5R(3xnOiNRSx7uhhLpr7t0phcxzNqstcaDxaA{ZZ8UKMM5|bZ6^3R-eZH=Ta^CdH*VmE8tOi;}#Wcg1fmylHfQW(l)gsoG zhR15!1>mHQ$sTAqbYVxfluMzTQ=3?@EBjLWPck#fD{}|Y-z9px77XriH@rPh+S52_ zC^o6tBDy;Lp5G-w^b*NlB14JPgL~sE0(oVME(7h3T?L)Od)BR4DkzbOxq?|dDyLuF z=w%>56Nr);T~KFG;QU!#SOtMTb^7XV(NlhvlW};~K>%nX0;%Uh2rdvJ+)YoW{%+JO znf=2M8A6xJOrPosa*}N33~%GoeU9nti8fyuwKm{oRrlQ5XktN~OX;C1SCKSd$~d%nmI{1#ZDyI3bH=;u%Aj@_ZxI#TxN(-((M=`G0W#slDA0g8E(OdDGaJLAbaB5!ZK@HeAm`* zT%2R@3bl2q?%#Pu+g-VTdXls!MW<_OwgRv&Okdm)8O#^op`i>2^oBO69o&Kp|3p&Et(P}VI9qPZEBgNB%&wgo&$N`KF-E{JMSSg24G6Bf5wx0rQ=9Rs>_ zFfAH<()x-0T8k(~DxLbQS7BH3G*R1xumiPmeYMTs@idNbeO6073kT9Zo$I3qc$lx* zG_r;Yy~-gdqI_CF!hUa36_-FjSxx4q4A6q_$1|*dWoz5PltwY(T``bimb0m5iG^Wh znD~ue{#cZPpXb0`Uec%Iu3vxTumh~HDXE^xt6^c_x8Qcbpa~{}*@`r3V$@Ey(1)eW z2!18g4Pj3+M^RMu;aaMxqmdN-EI+_GQ~E{{hWnGu;DMTK98Fc>%4!z#ur1J^$RFgC zq>%bD!Yg&XeP_4$WZvmn-Zo!{qn(Y$VwJsG^JjaFQ$3?dC;z-#`&J>|B>^ZD^pxRL zug6*KT1REGSk?Lk`-5ic2oq^ah0|b5cTp;7o=4EQ+0K=MO)!~3P<;u0N=4p)s&0v! zEEa#h*fCh{mKn}$?c5?rN9cXENNnZgJP2Q3A8X^AyX&RY0+~@skv#$%Q#dWHX4(#K z)x)4&Z$QlhWfo>f39eD@A5Nfe#?(!%fcT+#JAB74?GT?gO=8EQPrpR2K$S%2Z7GmZ zL43jGQyH}-y18k)nJKeol=4YmhiH9=C`R+_{n|8*K#kU{uGj4DGlnDmxas?c*SWj5!~$A%CG)km@JcgULj)76dd%KnhTy7BH7= zoYTwF?8IeN1+_<(vdY)zRj*WLmj2K}%%o_cSr_$F8`c(cwPl||T#%!imn(orS@``x z$w^2^df!Ay6^W5$fI+CuFigpb&B#NcGeG-Qg!Un2wL7M{-DhP)o_vdRVonKW%#yrL zsZImR%oex*p_o>OIucma(O>q3TrVs$uJ~Saa9N;;93}uYZV9R$hmH0D~)(23}XBje*jzc=NoeEdWr zfmU9UnB~HRUp$Ia?6R!JE3=BQ;3@>ACzz%F>&XTIa&a1&k;7fEVXneHfdUC3);8Bt z2tFkKTyZd4qXjU4g<4(#gBv-aHfM5J`x*XV;_44v6oU97OI@5WYZFPjkE*I!`1?-GSo)i&$_4+-aIgqWj^+cDELIB%FE zhAhEo)VPakj{UEcsm+ecG{LvYl}0_~3?6>#p_Y;!Z0VxG($G|8`G% zU-6}GCxG2Pr+1=6*|edCN;|nR&$K8fKTGTA_aM`=cm9~%g5?6!XRZlsXX9jtU#{#x z1<0oN-_GtPa9wtffu~QcxtCo^R9aC|z?tME({uj$X^|{`r~imwFF2qw;)v)kwT}DB zYyyJ+-*S2aRvqSeLTszgn|xxLrP*mE0)sr;yMWEI@+7zA8$EreRylZr!>7(+xJp9A z80nN8!SIVDf^0BpB|e2bIt5wo&e<1PE0#~TgGy@)f!L|~tGj27vIDzVLmyXX)wffGu-uDl`X+umYO|tQgLNAp5+x2%H9cjh6R@ujoGB=KXu`* zA>d75Dc{O<%EGfxV;g8$yV7G8%C@mlx+=y-f}2s~(U6yT?qL@$%L7vWtd|2kvAM@T zyu7b&8kGb8?w92lat9IcN@j!(D4~>^#{DOktCuslun-O^^w) z=a=`~I!kslP|v#3(q(jI!ygWZ%cQHva`aEPFPxN!RCBuHM8YbZ37*69bXfKvCH#_TE;!1;Wk5nIc zwH92H2FapHCjI-Do!=kwQMzq-{VUV!Lj9%S$FVAYzbe%8cU97NVX4tMP>$?!jaYxy zm_SI9A7i2R$*j$E*L?6Rdfc<)jdlIV&+QOtBgh~crlu-`{c#Wt*No)?!6PkcH9-s5Uoc$b-SE&Fe@Q*{-y%fR}4+&v^|01c7tQ4rn)WzATT2ONgcR0E#v|5-sOO4>+qG;7` z5c6}Io31FWkn{4pJncncS!>kQeLVN}Pt;64*1eC^1*lr|_X>zu=7~-nSqsVJn@#He z$#*1GQo*KjR8y*ApR+|}B<60A2xK)mNmZ1}lQ#VXvg85U%cW6I>*^>k+329nw`Vw( ze^VlX_dEclLu*A&`i5LmioMtiGEug0wUYh<^KOf8iR{LfZRKg2Ov0hf!-Vu6PMJi9UI`JIq=8zl)&<5bypL z-ZI^8IwWH1p@)#75V_l)LUT;q=(TK=SXY|H$r?=Er@&gyw~cPxQ!|*G=TtLmiIa?= zRui@p-16Gp@^Z()(Y03^aSor&`Er?rhIX_C)Q|v~_Hhn>T3Q)isJ7U`#>V_QikIK7 z?q(Tc!}2uPixI{aB-MQ)WmMl2nc!jnCi$OLRh6hf z3^vNly6B~A$J=9J&Q6{fvLnoV!aslCz0B)5=Xcr!lz%KoojliE!XSu5PH5FF|9!-vI z82^&F-6u|Y|BLNfL3?(VOcv~|_&s%$Wq*{X7L3CtvuTu2a~oFgH9t~>kIQA=lYS7+ z62@hj2RLspbv_n=N(FEq zyVuz$%qz4Fr8>DV^;z_eC{udCQlh@-Max04m@@U}$(1h$wNcC1fbDE0F8(`Q3w_U= zCb&&&1r=sjAm-AOt*3Gd*>1(z1>>kSE2%T38kC<_7PZT7s`@U0V%x1(;5ioA`@Wpt z{k~0Rj^k2N4y}(nQ!PFsY0!NNRBxn#Bb+LKz8)0eZG!XXG@|tva0RwCeQt2fjvjLB z!H;ofuv`?JX)R0y2yMq22U+_$*j?SPM@TdK3huw3Nm6}}arHu~pcGmOq@Wa4=LM0)F$l1*k?sHoJ)rG?Vp0q|O zg$V>~kaL5G(ki*;+iQu=q(kXBJZ&8qoE2w{H}7_LF0i$F%Im!2lXeOf(I1HAb_4(L zdu=cfs}f_z@SqRj@lnNgHoDHwY!mbIM9ZofDQ-qxs_QCl95cB7(`t(;A?G{@gz<$e zOlbBvO?NYNfAPXB*C+?D=9C8T@2SUs@|Fa8Pj|+Rob4y~qq|}}F>H8y?&}c_&qSUK z*0F`DrBTDCk!Y!90i;65hG^!VOhhb09|P#UE@l4Db)yj#VX326D3h>MRg3y-d!%NfE}~C2C=BYmsZ@&S4xi7(SHF))2f0%5r3Y?R(bi3 z)7E6%$TJlEqu&RmzBM};q`%oQ9ceT$mX)}b)yG=Ga5h_+HYqEe2#7W*vf4PW4ivjO z`u(rQE6ZLK7Z=POb*k${jB;!C7go(XEF0km>w;DKl{VA~x;s=7ra#B8-no3gjSWe_rURofm)k=6rx8!YXkmk>7tBM+jBuR4pNZ%xPh6*ZA$(m+vsOzeQ zV>RP|_g(FOkBzId{iit{HIGsze`G5S+)s|?I}hi1vMK>r?Tt>e-Ct5fYa8-r+a?#) zw+9CIJ*z4pLVOs~MyzjSJu@V&&z1BjHeKAfc~icKbM!CI1NqD!gq%r}tw6g{DrYrP z0wk_#C!UBP5e~;9^0Mb;9QeD>hDpw*;_QI7AC3ih4PNSfH3%WxbPkvZB*duKz(O3c zr^X(~Vg+m@G4WLu>!-AP-|qHDdQFCf<3r_^^ipJ8fZrXn7$R3p6NA|63%0M-XUdH` zNNkiVUGC8>sjF${;jkWvkWi()JaWKhltXp&n~a|w3!$o&5E6NKJgMi3I$&Cx~P;tKv}{ob2Q=9vMrp(=%%(leuq$RI65RLpG+&JEwv~r8g*dJ}(?t7?{5FAm812pj7mMoeD1p zcW^Ro-dCuRuU+Qs(4O#rj>7iu6{y+OwJy*gUNziURvGBKGTh4*z|_w%LdRGH+J{ea zqxLsLkIc3k+SMnbDPich${oaqJ9V9VGGLgTaGP#mxl|jE?~90qTeb8UO@ve)tiq#A zFPp52TnYr2Kz1*a{fFNCQ-P8LnN|`ijhW*e|CEf0Nf|+EtBP_e6A1&POMO!Hf|}oN z=8MePoFlR(zOPrKpiZa+?>LqN*&WR|JXvwbrA1u@g&<036g;2ChU>LZP!ViM!`|HL zdG&aF0SM|`8aAPz;JU`U9i)z?H8)@M22q&_YDBJTfSJ0Ks$h-erLGrZIIfLqP$cz2 zm744Kxr1NK6;-bU9nG894=y+I6HQ(VU;T~_8*KF*#UeKD_c5(f*Ng((e!DFo2V^B9 z*~LxmoM&NCrKcGy+}wPq4LN8e@^4zbJWi2=n6_N)QhcbtxdFIJRPM1V-M(;~rAP?B(uxG7V^|b^uUcXw5F{FxuD?&z6)3Uy zKap%=jc85DQTU3(K}bJRk=s$tVWBD42%D4i(Q{lNU1$iGbe`Xs75KJh^gpCq>ub}V z%XbbTOvK+R=PM8e+n7joj1PWi5h^iuOA~{(rdsFRf9-+wvU&F$Se!#kmfmZ{%F%<) zwtg*5T3bP#Ukf!WVnkQ%LK>a4U_;kRLlx1Z>AnTDm9n!|h=r^S57g1LZ*_+K^CJ-z z>aNnr>P0etgiFIZEJxVrPEK?C=V>t~e@$w-s_&sAcu*E2UK3)grKvvRay#?ccXGxi za<|Lq#9sq*UKXY`THhrY*fc&AKpzn-gmhDX2(^XJ1*P6{GIcGL*fm8m-aqKO4y8?1 zNc5%LqAYJPzYgr5Ozb>x&@3Vz@l=8WTKl9PAk>#}Qmi$BjQenIVq=c)pDi^u(zumS zb6pCpavg)O-s)Q9X=j3JV+<5<(Ge=-4b(?46h8sURn{TDNaAc(WS7yjTuz#IC>zP` zx$lwxI3$Q&_%N9}OhGilF`Au*LZ^U{DgI;^9@cXZ3z8U072z`nJEh$QS6ukZ+kM|_ z{5q1RGvKTFlY(edcxh&=@e*Qc3x2q(5V9$vSMot~kh}&p)3X&3hJ-CnjxBz7(O`TI zYm^yyv0&wgv+ipQoAaVa0UiB6xhIDx) ztsd5OSIj_bU64He!OZsz?fC0s;V);FW*h8444P7%+BgU2@Qp;(BSZKp?Lk4t(gzL5 z8Le`3pKXiO!5bDVe2F`M3cb0zX=!pv2{$7}UX0kiw)|=CRk1U5hdttklGDDPXwaXF zcdL;@LOst?5^&JZNvBDxgn1b?8En=2*{hc9yXenCIFy~dS#Q~-@$q1IOlD!e1=_~Jf0;|uP2m5BbnbR+9h3_R;KnWA- zu=}(WRtcNTG7qp3X^VnPE^3aLYx|QWSBbgocv7=fcs) z@}T}o_(jr(N>aTbj?e~${_>I-r-g=sS~1NHflX1+C%?h_uokqr{^X=8Kg>#_m0uf~LAjkcjEM2JNdq#Z0 zp;PTjaiI(U;iveGeMUfNr##9oB$T{b@6eb}9+slT0G;T|5EsSAKSHXBcNw@1)u=oq zu#MY2;#?Dr=yh?d7$uFu+?g2sP~jKI{eQXG%Cl7El5BSFmy6FEo>Xc`BV0R_Lgk@M zQjC=G_&D#ddiU5=5hUbK5za4s579w;S_t_5ni zQr@1XB(8_g1RPpm$VHGi{*yJp>3E$Hhtl2S*{G2cNZs4}IauD(K%|V6>ZJlP@N2lC z_0Ok;j>*4RMJ6onRpKd<;u;|R*2v)h-YA+{zz>PV#_?vwjgs6Lp(&J%z2HU*bFjBa zxY3Zm`3Tf}k$Ts>LC7H(`!dwD$ojHZg@_@S`Bz1Jz8+EahO}sC+F{+^teBQUD|j|m zpwfffMk;FH!6O9IjF}=z43vVtnvRY$rRrdK?F5Iw@RA=(REi%}9s~LaB?mqXkOh5K z5lwhVxi=WKTLI?gxka?+7oVug5+bIV(4Ml}8bFT{h~(86*@;Va8U zU~4C{P@K#4|H3L6eLet4GoImzhv0V(Je z-(wZ_9WB7C^FP4Ry1w1EX9^$2wqQIww65IoSqTIe#fVr;vlsIId8WBWP?h+ZLK-PI z`?)Kny7;HBa}q(vpY+kYsZ!AapXeCqn?c4Q-(UGkvQ;q^tC?^Jz7oMLp`UM=vx49Rj@VyR$~ZcUzE;&JG7tO)|)gj;L_j&ak% z`kiccilGZXZ5ww|TZdOVKHNk06vKlDB*XGG`;#d46x1h8hN^Rmk=A5udJjPax$MYg zeBCOc3UI^XVR{GsxWNMU_v&gwtL}m}s^3f1g}RT$Yhs}6dQ49~|CG1`lSYOP2k(as zF0cnEth0gUoDz=b_FVx9^E5wy-v?R;HH`wC(ni&XU|t#iw2r@;DTw=Nh+H&v{$~1Z z{V4qP{Up(*5*qEepF5iCDG)x!{<6X6D1-C_1M~%a=znb763rR)C+~Iy&5K?J%Xv({ zMcm3vBi-JAct2karYINz?##*sW#my$RG5^_?%^ z)D*#cX_T5RTTkn>u_qkF>x=F}bg4f-^D!o^ehsY@Aszm(283X0>(wPzmid!aoitix z#9?Mh70B!Q=y#YKmdWNp_>%>uUL|Xz*5xZkX{a=q64_UFaV&7jf3XUVA&p_Oh+tA; ziGV+ixi=(&A0q+gu09osB@1wp5GY9dK%I6T{6+l}qK;3;>J=@KMEs-Ag2nplgp`Yi zICdpug~#DHDd>T^rr7_lEqP|n>q%Sm$`z6$60^$Bsl1dE7(J7w%CY5!<|1n6B3dYl z+kQr|V|58nHVqfRg$gfU20;*qW#MGacjrn;%_a5&?se@2w45mtEd@iI4imC=qO+dZ z3%BCGoiQzmwo+iHUE~iDW^65I+3T_v8PDN#CM>coO;TYbG#g?Ov0lV!Cc>qbVJ(SL z9B`puj*+eeE%k^H5sGNo9!pj;BZtqWvk(y{6E%KwM~UGKj%nd1#nxYdhta_t5Co}vAo zL6Ihb{ID=^0V5?w2zE(gly(4X%xj?&D zB2KD_bgzA1E_6>?BWA<`)%kpT(={?Dk5(O|xk1kS;YZI!qZQi&l53O|w#XR-BOj1SMn6&tBgJ zF#f)t;6}1gm}=ylb0TLofvqPd7}7DKmJ@1HUd_xRo1Mn_1-HR#ge7LPuy2_%{wcr) zAp;emGU0G`pz#gAh`AkAu{U5K*@L;qV6|> z8Hiv)ky75MhXWyxgO{kxyXAijT7zQaSo*u8MK(RUsBAt*0oNDz=zj)|d}@Jwr33Iy zsQ)sxhlxx6zu3TslYoRX(}XnX@%!uxfs?G>{*xCDc<>%8{*ovef9(w@5V!^Go;F4{+oi-)3g|R0-CH z=+d47^(S6NWbRNSXPGNa|3^{W$#+2t7=;gox8iA_$mcc6fr+i1C5z~)WTF&k}H!Bv=tiw+)~hf5UF@9bUNQn}O* zhIPwJ+vTC-&7rV4hfG9d;7Qf17Lf^3D5NA@oE~MGNmTK`SskXojsv*}(9NuWQIcY-4PaB|U=rcIC%6B>?9*HPlto)~z%i97oq8 z@fza#l?`oJ5c^hT97?-Vuk@0LnY(?+)+3qDd?b%=aKYRAtC!&VVq*BEjDL`sQPfA_ zKp9yWRdXsM(%Zruhd+wI5@S=QXPZ({8017G(Cwr-(B)8r80zA@t1WMBe2B#UH6(~~ zxFBofB<-J{03?v3Z6-3I4tH_6ut)ivNBfk@BM003(QKtuf*$U2jP{ZH0XL*o4J8%J z#FQk>=EU4w!)mpXx9y33d*agBt=uMrb(^;Hz|R&>Us?^VH`@XEzlWD#i`P7`4Osyj z{i*)_GW&C`bt;L<-sv|GMdilB1g?LY{Qi}zaS?z64Q4be;h^6}6m-T#k^JqPecEkO ziG>{|L@rBH3`Fv=^b%>>6(9L6C_5y0B0znOkc6E}L09KfN~<^{JPe0r4mD+4h?Vm8 z`m-PxJ|lZ!bt3uG4^8nJrwu`l)HB>+!AIio#D+6_#fxt`{m4YgiIG11S_iVs2gfbu z&q07zL=zat3zQc*!4Z^`@uAZ3w8b1;!gzta&{Bq-|AXZ6F3J=?ORBD`m4laH6*Spa zdeOXG+;ghF>8vttzV!lf7UmT^Qq&@JvM%RXLp3uJa@78d&}wbAp|)m3b3hkm-|5Rg zg7|-7K^qdBE7CHV5$`$5)2U(aWv@QvlTf$)lE?Am*49Bd?tWw`3f=|W)u5>MrAyk=bNTY6pD&} z79yXnBh+cTo6VBs@86y@2S75xc&4N_`t76tslmAXtvAr9Jh=iQw8;O6?eQYSmgSVr ziBj2eYuJ_`ULS}U6W!8JqAuGpr3;rJ7#efSjVxY*;jRZSU$aNZ`}*Lo+U(Z#?8?|* z#%8S4XKc~iK zQzSnE9q2N|zNMbwyinX3qQgFky)cWI*?AaLi}{eS5fXnlZd_fN@Z$@SNaZw;p?y)N zD(OK@HqHi_-`H}VMhA;dYT__D2qt!W@1O3OSRoUf!AWoYHw%?%=@b9CXo;kV!nx|s zD%MHaFnk}Ym^jA^2Hd#F|b}9JDvf^Ow z8jG!Pm#Q^I(F{SRZPlyfhouVgAmY1-Whv@i9B2`x{L=5n|5US1vjbd}uIBzm^2$Jq zT=qoy=CAqYTdmgMWuaIZ@4(VX7_HUgb4#XH2BacAZ`;Nt#$kwqbihX`%Jg`I&L-$U z-gM(goAU>GgBm;@_L1Uw2v>Dd>*p3GKn{vIGaT84hN%|R4GoLihyL&sfMdR>?tBj) zq#h*@9FR>oxn?hx`-@OPjk)AntXJkt=WDVG&gJ|o7K(&ZW2n*gysIjRZzvt9PRshq zkJ;rqfK?Wzr^Bo01g+LLd4ug#=$IbhN0=Aq2)=2d`Z5f;d2|vnXB|-bb@=#S@+JP? z&G6hk*n_fcC)c1vHoBHxBg?(Vw*;{RhPoh9so639>!mOtmMZ0# zD%C2eh%hl=VF#-BcDr1^wsaa|)b9W@QaDG@E56X9s2a>s3&-tUAoC9W{N6~MqxqwN zSUeV-$vtQ1y)dGt*@R5f3QZglBb;)%<173)Db-p6_8Xmi|7tH8Rs`B`KS+ObTBSx z<}Nx7OMCocvjd~8^VlFJ*9~qUVuW~Po zMQvfbzMtEFsF}4B4*$+dgeZHHwp~p`9H!3|s3W5i)zX$!txqzjpA`b)MJ2*lZABHV zlPGc#Uf^rOlTAZJW?^-yE#t61+#X^+ zv8h55=j7`PMGsB=TY*0w6gu?7R!)lrlD%6Frb7y)k5NkmQZ7_FppKQi1QqXJ2dp$V z(u#}y>VBSxt8f`)d(r?c;#^?vqvROKP-MtqB{{FUC^vBb5M~3dG-tBAHQp~8omGyb zD5SZBSlGtMX^vl81a%<_rI_p)B0uGyCEbB_v(n=Qa*zdx5nWFUEU82m zX6&pE%eq?xNr-G+`1cPUhGN2e=5r_0L{823TK{MJOg9(hkbQPL6%Qrc={|{uH|*WL z%8dxkRK6QDM-PxLE-7yFm6iOxmCMcAF^ueBR3mV!J@@CoSCjF$3FLZf7=cBJ_$>YClg>w41d1PHX`{2=Hv@rYke~H_A zAjp@uQq0=Rog40ZFWAnv9Fxm^p|DMDBTXe?P_F}clF9@Vz*?14(#<4(GdqOg!=Z7y z-&ff~juzJ*`EUyv)4jRFXzW?2?fs}16J0lHm3I1KDz-7tMxw7$@T-Kx{eiM&N^Vah zr~AuOm-%40=?F#3>xCT7qmrB}`qZI#HvaS15(lwzS~coVD4!!Fu#@#rG60QJOO@05 zyXsY-#0h*_(NSv)7sF;m=#WOIsIl^m!@9(&R7+*$WX4+$yOqpFkRjk>D7fsI2+x%~ zKumE$A9p-saYQ2LK-+A3PPEulzrwT12^wMgF?iDxqDCa=08=sH<*_SBZ(%_Bl{^)49jn&&V#z$1KoR}NKmz!K$Ot>slE}3~Tn$N*lVox=z zHzX7vVt!yjUIDmO-v}&-FjC}=$c$5Yxkc^#G?}yQdE}-WzdGmj0M%-Jv;H3$+NA5K zknn5x;J8ny`vNJKDm?(ylTuOCN#f_|s2jsmd2`6cO~b#Jp&}D45xPhkiGido6@*b{ zYm+2qk`xk>E_&s>P-~+R-3^IOkp3G&3@!!c_qkLzxdr?~npLp6aYvFC&Yx*FN2xaH z@+$1}R!xS?m#4gBdv-})Z%+gm3aS|PI`2qyADX|y20Ra#L!$xOKj-i4zUtgN`A>D_ zk9zTIZOU$7s&jZqqtRKFyHiQPR9@b2^00kiuulEmAvi40%DhhK8~=}njtLDcI4c~@ z9**R4Eb_A|TF(;b;=RgY8su zcm9MqK87kq_QmM7 z(*cRWr1wT>bF+M+RKv*z>*P*j_yTTIID*ULa8mBH8g4`x$~0F79x!>sZ;s5{C6NCL zL*VjvL+M|{U@S06HS2<`DuPNuTHwksG0ptXZyPAjBwSrw1vg4I-VHt&J9ZS;*&3_n z4cWw_j$oC1ykK-{_B6ZQzx0y^oZX+35p>=0sxCj3N&YvV+HPQEPzmFX2bQigy8YSl zQRlRYacd0toS=I?5xAld8mISjfxVso>0*#-AP@Gs;?$CMRK7s3bKp49xmz>jNwZ%U z^L~m~6Z!!ieMO4v1`V6=f4VsHXsEkCj?a(`jSz!OWt}j{lC801Cn_ePtQiI~rpUvP zZNfAp48CG4AxkD?$yV7WTRi4LmXhodDU^LFeya0(I_J56+;h*l_kP}=f9|>GzVG?G zUf$ey2kV>t6oXK)$dTq%wpF-WQyJ>tJK%*ML-vHE9l?2z4g_Uwl3Et9g{ZNW8Pu=CDH-WU;#uupiTYq)lPD-e*N;MCE z<2#tK8XrzjTDXmLK{>LXernU%FayV-jU10+c-i~qABp_ngtkw86&CEO0zdc3s8sN~A^ebO9 zJ*5+pTS(U=s5!;U2Ogh5QTF*7X$}|hshl~C4RiJ8lEbTHF?Ud})fmG&eX>V!L5618!t**f(DL z+WR?r9g(*%0S}~za^y|BWb<`biO(i^8tHPQU8HFDPceK!LV}&ImNAF=F`?*{(P`ot zw}q)!?{#yhG-JFsxoWbNOT% z>M%F{Y#sf_s!PJ>YktSAqtC{DifNNSfE@W~j^GhN7d$mr0;{G`;2XdlB%5vhdh(HW@_lx{ez6E*n@4=4|EZ#|0q5WI9Cu? ziRhzbfjYGB%39%CjBt6qtmgVSgEcL@CX%#>JtE%dD%Kj+XS@?_QOlvSM zlkxONxpz`t=b(!C82QG>l-$n+6#hU=MOWA+;*jxy((!W95&`%;E?tqYAU*mSu?U?l z-SG;Zx%V9YhH9tLs_K67898YkB#)E9^3)O!>3b%rRp+33POcRTs zw=J~E^0?D>B8C9(_XlpK7b4~!DLi$i+pNRA?RFjWIPEm%_6-ow_RZyqRu`$rsFyF5 zzB|~25W02ezA5wI7h#YKGl?^zD)&u>sFh+%#7ndyjC9Q+Wnz7+Bel4h6s*XZcByBQ zo0Fnx^g~0QL<(wta{x}wALiudIW;j(VPo3)rWYzc;?M!}4orsYY259QaoJ49twg2q zFt_Sr6EYia@ve1CNK1WeNz00TWm!#Y3=BG6sIV!*qL%Tb)j{hHiCU^KY1rwXN!=Mw zgAQG(b5ri~QH*&+kf|Wa)t`>u@p)%ACAKZt(AjBS#{Gd7*mr!S?8~8+vpwyzBFk-@ z9`%i6<-hZOlM^b#9bbUiUf53vO8~mgnqU+V;tVHUzf_GevdgvUj0<(m&irdpoAfOa z+s&02!#Ni4!)h8umcpFh%3o@%i?* z2o12~ztyvHSs4K>wo2qX%xxuh^wfmSMJ>uq)YY&gNXmzZcu(VdcLYTTZg#2oX3L3R z!09`YV%*vx3d|6TB&afH=_3_e>zXZ{cOUiR|Jtu-;7kzg`K;pkTsE2d`+JvYz>0`I{ko-h7N z%MVO}t>4Y%i|!eKtc}W&Eq!3GO5-*|10abv22La=f>PY5mCAi~#<$Ow%K=gYt|1xh z;t5g|1NJpdZSx#?t+4U1UH^@0@IjGly5*rwsD*hdOQaLMJ&4VK$B4KkK!ZUU&a5OS zd1!)>#AGT11VvTo5MO>h(Lpz&;}bpKANagiZJNWN?8Wg6dfAu~3~fwlJ=`iqM&iiA zThS5eRs~-o3v=%6h&U5JPeIE!MP4X6D+!gn zGmsT-A9V@2y6oC{a1ZiAC?+l65Kn3$Oc)A&pJbNn*<%BFq-a8Xog$I^E;Dd*m0n)v z@51+;#^|xI+{p?u#6PLP6&3zKlxJNTlxT;LW}P1ia^?`}y;j0?8eSFtUy{q}O4V16Tm%rOqOc1yhgHdq@7B4~lVfm(tFm`ISu)Mc#mlkU3SS!B~3pY`kH>sdqM!g*=LHAN+qP@WZ z#dtO>-e|Hhpr-8YuH2~DK*0}nA{(~xoWTt@lJ5ZFnTw~1F!El1uk_jU?U&)2Ur~-x zhx?{bdz!-YaFnKD$vfpK`d@KSuk!D%GQM!DD@}!Wpf^U%1|Go**#;b0&6CE=T7X$o z^OWaWcA{rWe77+E4Lnvgay<6Ib^YrC_J%jbgWYU{BcnB$X@}$`=ry%hsi}n#vh3AQ z_x33>Y(>OZkkQ?IHOy?hRLnHuYe$mAMp(4f_c1e-MoYaWE6RL@zyJdSg8>Vb-}wP5{7I_*S$5zH7#Qm3Ra1KtMJK@C!I{y- z-pP!?!`8+(&Oo8>JI27K+#3?&CH>!4OUcy%!R2@v+4AWp@hv-2te;?u=c}u3dYRKt z9^9du{0{b=OQ$?5{HkG#9hm>L9T@SWr_qkmI4k0j`0i87Z)rETW4$?`Uapk!Q^36O%VNM2)Qo& z9a&MQ!xD^zIkGDW!ITY)g#uv-XM=X^?ZJxvWq*U(A1_hkVp~riY(BK1j^5eZ@MgzZ zZIoNF37g(8da}KL;^SjiFZ`edFCH(zUSZz;1^rtI+HlB?a-Y2oC{6;3WnnXi_ITuH zLAtEc*uL;1<2>} z9yh~|=_u+_%rQr>Czj~=BRsw&__{;$&NHe=RfSZl@T&@H6uy1=|DVIj77mNw=Q+%L zo&$Qk!&e+YVU-CZk4_8&af@mg%q3f;rNwrC_Wv8}6T%AzqslwVL^#v-o`}yvU z?43kRA-_;m3#v!$3t{~QWpv)v*JCSo7G_QqW)UgC;cP2& zCb#a@fa_{7{p@~|1kXRltyCMaV>)wCa653`EsX=#VMQnAaTv>Lu$`5JzKeMu zif}@1d8GM(yW#zi83diad*RFe`HW#Y!NPHLZ6V3bpGU9W7mI>@j2^IM2HaGI2~Etv>7Fx+gqCt&MS(>&9`{TNq>g6 z-b1Uh@%`mj=)I9+^Gl;q`t!sru3Aib`=9egvS&ufx5qCLupD@#D`C7_SudvUlnCyzhKv~LEgf{?u%1o5ki82(bh4cdV_;E z)|I0?c|!}r%)Xo%O>GyOXR&*8q9kTL{6yKh@KvW10SjNj-m+hi;gRbw^v_&b=GB1{c= zv75{emAFlj3kA24&?^)=PSGI-FFODZr@-aET!2@}g0pje`y8hTn z@8(#iQ>Mk1e1MJzMjbjsM&%x0uGV;rq}#X@R)RU&;LkS)sw%#{M%k(kaKZ)Ul)0ScXi}Q%Z7SA}tq1VZpY~FPuo~V%9#_H;7lU-Gj{k=puX=)uHpyi3Tkw!4r z<~|R2+_s-u>v( zZzorM^hqy$c%wH`zs{5bdt~TjR`%hp<7LO;>xkSj0D0!w5dm1)Yi|`1_H*fs@26!% z|86fkpUT$s0z$bT-*kMvBEGr4UQu)m*#zQ;1c#0{j)u;j{y~;`^FovF8@a7^_fe>Z z@ATzD5LcLGM2jZO$b8sRYn_YnVq_%Zy2R>Sx#sLVl-PEy z=PON-5>xnAIx^5b4>sBA%LP}tHKG?Z)#Xhn3+8ftIF_OE=4tN|>&x@Nb1QSn_Tqru z`?|(?9Nw_sF(URv){G;5rT{tn4#p9Q45hJsx6!tJ-tjo3(L*J0!gsBEJYsCX@yH%y z;QQ8<%pW9YAkFLcdt>2w==&6*$cNM2`umf40$1hTY#k8#o$}FRAoO?TEx7`?ozF{2 z-bUG!!1H->HiI`yK~r8yqS!7KHUoQ&9p8F}&c+@2)aszd$6J@*;{f1yi~Lbt7@SZ0 zXTo)+`h4Wq+j>%UhGSe1(+-0XrB=WnD(C^PeeEt)g1o1 z4${%xF_cLmGVCu;ts1 zot(h6KG_2(g#5RW*%)TI5Z|iQf^6@%yFeuuFGL##WVzgtyx&T2CGo^OL%7M8n@moW zKB#x-fAtTxmsjK_aqpj7&nS~trW)b>S_9xc-{rYH(;zib^y-f29Yy~^!Rs6VWZ?@M z>nx*4lRlbx1eEs`ap zw`7g3_qIjB*Q0xbk9LTVn*sc`7-h;{cPC9PNX9tUgr)NhTSv2n4Jnrqd+h_-=Q0-H z5BR{@Q>%MZiRgAjm^U5+pE~-jF>j>a@(ho9{WxlGso?udUf0XZYj)?$HS)&W&aL>t zR|m`q=!+X&S*=+g)nqFkSC}*foB;qaqLkdGI{LXgZ=55i%J25LECxVolSk)OV$(LJ zq_g7fKw?2j>Q8Ha9e1$0zsS>UMXF^?Q{Wswyf=6|nAm*B9Y0Ku>6-5jz-A1p8W=wo3`nDJ@j$&{P~xOhiW8YZ3IxF3Sw(e z`qar+XB~Bp2ODecz(jrtNvK$w(v|!CEBHoYJ(%hCm^lKV?B4I#R{c11g zTNg{?c!?Qm5C*ahSS8o5m!7RO~UW>CbT}6wJQkofh;0rsi=+AXt|ga>czacyvZ|?N)Ka+^bxqzuout7b_a4+5 zQ~^lHw4~S1e4bxR*!tTw(Ug^RUNxDP8#9~?4LLF~T>NEp@6zZ_Q?BAi$(N?`l<2+@ zrUYuGLRo2cjj~Lv_IGqM=?yaw?bS1VNEc1niL%-NJA9l4Dr0{jpUal;RjJZ61jb3GC|l+!Qx86f zn~Kzg>BR=uQ3A4w0(HHQ3}q8cwqRp7G!X(8A81hJ=Hg+}`^KBS4I&&;O>8PnyPYR8 z>4hdr)i7c`7E!&dsx;p)avSI+)Y(Xm;X*9-eODpM_CblG2irKHL_8E)vr^5*lf`0u zh5!=c)We$}k&B6x#`~THnyDNX0$>m+VTog3m=7|>`T=PzW;26O{q}Y+*!1~AHu444 zBsY-x*pW{PrpF*-9n?^`0&1leJt&bjBC)kZnkUwo-jcV*tUFG$1}#CHBgeX-@^w7L z;(Qx7EU{LWZPwYkx*PlXg65_}rTi>UlNu_$%(~J{Q5$?;sT@P8T(lzYPzb(44J~)M z_2SH34JhDNk(zu-)HY+W3LXj;b7%rcU}tFv=4b|%*4YNgS%Pa+Bi%Ji<1oINhlbI3 z+Li8mC(paVWba00AoZhEn45=L?L*B;&vWugzrjtI30Q!cH0ll5prlaBqj+twfuFlO_>`c_bse7Qr-U9t4d1p{^T2~@ly19?OYMSvf?Q>C8sX`&1 z2E0V82|YY;`0E$Q&}_~}RqJ@*D4LSXE4yaA{+JOY(&MEs!0L7g+Vj_4lPyG3QZqbR zA5p;T)f;(oNS>h)b*iiym-2P!Ac|rNLtqLQ3xS}`X40o0TtGiEH>1CJ0YhvI0vH^;8m9T7!&`RPQ?=_ z>?q)ovnBkk=C|aZu?R--nZ}GD3Y6ifF+~o^n=sqU4O)1a(FCjOEsuo41QO6DnD22L zFt8&oXs|kDba{KILB2v(BzzO9KD>wi7Rv1A37|wJX?pxzO&Pkco-F<;i1iUZ0L-dk z#7s%$OOm>g>MfibWjB%t{H}#Y&))JI$^f?gAibk}=}=S85E8|RYAX<6flI6z!kI1%6 zHk7hK0Gdrwr;``O#M-(S@3;KL`sgQ#o4U{ww;G|s7K{qxhtB(Hp1Tjv`-#T-wEgWZ zLr;g|;<1rmp$hf2eIjm&-qys8-bdlWxsorboi0Wyf43IIqUf~I%2ESjS;A_nHEWoX zY0?!=x?8)=UH#?eq*rTvlh0bTr7YH^6iOwUNA9-fM$ORqG~L|@NgsDPpp`y&6_H>> z_7R7d0|7B2eG%NTfr#&&)-CE6(@(9I$6JI61RT{O#;8^*Cuy z%9cw5(=6ev%t%@LAMydbp9(ZBERqba2UUz*qzu?+LD3}F93^DN2sHFo#-Q63 zwJxu)>G)+gJzJ$Jq~YdaeGjW!KyxZAh0(_(7dPg20paW*3EBt5lf}QHfxIXj=^2}T zj)KELb+y6yT_(`sO`I;lk0`S_$LT84`*!6LposSyi}mZ)+3;1FWRuHGpMh2=)c8uo z(SON*&w{JyPno4lmUUu9lCRU{7&Pf(mzhS0Z7#Gca}x6(?M%>|jN%AR1bZp(KGc5~%KeA7U&<))tgF+tK7zN(fzX8ewjx}b= z;+@o`g{RVJ(xlHJd#eI*_W!P_a3k${*_WE)!aCjT1H_8x5mLL|V`}5TqxNrx_3bEb z7GO(B*6ZokaXMj%B*y%l8mZ4UlvWyqljO2S0&Qu{30|JHHKC=7S%~8ltnM@iV6=c= zFwaj27L2eg-cm)NLMsj|XoP4lB81A`09Rd5qPy_KP*f*7K#ZiGNgo2JJNA_GX$2N=jY+M6UB6lH=wmcl%Y z30r?A8s^BAr>?yvTbz00qZ*FU_#c25Cqj|9mm}p)@J#^TZ_jRl9Rx=AE52i^WF)~` z@o!fbTRX+j*}N$jj82>P?^|C_+hQ(t08QI`8{b4!xz-)6)~vfE(OlSY3bM2lt@Fm&w#H-;ij7v*Pxk@d!FC;cTwE}tS!lBt19-P{J$EeCEjh1+pwa@y zPGsf9WZBs5#=~?~Y;&z_`;_@7+*}*P?|H3=Al*0-3S-#`AS608vVCt>83p(Ec3fg% z?AUb(S_&6n*9MMEY|BV+>$iYHwN*9f$Gij~9&Q@kl`A$08eYV=iI+@E8Ayh<%HlH>k zt*vHY5;=gvCjM2K7^c&Mw0@O0mrCrpQnCD)T?ad;!r>VbH=(o@&kSOg{ruf57Kd%oeNJ+o0xTb~tPD zLO^R2TAGW;W4m4A4XQy_ONRzX<+!JQP*EUdW>FMJc7+ z2!75g3)sBW^Vq7jM6RABQg{RwWmf9saur%>rAQHPw5}&-Nm~zv&$;`ovdnoBz!LZ3 zqZC)ttv1`s;i6vKCE$p9+@E%xsxs!jC?7#-qNHkv>{4M$<=$#>!u*2Y+ZohwpZRCu z=*npeCTfPW(jdaCvB&Vc?N@o&-0c~ryAq=Y1wf3V{-^6(rhV*(T||N+-;{f?L7t2b zWr}6eV(l#hKQE%Qi!pB_={!~5pq$%kdU;rsqg$&cYy;gaC(WMu_-^s|?h+SazNt>f z&zt3^oz|)UoyuP&OyF z?EypXvAD~&G+Yf9GT5xoBZC3jT;>wLV@PAwdX69y8~}z96CMbw4tjuX4XRdp$ukXlpqCmXsSlf znm_0pX`bhONHgRz0U@w<7t@LMUD)~d{D9=Q>XKo&nknG}x}C``9VZkErq$_oi5eYi3(Y($d+p`RDe1z z<^F2KJ`RLcLW&Nev}*g+<-+1iG~~2L6OV5QG3u3UI^fKVJHPpU|NMPYg^H+3&+pbO zbF3D5*+{qvt2x-UIxlUrdT&z_5Y-K4zX-nJMsqk2194;5f;)yc7mGojEV|B5H-(FQ zJvZVvJ|g<>63pW3vNQIk+#wo`btUjQTB_Au`rXzU?zB?{ycF5{JxOSa>C({jB#Eh# zE;6HPTzZu?70~Rol`?ldAMH1l9Tn;;2A?IJhdi>CxZ(trq`MUkk%TTBF4!U8V zJPb-_BdWcPH_=EY*j9}Ru~MoNomR1;C(CLO8*Swli>p$WNTm4?yvt_@>N?@aD%J;h zI@%>Iqu-ejD8>i53jF5a?Q)sDpG}#9bVc7moLPD;N#eDtByCJKkw8vDLAbwIC}#43 zL6AZ~x>0|n*>3RCRIk+FD;epR)5w%ktyF}~EguKwUv1o;4p!ull5aAB=vwM?6PBgT z#jDvtANrN$CxzF%d`7u%c7?lNnw)rb+TGzz5a(atUpKn+v}g1>GV3Kx?U#f#I5?MU z$YtCWlTaOabCl!HO@UjshM(4&PI|Kr1hp?oHP-~W(K27{^@qx=$Dya%y=ph}_4p4$ z=B+|^=a04ZJNOHA*dqS2&EArq?eSwymvO?OY46qO=$G>r*0`?L5e!rncVth|Qj@GP za0C38Z|Jct{m-YNyKfC`nE)oHJm%_yk090;W&-@#p0;Ep24HNQ9K)#$G(u&5hKM_o zNxs^DK@+gLX37PrljK;2U2A(nhBd67n+35hEghaov8bKu@3C>>Qc@-GaeWHB9qS!$ zsmbdl>Q2m#H>)x5xVoIIJD=c9s4XWwGAwh=OhdUp#%Xe;c%PPYYcyOgki~mxM-QDr zY=zp_@2dl5KmmBe;$ZKsmV%MCnSsI6>~q2N51B-lqxn*lQ@b6MbVZCb#r)pCN|&Ew z{>fl>8XU-s}u7PukxF~{FXzw)$7V;JX0XG&*Tvh4p zcHUmV_x^fHt7d9fyug}XI=@-4K<_y0v?XN65Oi?@u)WJa6lqQRe9Sw z1)#{?k|VzYE`5#B7F+hIm^EfSW~s(stuVU<8cd2~b|69DUWxVhbj&L^|Je9{-7vCU zuxqgf=4%ktlzF7u21>76SocpH>+qKs>dzB%Q{NJs2CQ}L{cg&{eICTe){x>S7x?>< zFusYTMR!-$$+W~C7b{D>&n=)ANI%rMu4tdT$pnZCRZ<==p_h>sirhE3G=yK*Q#~YL zcN<;svS7IJ&Z%EaiXDk+!^^bAZmOoveRc1#zUm&8G%H=`U4`N#yY7XSl*IPGwQ=CAYsew zcOkRl>XiRIaS?V5qnW=1sq4{%R3Al1Q+j}#M#@eVwh7*dRv!*${~eQbKHf}{ow|kx zK*;w}{#v3=t(#VcGE~0<293#}+WerjZDn-y$n)FL@fEd@FYr(#K~3)@#JWv&6!k)< zi0h_R9$gHsb2I7GV?m3Ge8?@?eSvIqRu|9nFuEVhA~_%Sbj|o)e&ps-*rmo{d9B2J zAQq8ktGGmDpe@U}GX;{~4y*nSYhI}ifPFE7%GRN!w=?8dd@z5BGrwps&vVG(o3){N zo$NXE;F&TK?JY4EQLIZHZ~c%rAiT%oC|Rc zos)A_>5*!qf~X!pm)8eYR$^0!P+ki;bt#_16t2m`Oh9^31*(<9az_%M?Gbx|Ss5xtAyd)fk33ct4|SGGBEnN}K7X{<;p9>Cl~2{;+KjrlPVD^#xbeSbaJF~g zZF%mV%D=av=2&i)YEYYXb4#7|*ji=2)V)LD^-w(Z={W;;@`jZ_o|M7?*pVt_V+^h;Y{-s zT(RBr*j zWEtkKGAlpFF?{$X1jw={|58pOhVWK-BB}kfgz`Qe_8zmV2`4|M`Gux@9!UW`7n|^b zat%xT+Us*?f)2iaNLL8aO5!TBJi&2W zUxnbtxLxR*qdHjc8D;wcSzF-6LcXzHY-ko!=a`{wF)Mq0^loT{aob9FfNCWZr!2w8 zn0rNFvlRgHWTQM#Gx70~g!L{-X+qcyM5n{NWfNo3C8B)?ZS#OUsSY4Hr&Cx{_oL*k zI8je?QzTRu0Tu#IjV%4OB#!7C#qq!%TqU+nY0onTwYTGFQ|`tP)+XLK+U7^&tjM}P z+0(&V7{{{3q_ zd1Sl@`a`9WTe|r{{V@WeE^q3;1#mE9!s*AGG6w`OAnQm#qHv+WR428!IndEngpO->G1Osa_o0d)h)|R*xe6}JR#;9R%BrZ))p5o_XmitxvS$D>DOS# zi#m+!s)U$;b78d@dBu^N?xMPX6NMH5hr7-)W1rCD>e9Mv~7 z+T!zMnvhOjEL>2-DUq+wa{SmP?IOnN@<%h?!Ob&)w0I0x{(huYTQj%iLJ(PrlrX0z%rN3YN$}Dk)PMf~9sg$50rWu3s zuEzICN{?;4j(Himb6IBd3@liC3t0_SpbU(dJvD@oMVgvZpeWcwdnOeK$?EE`iU+M6 zXTbA$CD+}Bk;~K`90t@oWdi$jI6+IsLN*B~i$P0N#0<>>gRoQIlq<3<@&V1H0%hPU z@%vy)0gpG8bXXIzeT-MF_|xy*-lQxYUhhu#2&LfSmAS+c5ZX?gEHodH?vH2%rcV-P z_UQasPW?N33RiVMBS;hRd0!;ptt6-!<3>X|tWeY_#Xz?HPf!>diF6nhaX?V1-jlm$776 z9BJ9#v3eo>O{C#(%+N5U(*Nxysc4;&p35z}1xJkuD%vFW6zMP-VjwZ7m>P7Z!fj^} z^}nj*1_8rlqRYu8mU%%QsPct;>$pDURssAr4|Buy}l2kjN9DT}_G zwaSO!^|Rw$f0)epskaah-7`UF94rfT3BkDXEpCcp-VJgG@_>s-Gu4t~RTa%RSnMvY z5O(>ig~{PWKU7GBOr(3&3-#U(e$!>$l??9Dl?GV4>{EkM?ii#6xhaWDL#c?BVewKy z>%*$-CE{jyb$0=lrgG3dN|*clUo9Bx?i7V}(T($hmINgKs)@KGpqHWW#utP}$+oQx zC!i=Ot9JFc_!ETb2S|sti-{vV8(|r`zqZrk)VFPwD$r_W zS$MH9e0S{BlEX2^FTe{Vuu;=Y!^JOCg$m*K6UdyuvPcIT%LIe=aTu5p*R}wt%%%Sj zw1{d87D;PE4e>R-+`UxPIbt8pXN*DI`Fr*B0m+bNea7*=*r@nps1cLVudrLmzwkE{ zxOK@2P<=)>AapZY&c=Cqjha8NW9zS~s4^En5>QolW-KJ{O>vavv>gbcl%vY_l1SAW zx1QIjB2Q-N=2cbM84?FcxBX}K^o4dv?Ck|G}>y3@M+8BA|=%pzhF&e7n>Zk^_jnq;QF?xr%IPxGC$^Vgepq%ox3% zGhc;xJTDsos;q<;{At_4Bhpe3I`*>R1y(2-&JX_){RL236ku8wBq@%lY<>Ex5H`rj z67Rp>n^t9KL{Sy_z20F=ocQl!%EObkIC+*(RM?_4M4<_Bn+b8Z;(}$nC|udKZPBG| z`80o#IU5czB;SE6SF24q(!Ap^L!PCzYHBtNk;WX+MY#cx^^Z6=jQv|-kOP_--c|zC zUq_jJ*l8)iY=)&eZH|rrN>k1(-OMl%QpBt_3IYAqhjt`Xd>P6NFToZI;`LbOicd@% z4-U4E67{K|Ej4`LTp|SyZZbAulp{`@d}3fDM9cB}1BWjCZmRNnj%d$SE@>2UwUE)5 zw!B^OWyfLz`m
paragraphsToRemove = new ArrayList<>(); - - for (Object paragraph : paragraphs) { - if (paragraph instanceof P){ - P paragraphtemp = (P) paragraph; - // 检查段落是否为空 - boolean isEmpty = isParagraphEmpty(paragraphtemp); - - if (isEmpty) { - if (!inBlankPage) { - inBlankPage = true; - } - paragraphsToRemove.add(paragraphtemp); - } else { - inBlankPage = false; - } - } - } - - // 删除空白段落 - for (P paragraph : paragraphsToRemove) { - body.getContent().remove(paragraph); - } - } - - /** - * 检查段落是否为空 - * @param paragraph 要检查的段落 - * @return 如果段落为空返回true,否则返回false - */ - private static boolean isParagraphEmpty(P paragraph) { - // 检查段落是否包含分节符 - if (paragraph.getPPr() != null && paragraph.getPPr().getSectPr() != null) { - return false; - } - - // 检查段落中的文本内容 - for (Object obj : paragraph.getContent()) { - if (obj instanceof R) { - R run = (R) obj; - // 在3.3.4版本中,使用getContent()获取文本内容 - for (Object runContent : run.getContent()) { - if (runContent instanceof Text) { - Text text = (Text) runContent; - if (text.getValue() != null && !text.getValue().trim().isEmpty()) { - return false; - } - } - } - } - } - return true; - } - - - /** - * 在插入前检查目标位置是否有分页符 - * - * @param position 目标位置 - * @return 是否包含分页符 - */ - private static boolean hasPageBreak(Object position) { - if (position instanceof P) { - P paragraph = (P) position; - for (Object run : paragraph.getContent()) { - if (run instanceof R) { - R r = (R) run; - for (Object element : r.getContent()) { - if (element instanceof Br && ((Br) element).getType() != null - && ((Br) element).getType().equals("page")) { - return true; - } - } - } - } - return false; - } - return false; - } - - /** - * 删除书签 - * - * @param bookmarkInfo 书签信息 - */ - public static void removeBookmark(BookmarkUtil.BookmarkInfo bookmarkInfo) { - try { - // 获取书签所在的段落 - P paragraph = bookmarkInfo.parentParagraph; - - // 遍历段落内容,找到并删除书签开始和结束标记 - List paragraphContent = new ArrayList<>(paragraph.getContent()); - for (Object obj : paragraphContent) { - if (obj instanceof JAXBElement) { - JAXBElement> element = (JAXBElement>) obj; - Object value = element.getValue(); - - // 删除书签开始标记 - if (value instanceof CTBookmark) { - paragraph.getContent().remove(obj); - } - // 删除书签结束标记 - else if (value instanceof CTMarkupRange) { - paragraph.getContent().remove(obj); - } - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - /** - * 使用 ObjectFactory 创建表格 - * - * @param factory ObjectFactory 实例 - * @param data 二维数组,表格内容 - * @return Tbl 表格对象 - */ - public static Tbl createTable(ObjectFactory factory, String[][] data) { - Tbl table = factory.createTbl(); - for (String[] rowData : data) { - Tr row = factory.createTr(); - for (String cellData : rowData) { - Tc cell = factory.createTc(); - P para = factory.createP(); - R run = factory.createR(); - Text text = factory.createText(); - text.setValue(cellData); - run.getContent().add(text); - para.getContent().add(run); - cell.getContent().add(para); - row.getContent().add(cell); - } - table.getContent().add(row); - } - return table; - } - - /** - * 获取指定标签的标签信息 - * - * @param key 标签名 - * @param bookmarks 所有标签信息 - */ - public static BookmarkInfo getBookmarkInfo(String key, List bookmarks) { - BookmarkUtil.BookmarkInfo bookmarkInfo = null; - for (BookmarkUtil.BookmarkInfo info : bookmarks) { - String name = info.bookmark.getName(); - if (key.equalsIgnoreCase(name)) { - bookmarkInfo = info; - } - } - return bookmarkInfo; - } -} \ No newline at end of file diff --git a/detection/src/main/java/com/njcn/gather/report/utils/Docx4jInsertParagraph.java b/detection/src/main/java/com/njcn/gather/report/utils/Docx4jInsertParagraph.java deleted file mode 100644 index fdc8cc5c..00000000 --- a/detection/src/main/java/com/njcn/gather/report/utils/Docx4jInsertParagraph.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.njcn.gather.report.utils; - -/** - * @author hongawen - * @version 1.0 - * @data 2025/3/25 19:37 - */ -import org.docx4j.openpackaging.packages.WordprocessingMLPackage; -import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart; -import org.docx4j.wml.*; - -import java.io.File; -import java.math.BigInteger; -import java.util.List; - -public class Docx4jInsertParagraph { - public static void main(String[] args) throws Exception { - // 加载现有的 Word 文档 - WordprocessingMLPackage wordPackage = WordprocessingMLPackage.load(new File("C:\\Users\\hongawen\\Desktop\\base_template.docx")); - MainDocumentPart documentPart = wordPackage.getMainDocumentPart(); - - // 获取文档中的所有段落 - List paragraphs = documentPart.getContent(); - - // 在中间插入一个新段落 - int insertIndex = paragraphs.size() / 2; - P newParagraph = createParagraph("This is a new paragraph inserted in the middle."); - paragraphs.add(insertIndex, newParagraph); - - // 保存修改后的文档 - wordPackage.save(new File("example_modified.docx")); - } - - private static P createParagraph(String text) { - ObjectFactory factory = new ObjectFactory(); - P paragraph = factory.createP(); - R run = factory.createR(); - Text t = factory.createText(); - t.setValue(text); - run.getContent().add(t); - paragraph.getContent().add(run); - return paragraph; - } -} \ No newline at end of file diff --git a/detection/src/main/java/com/njcn/gather/report/utils/WordUtil.java b/detection/src/main/java/com/njcn/gather/report/utils/WordUtil.java deleted file mode 100644 index 450add31..00000000 --- a/detection/src/main/java/com/njcn/gather/report/utils/WordUtil.java +++ /dev/null @@ -1,144 +0,0 @@ -package com.njcn.gather.report.utils; - -import org.apache.poi.xwpf.usermodel.*; -import org.apache.xmlbeans.XmlCursor; -import org.docx4j.openpackaging.packages.WordprocessingMLPackage; -import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * @author hongawen - * @version 1.0 - * @data 2025/1/9 20:52 - */ -public class WordUtil { - - - /** - * 将源文档的内容(包括段落、表格等)追加到目标文档中 - * - * @param target 目标文档 - * @param source 源文档 - */ - public static void appendDocument(XWPFDocument target, XWPFDocument source) { - // 在追加内容之前,插入分页符 -// insertPageBreak(target); - // 遍历源文档的所有块(段落、表格等) - source.getBodyElements().forEach(bodyElement -> { - switch (bodyElement.getElementType()) { - case PARAGRAPH: - // 处理段落 - XWPFParagraph sourceParagraph = (XWPFParagraph) bodyElement; - XWPFParagraph newParagraph = target.createParagraph(); - newParagraph.getCTP().set(sourceParagraph.getCTP()); - break; - case TABLE: - // 处理表格 - XWPFTable sourceTable = (XWPFTable) bodyElement; - XWPFTable newTable = target.createTable(); - newTable.getCTTbl().set(sourceTable.getCTTbl()); - break; - default: - // 针对其他类型(如图片、页眉页脚等)可以扩展处理逻辑 - System.out.println("未处理的内容类型:" + bodyElement.getElementType()); - break; - } - }); - } - - - /** - * 替换表格中的占位符 - * @param document 文档 - * @param placeholders 待替换的占位符 - */ - public static void replacePlaceholdersInTables(XWPFDocument document, Map placeholders) { - for (XWPFTable table : document.getTables()) { - for (XWPFTableRow row : table.getRows()) { - for (XWPFTableCell cell : row.getTableCells()) { - for (XWPFParagraph paragraph : cell.getParagraphs()) { - List runs = paragraph.getRuns(); - if (runs != null) { - for (XWPFRun run : runs) { - String text = run.getText(0); - if (text != null) { - for (Map.Entry entry : placeholders.entrySet()) { - text = text.replace(entry.getKey(), entry.getValue()); - } - run.setText(text, 0); - } - } - } - } - } - } - } - } - - - /** - * 替换段落中的占位符 - * @param document 文档 - * @param placeholders 待替换的占位符 - */ - public static void replacePlaceholdersInParagraphs(XWPFDocument document, Map placeholders) { - for (XWPFParagraph paragraph : document.getParagraphs()) { - List runs = paragraph.getRuns(); - if (runs != null) { - for (XWPFRun run : runs) { - String text = run.getText(0); - if (text != null) { - for (Map.Entry entry : placeholders.entrySet()) { - text = text.replace(entry.getKey(), entry.getValue()); - } - run.setText(text, 0); - } - } - } - } - } - - /** - * 替换文档中的占位符 - * @param document 文档 - * @param placeholders 待替换的占位符 - */ - public static void replacePlaceholders(XWPFDocument document, Map placeholders) { - replacePlaceholdersInParagraphs(document,placeholders); - replacePlaceholdersInTables(document,placeholders); - } - - - public static List findHeadingLevel5Paragraphs(XWPFDocument document) { - List headingLevel5Paragraphs = new ArrayList<>(); - for (XWPFParagraph paragraph : document.getParagraphs()) { - String style = paragraph.getStyle(); - if ("5".equals(style)) { - headingLevel5Paragraphs.add(paragraph); - } - } - return headingLevel5Paragraphs; - } - - - /** - * 获取段落的位置(通过遍历bodyElements) - */ - public static int getBodyElementPosition(XWPFDocument document, XWPFParagraph paragraph) { - List bodyElements = document.getBodyElements(); - for (int i = 0; i < bodyElements.size(); i++) { - if (bodyElements.get(i) instanceof XWPFParagraph && bodyElements.get(i).equals(paragraph)) { - return i; - } - } - return -1; - } - - - -} diff --git a/entrance/src/main/resources/model/report_table.docx b/entrance/src/main/resources/model/report_table.docx index ded22ce67a26289d7f3a62c9c29358848735e73e..f6d53866d1a93774af8bbdd926c017df7276e4e4 100644 GIT binary patch delta 19381 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