From f0fe9c58086e751106c16b3cfc040a6991668269 Mon Sep 17 00:00:00 2001 From: wangxy <1481820854@qq.com> Date: Thu, 17 Apr 2025 14:49:05 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E8=87=AA=E6=9F=A5=E8=87=AA=E8=AF=84?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=E5=AF=BC=E5=85=A5=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../manager/CheckReportManager.java | 77 +++++++++++++++++++ .../system/check/CheckReportController.java | 16 ++++ .../system/checkReport/checkReport.html | 54 +++++++++++++ 3 files changed, 147 insertions(+) diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/manager/CheckReportManager.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/manager/CheckReportManager.java index 8dfabdc..be901ee 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/manager/CheckReportManager.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/manager/CheckReportManager.java @@ -3,6 +3,11 @@ package com.ruoyi.web.controller.manager; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.text.CharSequenceUtil; +import cn.hutool.core.text.StrPool; +import cn.hutool.http.HttpStatus; +import cn.hutool.poi.excel.ExcelUtil; +import cn.hutool.poi.excel.ExcelWriter; +import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.entity.SysDictData; import com.ruoyi.common.utils.ShiroUtils; import com.ruoyi.system.domain.check.TdCheckReport; @@ -11,11 +16,17 @@ import com.ruoyi.system.domain.check.dto.*; import com.ruoyi.system.service.ISysDictDataService; import com.ruoyi.system.service.check.TdCheckReportService; import com.ruoyi.system.service.check.TdCheckTypeService; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.util.IOUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.net.URLEncoder; import java.util.*; /** @@ -28,6 +39,7 @@ import java.util.*; * @description 检查报告 */ @Component +@Slf4j public class CheckReportManager { @@ -43,6 +55,10 @@ public class CheckReportManager { + @Resource + private SysAreaManager sysAreaManager; + + public List selectTdCheckReportList(CheckReportDTO tdCheckReport) { return checkReportService.selectTdCheckReportList(tdCheckReport); } @@ -121,4 +137,65 @@ public class CheckReportManager { } + public void exportDetail(String id, HttpServletResponse response) throws IOException { + TdCheckReport tdCheckReport = checkReportService.getById(id); + TdCheckReportDTO tdCheckReportDto = Convert.convert(TdCheckReportDTO.class, tdCheckReport); + tdCheckReportDto.setFramework(sysAreaManager.getAreaName(tdCheckReportDto.getFramework())); + tdCheckReportDto.setArea(sysAreaManager.getAreaName(tdCheckReportDto.getArea())); + List list = checkTypeService.lambdaQuery().eq(TdCheckType::getCheckId, tdCheckReport.getCheckId()).list(); + if (CollUtil.isNotEmpty(list)) { + List tdCheckTypeDtoS = Convert.toList(TdCheckTypeDTO.class, list); + tdCheckReportDto.setCheckTypeDTOS(tdCheckTypeDtoS); + } + try { + String fileName = URLEncoder.encode(tdCheckReport.getCheckId() + ".xlsx", "UTF-8"); + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName); + // 4. 使用Hutool导出Excel + ExcelWriter writer = ExcelUtil.getWriter(true); + // 1. 先写入主表数据 + writer.renameSheet("自查信息"); + writer.addHeaderAlias("adduser", "检查人员"); + writer.addHeaderAlias("depart", "检查单位"); + writer.addHeaderAlias("checkStartTime", "检查开始时间"); + writer.addHeaderAlias("checkEndTime", "检查结束时间"); + writer.addHeaderAlias("framework", "所属市州"); + writer.addHeaderAlias("area", "所属区县"); + writer.addHeaderAlias("totalScore", "实有项目总分"); + writer.addHeaderAlias("percentageScore", "得分占比"); + // 只导出有别名的字段 + writer.setOnlyAlias(true); + // 2.2 写入主表数据(只有一条记录) + writer.write(CollUtil.newArrayList(tdCheckReportDto), true); + // 3. 写入子表信息(多条记录) + writer.setSheet("自查类信息"); + // 3.1 设置子表表头 + writer.addHeaderAlias("checkItems", "自查项"); + writer.addHeaderAlias("typeContent", "自查内容"); + writer.addHeaderAlias("score", "分值"); + writer.addHeaderAlias("realScore", "得分"); + writer.addHeaderAlias("deductionCriteria", "扣分标准"); + // 只导出有别名的字段 + writer.setOnlyAlias(true); + // 3.2 写入子表数据 + writer.write(tdCheckReportDto.getCheckTypeDTOS(), true); + // 4. 可选:调整列宽自动适应 + writer.autoSizeColumnAll(); + // 5. 输出到浏览器 + writer.flush(response.getOutputStream(), true); + writer.close(); + } catch (Exception e) { + log.error("文件下载失败:{}", e.getMessage(), e); + try { + response.setContentType("application/json"); + response.getWriter().print("{\"code\":500,\"msg\":\"导出失败:" + e.getMessage() + "\"}"); + } catch (IOException ex) { + log.error("返回错误信息失败", ex); + } + } + } + + + } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/check/CheckReportController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/check/CheckReportController.java index 3980835..d63f1f2 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/check/CheckReportController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/check/CheckReportController.java @@ -11,12 +11,15 @@ import com.ruoyi.system.domain.check.dto.CheckReportDTO; import com.ruoyi.system.domain.check.dto.TdCheckReportDTO; import com.ruoyi.web.controller.manager.CheckReportManager; import com.ruoyi.web.controller.manager.SysAreaManager; +import io.swagger.annotations.ApiOperation; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; import java.util.List; /** @@ -76,6 +79,19 @@ public class CheckReportController extends BaseController { return util.exportExcel(tdCheckReports, "检查报告管理数据"); } + /** + * 导出检查信息 + * @param checkId + * @param response + * @throws IOException + */ + @RequiresPermissions("system:check:exportDetail") + @Log(title = "检查报告", businessType = BusinessType.EXPORT) + @GetMapping("/exportDetail") + public void exportDetail(@RequestParam String checkId, HttpServletResponse response) throws IOException { + checkReportManager.exportDetail(checkId, response); + } + /** * 新增检查报告 */ diff --git a/ruoyi-admin/src/main/resources/templates/system/checkReport/checkReport.html b/ruoyi-admin/src/main/resources/templates/system/checkReport/checkReport.html index 4937203..ed76fd0 100644 --- a/ruoyi-admin/src/main/resources/templates/system/checkReport/checkReport.html +++ b/ruoyi-admin/src/main/resources/templates/system/checkReport/checkReport.html @@ -80,6 +80,7 @@ var detailFlag = [[${@permission.hasPermi('system:check:detail')}]] var selfCheckFlag = [[${@permission.hasPermi('system:check:selfcheck')}]]; var removeFlag = [[${@permission.hasPermi('system:check:remove')}]]; + var exportDetailFlag = [[${@permission.hasPermi('system:check:exportDetail')}]]; var checkStateDatas = [[${@dict.getType('sys_check_state')}]]; var prefix = ctx + "system/checkReport"; let datas = [] @@ -169,6 +170,7 @@ align: 'center', formatter: function(value, row, index) { var actions = []; + actions.push('导出 '); actions.push('详情 '); actions.push('编辑 '); actions.push('删除'); @@ -243,6 +245,58 @@ // function openEdit(id){ // $.modal.openTab("修改" + table.options.modalName, prefix + '/edit' + '/' + id); // } + + + /** + * 导出明细 + */ + function exportDetail(checkId) { + // 显示加载中提示 + $.modal.loading("正在生成导出文件,请稍候..."); + // 创建iframe + var iframe = document.createElement('iframe'); + iframe.style.display = 'none'; + iframe.src = prefix + '/exportDetail?checkId=' + checkId; + // 记录开始时间 + var startTime = new Date().getTime(); + // 定时检查iframe状态 + var checkInterval = setInterval(function() { + try { + var iframeDoc = iframe.contentDocument || iframe.contentWindow.document; + // 如果iframe内容加载完成 + if (iframeDoc.readyState === 'complete') { + clearInterval(checkInterval); + $.modal.closeLoading(); + // 检查是否是错误响应 + var responseText = iframeDoc.body.textContent || iframeDoc.body.innerText; + if (responseText && responseText.startsWith('{"code":500')) { + var result = JSON.parse(responseText); + $.modal.alertError(result.msg); + } + // 移除iframe + setTimeout(function() { + document.body.removeChild(iframe); + }, 100); + } + // 超时处理(10秒超时) + if (new Date().getTime() - startTime > 10000) { + clearInterval(checkInterval); + $.modal.closeLoading(); + document.body.removeChild(iframe); + $.modal.alertError("导出超时,请重试"); + } + } catch(e) { + // 跨域异常通常表示文件下载成功 + clearInterval(checkInterval); + $.modal.closeLoading(); + setTimeout(function() { + document.body.removeChild(iframe); + }, 100); + } + }, 200); + document.body.appendChild(iframe); + } +