From ebdbbb3f1390f9b3046b03466b7c74692667de90 Mon Sep 17 00:00:00 2001 From: guoshengxiong <1923636941@qq.com> Date: Tue, 7 Jan 2025 18:48:03 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8C=85=E5=A4=B4bug=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...eringQualityInspectionOrderController.java | 4 +- .../ConfinedSpaceOperationController.java | 2 +- .../controller/FirstOrderFireController.java | 2 +- .../controller/HeightPermitController.java | 2 +- .../LiftingOperationController.java | 2 +- ...ndestructiveTestOrderTicketController.java | 2 +- .../WitnessSamplingRecordController.java | 2 +- .../ExamQuestionBankController.java | 6 +- .../exam/controller/ExamWorkerController.java | 117 ++++++++---------- .../java/com/zhgd/xmgl/util/EasyPoiUtil.java | 62 +++++++++- src/main/resources/template/下载试卷模板.docx | Bin 29323 -> 29498 bytes 11 files changed, 122 insertions(+), 79 deletions(-) diff --git a/src/main/java/com/zhgd/xmgl/modules/baotou/controller/CivilEngineeringQualityInspectionOrderController.java b/src/main/java/com/zhgd/xmgl/modules/baotou/controller/CivilEngineeringQualityInspectionOrderController.java index f50aaae91..f64ac07a1 100644 --- a/src/main/java/com/zhgd/xmgl/modules/baotou/controller/CivilEngineeringQualityInspectionOrderController.java +++ b/src/main/java/com/zhgd/xmgl/modules/baotou/controller/CivilEngineeringQualityInspectionOrderController.java @@ -3,7 +3,6 @@ package com.zhgd.xmgl.modules.baotou.controller; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.IdUtil; -import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; @@ -18,7 +17,6 @@ import com.zhgd.xmgl.modules.basicdata.service.ISystemUserService; import com.zhgd.xmgl.util.EasyPoiUtil; import com.zhgd.xmgl.util.Fileutils; import com.zhgd.xmgl.util.FlowUtil; -import com.zhgd.xmgl.util.PathUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; @@ -322,7 +320,7 @@ public class CivilEngineeringQualityInspectionOrderController { } } File tempFile = File.createTempFile(IdUtil.simpleUUID(), ".docx"); - EasyPoiUtil.exportWord(map, url, tempFile); + EasyPoiUtil.exportNewLineWord(map, url, tempFile); EasyPoiUtil.wordToPdfExport(response, tempFile); } diff --git a/src/main/java/com/zhgd/xmgl/modules/baotou/controller/ConfinedSpaceOperationController.java b/src/main/java/com/zhgd/xmgl/modules/baotou/controller/ConfinedSpaceOperationController.java index 234b1bf6d..533a19ed7 100644 --- a/src/main/java/com/zhgd/xmgl/modules/baotou/controller/ConfinedSpaceOperationController.java +++ b/src/main/java/com/zhgd/xmgl/modules/baotou/controller/ConfinedSpaceOperationController.java @@ -245,7 +245,7 @@ public class ConfinedSpaceOperationController { } } File tempFile = File.createTempFile(IdUtil.simpleUUID(), ".docx"); - EasyPoiUtil.exportWord(map, url, tempFile); + EasyPoiUtil.exportNewLineWord(map, url, tempFile); EasyPoiUtil.wordToPdfExport(response, tempFile); } diff --git a/src/main/java/com/zhgd/xmgl/modules/baotou/controller/FirstOrderFireController.java b/src/main/java/com/zhgd/xmgl/modules/baotou/controller/FirstOrderFireController.java index c88ba207e..e5dfb90b4 100644 --- a/src/main/java/com/zhgd/xmgl/modules/baotou/controller/FirstOrderFireController.java +++ b/src/main/java/com/zhgd/xmgl/modules/baotou/controller/FirstOrderFireController.java @@ -324,7 +324,7 @@ public class FirstOrderFireController { } } File tempFile = File.createTempFile(IdUtil.simpleUUID(), ".docx"); - EasyPoiUtil.exportWord(map, url, tempFile); + EasyPoiUtil.exportNewLineWord(map, url, tempFile); EasyPoiUtil.wordToPdfExport(response, tempFile); } diff --git a/src/main/java/com/zhgd/xmgl/modules/baotou/controller/HeightPermitController.java b/src/main/java/com/zhgd/xmgl/modules/baotou/controller/HeightPermitController.java index 67e2b73e9..1bd6ed11b 100644 --- a/src/main/java/com/zhgd/xmgl/modules/baotou/controller/HeightPermitController.java +++ b/src/main/java/com/zhgd/xmgl/modules/baotou/controller/HeightPermitController.java @@ -240,7 +240,7 @@ public class HeightPermitController { } } File tempFile = File.createTempFile(IdUtil.simpleUUID(), ".docx"); - EasyPoiUtil.exportWord(map, url, tempFile); + EasyPoiUtil.exportNewLineWord(map, url, tempFile); EasyPoiUtil.wordToPdfExport(response, tempFile); } diff --git a/src/main/java/com/zhgd/xmgl/modules/baotou/controller/LiftingOperationController.java b/src/main/java/com/zhgd/xmgl/modules/baotou/controller/LiftingOperationController.java index 16931f8a9..ca6c292ee 100644 --- a/src/main/java/com/zhgd/xmgl/modules/baotou/controller/LiftingOperationController.java +++ b/src/main/java/com/zhgd/xmgl/modules/baotou/controller/LiftingOperationController.java @@ -265,7 +265,7 @@ public class LiftingOperationController { } File tempFile = File.createTempFile(IdUtil.simpleUUID(), ".docx"); - EasyPoiUtil.exportWord(map, url, tempFile); + EasyPoiUtil.exportNewLineWord(map, url, tempFile); EasyPoiUtil.wordToPdfExport(response, tempFile); } diff --git a/src/main/java/com/zhgd/xmgl/modules/baotou/controller/NondestructiveTestOrderTicketController.java b/src/main/java/com/zhgd/xmgl/modules/baotou/controller/NondestructiveTestOrderTicketController.java index 3c9da57a3..fbda433fb 100644 --- a/src/main/java/com/zhgd/xmgl/modules/baotou/controller/NondestructiveTestOrderTicketController.java +++ b/src/main/java/com/zhgd/xmgl/modules/baotou/controller/NondestructiveTestOrderTicketController.java @@ -337,7 +337,7 @@ public class NondestructiveTestOrderTicketController { } } File tempFile = File.createTempFile(IdUtil.simpleUUID(), ".docx"); - EasyPoiUtil.exportWord(map, url, tempFile); + EasyPoiUtil.exportNewLineWord(map, url, tempFile); EasyPoiUtil.wordToPdfExport(response, tempFile); } diff --git a/src/main/java/com/zhgd/xmgl/modules/baotou/controller/WitnessSamplingRecordController.java b/src/main/java/com/zhgd/xmgl/modules/baotou/controller/WitnessSamplingRecordController.java index 1e886413e..4e7a84b24 100644 --- a/src/main/java/com/zhgd/xmgl/modules/baotou/controller/WitnessSamplingRecordController.java +++ b/src/main/java/com/zhgd/xmgl/modules/baotou/controller/WitnessSamplingRecordController.java @@ -183,7 +183,7 @@ public class WitnessSamplingRecordController { url = Fileutils.getExportTemplateFile("excel/work/见证取样记录模板.docx").getAbsolutePath(); File tempFile = File.createTempFile(IdUtil.simpleUUID(), ".docx"); - EasyPoiUtil.exportWord(map, url, tempFile); + EasyPoiUtil.exportNewLineWord(map, url, tempFile); EasyPoiUtil.wordToPdfExport(response, tempFile); } diff --git a/src/main/java/com/zhgd/xmgl/modules/exam/controller/ExamQuestionBankController.java b/src/main/java/com/zhgd/xmgl/modules/exam/controller/ExamQuestionBankController.java index 77bc3a368..a2aa0fc85 100644 --- a/src/main/java/com/zhgd/xmgl/modules/exam/controller/ExamQuestionBankController.java +++ b/src/main/java/com/zhgd/xmgl/modules/exam/controller/ExamQuestionBankController.java @@ -363,7 +363,7 @@ public class ExamQuestionBankController { List examQuestionOptionList = new ArrayList<>(); int index = 0; for (Map examQuestionBankImport : examQuestionBankImports) { - if (StringUtils.isNotBlank(examQuestionBankImport.get("*科目名称").trim())) { + if (examQuestionBankImport.get("*科目名称") != null && StringUtils.isNotBlank(examQuestionBankImport.get("*科目名称").trim())) { index++; List subjects = subList.stream().filter(s -> s.getName().equals(examQuestionBankImport.get("*科目名称").trim())).collect(Collectors.toList()); if (subjects == null || subjects.size() == 0) { @@ -395,7 +395,7 @@ public class ExamQuestionBankController { examQuestionBank.setUpdateBy(systemUser.getUserId().toString()); examQuestionBank.setUpdateTime(examQuestionBank.getCreateTime()); examQuestionBankList.add(examQuestionBank); - } else if (StringUtils.isNotBlank(examQuestionBankImport.get("*选项代码").trim())) { + } else if (examQuestionBankImport.get("*选项代码") != null && StringUtils.isNotBlank(examQuestionBankImport.get("*选项代码").trim())) { ExamQuestionOption examQuestionOption = new ExamQuestionOption(); examQuestionOption.setQuestionId((long) index); examQuestionOption.setOptionCode(examQuestionBankImport.get("*选项代码").trim()); @@ -416,7 +416,7 @@ public class ExamQuestionBankController { } return Result.ok("文件导入成功!数据行数:" + examQuestionBankImports.size()); } catch (Exception e) { - log.error(e.getMessage()); + log.error("通过excel导入题目管理信息:", e); return Result.error(e.getMessage()); } finally { try { diff --git a/src/main/java/com/zhgd/xmgl/modules/exam/controller/ExamWorkerController.java b/src/main/java/com/zhgd/xmgl/modules/exam/controller/ExamWorkerController.java index ca16aea8d..f6e3ddda2 100644 --- a/src/main/java/com/zhgd/xmgl/modules/exam/controller/ExamWorkerController.java +++ b/src/main/java/com/zhgd/xmgl/modules/exam/controller/ExamWorkerController.java @@ -1,9 +1,11 @@ package com.zhgd.xmgl.modules.exam.controller; -import cn.afterturn.easypoi.word.WordExportUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONArray; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.zhgd.annotation.OperLog; @@ -15,24 +17,21 @@ import com.zhgd.xmgl.modules.exam.service.IExamTrainRecordService; import com.zhgd.xmgl.modules.exam.service.IExamTrainService; import com.zhgd.xmgl.modules.exam.vo.ExamQuestionBankVo; import com.zhgd.xmgl.modules.exam.vo.ExamTrainRecordVo; +import com.zhgd.xmgl.util.EasyPoiUtil; import com.zhgd.xmgl.util.Fileutils; -import com.zhgd.xmgl.util.WordUtils; +import com.zhgd.xmgl.util.PathUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.MapUtils; -import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import springfox.documentation.annotations.ApiIgnore; import javax.servlet.http.HttpServletResponse; import java.math.BigDecimal; -import java.net.URLDecoder; -import java.net.URLEncoder; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -175,11 +174,12 @@ public class ExamWorkerController { String recordId = MapUtils.getString(param, "recordId"); List questionBankVos = examTrainRecordService.getAnswerDetail(param); Map> typeMap = questionBankVos.stream().collect(Collectors.groupingBy(ExamQuestionBankVo::getType)); + HashMap imageMap = new HashMap<>(); //封装数据 Map params = new HashMap(); for (Map.Entry> entry : typeMap.entrySet()) { Integer key = entry.getKey(); - int i = 1; + int[] i = {1}; List list = entry.getValue(); if (CollUtil.isNotEmpty(list)) { ExamQuestionBankVo one = list.get(0); @@ -188,83 +188,68 @@ public class ExamWorkerController { BigDecimal total = NumberUtil.mul(list.size(), score); if (key == 1) { params.put("t1", "一、单选题:(每题" + score + "分,共计" + total + "分)"); - //遍历题目 - for (ExamQuestionBankVo question : list) { - content.append(" ").append(i++).append("、").append(question.getQuestionName()).append("\n").append(" "); - List optionList = question.getOptionList(); - //遍历选项 - for (ExamQuestionOption option : optionList) { - content.append(option.getOptionCode()).append("、").append(option.getOptionDesc()).append(" "); - } - content.append("\n"); - } + addOption(list, content, i, imageMap); params.put("c1", content.toString()); } else if (key == 2) { params.put("t2", "二、多选题:(每题" + one.getScore() + "分,共计" + total + "分、漏选少选得" + NumberUtil.div(one.getScore(), 2, 2) + "分,错选不得分。)"); //遍历题目 - for (ExamQuestionBankVo question : list) { - content.append(" ").append(i++).append("、").append(question.getQuestionName()).append("\n").append(" "); - List optionList = question.getOptionList(); - //遍历选项 - for (ExamQuestionOption option : optionList) { - content.append(option.getOptionCode()).append("、").append(option.getOptionDesc()).append(" "); - } - content.append("\n"); - } + addOption(list, content, i, imageMap); params.put("c2", content.toString()); } else { params.put("t3", "三、判断题(每题" + one.getScore() + "分,共" + total + "分,正确:打√,错误:打×)"); //遍历题目 - for (ExamQuestionBankVo question : list) { - content.append(" ").append(i++).append("、").append(question.getQuestionName()).append("\n").append(" "); - List optionList = question.getOptionList(); - //遍历选项 - for (ExamQuestionOption option : optionList) { - content.append(option.getOptionCode()).append("、").append(option.getOptionDesc()).append(" "); - } - content.append("\n"); - } + addOption(list, content, i, imageMap); params.put("c3", content.toString()); } } } - List> list = new ArrayList>(); - Map obj; - for (int i = 0; i < 5; i++) { - obj = new HashMap(); - obj.put("name", "abc-" + i); - obj.put("age", i); - obj.put("sex", "男-" + i); - list.add(obj); - } - params.put("objs", list); - String url; -// url = "C:\\Users\\Administrator\\Desktop\\下载试卷模板.docx"; - url = Fileutils.getExportTemplateFile("template/下载试卷模板.docx").getAbsolutePath(); -// - //jar包获取不到文件路径 - //URLDecoder.decode() 解决获取中文名称文件路径乱码 - String templatePath = URLDecoder.decode(FileUtil.file(url).getPath(), "UTF-8"); - + String tempUrl = Fileutils.getExportTemplateFile("template/下载试卷模板.docx").getAbsolutePath(); +// String tempUrl = "C:\\Users\\Administrator\\Desktop\\下载试卷模板.docx"; //生成word文档流 - XWPFDocument doc = WordExportUtil.exportWord07(templatePath, params); - //文本换行 - WordUtils.addBreakInCell(doc.getParagraphs()); - //设置响应体内容类型 - response.setContentType("application/octet-stream"); - //添加响应头 - response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("下载试卷.docx", "UTF-8")); - //暴露新添加的响应头 - response.setHeader("Access-Control-Expose-Headers", "Content-Disposition"); - //将word文档流输出到输出流中 - doc.write(response.getOutputStream()); - //关闭流 - doc.close(); + EasyPoiUtil.exportNewLineWord(response, params, FileUtil.file(tempUrl)); + } catch (Exception e) { log.error("导出试卷出现异常", e); } } + /** + * 导出word添加题目和选项 + * + * @param list + * @param content + * @param i + * @param imageMap + */ + private void addOption(List list, StringBuilder content, int[] i, HashMap imageMap) { + //遍历题目 + for (ExamQuestionBankVo question : list) { + content.append(" ").append(i[0]).append("、"); + i[0] += 1; + if (StrUtil.isNotBlank(question.getPic())) { + JSONArray ja = JSON.parseArray(question.getPic()); + if (CollUtil.isNotEmpty(ja)) { + //保存图片占位符 + /*try { + String imageKey = "image" + i[0]; + imageMap.put(imageKey, EasyPoiUtil.imgFormatting(PathUtil.getBasePath() + "/" + ja.getJSONObject(0).getString("url"), 18, 18)); + content.append("{{" + imageKey + "}}"); + } catch (Exception e) { + log.error("导出word添加题目和选项错误", e); + }*/ + } + } + content.append(question.getQuestionName()).append("\n").append(" "); + List optionList = question.getOptionList(); + //遍历选项 + for (ExamQuestionOption option : optionList) { + content.append(option.getOptionCode()).append("、").append(option.getOptionDesc()).append(" "); + } + content.append("\n"); + } + } + + } diff --git a/src/main/java/com/zhgd/xmgl/util/EasyPoiUtil.java b/src/main/java/com/zhgd/xmgl/util/EasyPoiUtil.java index 68166e8ea..ba4173a9d 100644 --- a/src/main/java/com/zhgd/xmgl/util/EasyPoiUtil.java +++ b/src/main/java/com/zhgd/xmgl/util/EasyPoiUtil.java @@ -7,13 +7,43 @@ import com.documents4j.api.DocumentType; import com.documents4j.api.IConverter; import com.documents4j.job.LocalConverter; import com.zhgd.xmgl.modules.basicdata.entity.SystemUser; +import lombok.extern.slf4j.Slf4j; import org.apache.poi.xwpf.usermodel.XWPFDocument; import javax.servlet.http.HttpServletResponse; import java.io.*; +import java.net.URLDecoder; +import java.net.URLEncoder; import java.util.Map; +@Slf4j public class EasyPoiUtil { + /** + * 导出word + * + * @param response + * @param params + * @param file + * @throws Exception + */ + public static void exportNewLineWord(HttpServletResponse response, Map params, File file) throws Exception { + try { + XWPFDocument doc = WordExportUtil.exportWord07(URLDecoder.decode(file.getPath(), "UTF-8"), params); + WordUtils.addBreakInCell(doc.getParagraphs()); + //设置响应体内容类型 + response.setContentType("application/octet-stream"); + //添加响应头 + response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("下载试卷.docx", "UTF-8")); + //暴露新添加的响应头 + response.setHeader("Access-Control-Expose-Headers", "Content-Disposition"); + //将word文档流输出到输出流中 + doc.write(response.getOutputStream()); + //关闭流 + doc.close(); + } catch (Exception e) { + log.error("exportNewLineWord:", e); + } + } /** * 根据模板导出word @@ -29,7 +59,27 @@ public class EasyPoiUtil { doc.write(fos); fos.close(); } catch (Exception e) { - e.printStackTrace(); + log.error("exportWord:", e); + } + } + + /** + * 根据模板导出word会换行的 + * + * @param map + * @param url + * @param tempFile + */ + public static void exportNewLineWord(Map map, String url, File tempFile) { + try { + XWPFDocument doc = WordExportUtil.exportWord07(url, map); + //文本换行 + WordUtils.addBreakInCell(doc.getParagraphs()); + FileOutputStream fos = new FileOutputStream(tempFile); + doc.write(fos); + fos.close(); + } catch (Exception e) { + log.error("exportNewLineWord:", e); } } @@ -84,10 +134,20 @@ public class EasyPoiUtil { return image; } + /** + * 导出项目子账号签名图片 + * + * @param u + * @param width + * @param height + * @return + */ public static Object getImgFromUser(SystemUser u, int width, int height) { if (u != null && StrUtil.isNotBlank(u.getElectronicSignature())) { return EasyPoiUtil.imgFormatting(PathUtil.getBasePath() + "/" + u.getElectronicSignature(), width, height); } return null; } + + } diff --git a/src/main/resources/template/下载试卷模板.docx b/src/main/resources/template/下载试卷模板.docx index 339d7ee9106823541cbc19a293f6b442ce1ecc0a..bb425ec6718f08fbb69ad49adeb1f869bebfe7a7 100644 GIT binary patch delta 7326 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

Bl3n&+$ayJo;`3OHJ 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 LqkeM!2lD>_NavgV delta 7226 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 L2L_AxKl1+pc*u4&