diff --git a/ht/src/main/java/com/ccsens/ht/api/PatientReportExportController.java b/ht/src/main/java/com/ccsens/ht/api/PatientReportExportController.java index 0e19d4c9..59a88088 100644 --- a/ht/src/main/java/com/ccsens/ht/api/PatientReportExportController.java +++ b/ht/src/main/java/com/ccsens/ht/api/PatientReportExportController.java @@ -11,10 +11,7 @@ import com.ccsens.util.bean.dto.QueryDto; import io.swagger.annotations.*; import lombok.extern.slf4j.Slf4j; import org.apache.poi.ss.usermodel.Workbook; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; @@ -70,19 +67,19 @@ public class PatientReportExportController { return JsonResponse.newInstance().ok(export); } - @MustLogin - @DoctorAudit +// @MustLogin +// @DoctorAudit @ApiOperation(value = "导出指定id的报告单分析",notes = "导出指定id的报告单分析") @ApiImplicitParams({ @ApiImplicitParam(name = "json", value = "导出指定id的报告单分析", required = true) }) - @RequestMapping(value="/exportAnalyse", method = RequestMethod.POST) - public void exportAnalyse(@RequestBody @ApiParam @Valid QueryDto> param, HttpServletResponse response) throws IOException { + @RequestMapping(value="/exportAnalyse", method = RequestMethod.GET) + public void exportAnalyse(@RequestParam(value = "ids")@ApiParam @Valid List ids, HttpServletResponse response) throws IOException { //查询报告单信息 - log.info("导出指定报告单分析:{}", param); - Workbook workbook = patientReportService.exportAnalyse(param.getParam(), param.getUserId()); + log.info("导出指定报告单分析:{}", ids); + Workbook workbook = patientReportService.exportAnalyse(ids); log.info("导出报告单分析结束"); - String fileName = "报告单信息"; + String fileName = "报告单信息.xlsx"; response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, CharsetUtil.UTF_8)); workbook.write(response.getOutputStream()); } diff --git a/ht/src/main/java/com/ccsens/ht/bean/dto/PatientReportDto.java b/ht/src/main/java/com/ccsens/ht/bean/dto/PatientReportDto.java index 0111fdb0..dd2fa278 100644 --- a/ht/src/main/java/com/ccsens/ht/bean/dto/PatientReportDto.java +++ b/ht/src/main/java/com/ccsens/ht/bean/dto/PatientReportDto.java @@ -99,8 +99,18 @@ public class PatientReportDto { } + @ApiModel("导出报告单分析-请求") + @Data public static class ExportSpecial{ + @ApiModelProperty("报告单ID") private Long id; + +// public ExportSpecial() { +// } +// +// public ExportSpecial(Long id) { +// this.id = id; +// } } /**医生对报告单权限*/ diff --git a/ht/src/main/java/com/ccsens/ht/bean/vo/PatientReportVo.java b/ht/src/main/java/com/ccsens/ht/bean/vo/PatientReportVo.java index b777a8c7..bbf1809a 100644 --- a/ht/src/main/java/com/ccsens/ht/bean/vo/PatientReportVo.java +++ b/ht/src/main/java/com/ccsens/ht/bean/vo/PatientReportVo.java @@ -14,9 +14,9 @@ import java.math.BigDecimal; import java.util.*; /** - * @program: ptpro + * @program: ht * @description: - * @author: wu huijuan + * @author: whj * @create: 2019/10/31 10:28 */ public class PatientReportVo { @@ -604,8 +604,7 @@ public class PatientReportVo { } } - /**医生对报告单权限*/ - @ApiModel("PatientReportVoAuthority") + @ApiModel("医生对报告单权限") @Data public static class Authority{ @ApiModelProperty("对报告单的操作权限 0:仅查看 1: 可修改 2:可审查") @@ -735,4 +734,63 @@ public class PatientReportVo { @ApiModelProperty("答案") private String answer; } + + @ApiModel("报告单分析导出-vo") + @Data + public static class Analyse{ + @ApiModelProperty("报告单ID") + private Long id; + @ApiModelProperty("测评日期") + private Long reportTime; + @ApiModelProperty("患者名字") + private String patientName; + @ApiModelProperty("性别") + private Byte sex; + @ApiModelProperty("年龄") + private Byte patientAge; + @ApiModelProperty("文化程度") + private Byte educationalStatus; + @ApiModelProperty("职业") + private Byte career; + @ApiModelProperty("临床诊断") + private String clinicalDiagnosis; + @ApiModelProperty("严重程度") + private Byte pasi; + @ApiModelProperty("mmse分数") + private List mmseScores; + @ApiModelProperty("moca分数") + private List mocaScores; + @ApiModelProperty("总分") + private List totalScores; + + } + + + @ApiModel("mmse分数-导出分析") + @Data + public static class MMSEScore{ + @ApiModelProperty("code") + private String code; + @ApiModelProperty("分数") + private BigDecimal score; + } + + @ApiModel("moca分数-导出分析") + @Data + public static class MoCAScore{ + @ApiModelProperty("题目排序") + private int sort; + @ApiModelProperty("分数") + private BigDecimal score; + } + + @ApiModel("量表总分数-导出分析") + @Data + public static class TotalScore{ + @ApiModelProperty("量表类型") + private String evaluationCode; + @ApiModelProperty("总评分") + private BigDecimal totalScore; + } + } diff --git a/ht/src/main/java/com/ccsens/ht/persist/dao/HtPatientReportDao.java b/ht/src/main/java/com/ccsens/ht/persist/dao/HtPatientReportDao.java index c6a987bd..336bd517 100644 --- a/ht/src/main/java/com/ccsens/ht/persist/dao/HtPatientReportDao.java +++ b/ht/src/main/java/com/ccsens/ht/persist/dao/HtPatientReportDao.java @@ -18,40 +18,41 @@ public interface HtPatientReportDao extends HtPatientReportMapper { /** *根据病人报告单ID查询报告单结果 - * @param id - *@return: com.ccsens.ht.bean.vo.PatientReportVo.ReprotPatient - *@Author: wuHuiJuan + * @param id 报告单ID + *@return com.ccsens.ht.bean.vo.PatientReportVo.ReprotPatient + *@author wuHuiJuan *@date: 2019/11/19 11:08 */ PatientReportVo.ReprotPatient queryReportResult(@Param("id") Long id); /** * 根据病人报告单ID查询报告单各项相关分数 * @param id 报告单ID + * @param rey 是否查询rey * @param report 报告单类型 - *@return: com.ccsens.ht.bean.vo.PatientReportVo.ReportScore - *@Author: wuHuiJuan + *@return com.ccsens.ht.bean.vo.PatientReportVo.ReportScore + *@author wuHuiJuan *@date: 2019/11/19 11:46 */ List queryReportScore(@Param("id") Long id,@Param("rey") int rey, @Param("report") String report); /** * 查询NPI的分数 - * @param id - * @return + * @param id 报告单ID + * @return npi分数 */ - List> queryNPIScore(@Param("id") Long id); + List> queryNpiScore(@Param("id") Long id); /** * 检查未完成的报告单 - * @param userId - * @return + * @param userId 医生ID + * @return 报告单 */ PatientReportVo.Complete checkComplete(@Param("userId") Long userId); /** * 忽略报告单 - * @param id - * @param userId + * @param id 报告单ID + * @param userId 用户ID */ void ignoreComplete(@Param("id") Long id, @Param("userId") Long userId); @@ -59,35 +60,35 @@ public interface HtPatientReportDao extends HtPatientReportMapper { * 查询报告单名字(ID,名字,导出路径) * @param doctorId 医生ID * @param patientId 病人ID - * @return + * @return 报告单id,名字和pdf路径 */ List queryReportName(@Param("doctorId")Long doctorId, @Param("patientId") Long patientId); /** * 管理员查询报告单 - * @param adminQueryReport - * @return + * @param adminQueryReport 搜索条件 + * @return 报告单 */ List queryAllReports(PatientReportDto.AdminQueryReport adminQueryReport); /** * 根据临床诊断统计 - * @param param - * @return + * @param param 统计条件 + * @return 临床诊断统计 */ List countByClinicalDiagnosis(PatientReportDto.ClinicalDiagnosis param); /** * 根据年龄性别统计 - * @param param - * @return + * @param param 年龄性别 + * @return 年龄性别统计 */ List countBySexAndAge(PatientReportDto.AgeAndSex param); /** * 根据日期统计 - * @param param - * @return + * @param param 日期 + * @return 统计 */ List countByDay(PatientReportDto.Day param); @@ -95,7 +96,7 @@ public interface HtPatientReportDao extends HtPatientReportMapper { * 查询报告单的详细答题洗洗 * @param id 报告单id * @param evaluationCode 测试类型 - * @return + * @return 报告单的详细答题明细 */ List queryReportAnswer(@Param("id")Long id, @Param("evaluationCode")String evaluationCode); @@ -110,7 +111,7 @@ public interface HtPatientReportDao extends HtPatientReportMapper { * 根据病人报告单ID查询报告单各项相关分数 * @param id 报告单ID * @param code 量表类型 - * @return + * @return 报告单分数 */ List queryReportScore2(@Param("id") Long id, @Param("code") String code); @@ -121,4 +122,11 @@ public interface HtPatientReportDao extends HtPatientReportMapper { * @return 题目 */ List queryQuestionAndScore(@Param("id") Long id, @Param("code") String code); + + /** + * + * @param ids 指定报告单ID + * @return 报告单分数 mmse 分类 moca 试题和分数 其他:总分 + */ + List queryReportAnalyseScore(@Param("ids") List ids); } diff --git a/ht/src/main/java/com/ccsens/ht/service/IPatientReportService.java b/ht/src/main/java/com/ccsens/ht/service/IPatientReportService.java index 5ce6331b..4c8b1112 100644 --- a/ht/src/main/java/com/ccsens/ht/service/IPatientReportService.java +++ b/ht/src/main/java/com/ccsens/ht/service/IPatientReportService.java @@ -168,9 +168,8 @@ public interface IPatientReportService { /** * 导出指定报告单分析 - * @param param 报告单ID列表 - * @param userId 用户ID + * @param ids 报告单ID列表 * @return workbook */ - Workbook exportAnalyse(List param, Long userId); + Workbook exportAnalyse(List ids); } diff --git a/ht/src/main/java/com/ccsens/ht/service/PatientReportService.java b/ht/src/main/java/com/ccsens/ht/service/PatientReportService.java index 88314b52..3371e9ca 100644 --- a/ht/src/main/java/com/ccsens/ht/service/PatientReportService.java +++ b/ht/src/main/java/com/ccsens/ht/service/PatientReportService.java @@ -26,6 +26,7 @@ import com.github.pagehelper.PageInfo; import com.github.pagehelper.StringUtil; import lombok.extern.slf4j.Slf4j; import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @@ -235,7 +236,7 @@ public class PatientReportService implements IPatientReportService { } private void initNPI(long id, PatientReportVo.ReportScore score) { - List> list = htPatientReportDao.queryNPIScore(id); + List> list = htPatientReportDao.queryNpiScore(id); Map npiScore = new HashMap<>(); list.forEach(map -> npiScore.put((String)map.get("optionName"), map.get("score"))); PatientReportVo.ReportScore carer = new PatientReportVo.ReportScore(); @@ -628,7 +629,7 @@ public class PatientReportService implements IPatientReportService { List reportScores = htPatientReportDao.queryReportScore2(param.getId(),param.getCode()); if (!Constant.Ht.Report.ADL.equals(param.getCode())) { - getReportScores(param, content, reportScores); + getReportScores(param, content, reportScores, reportPatient); } @@ -643,14 +644,189 @@ public class PatientReportService implements IPatientReportService { } @Override - public Workbook exportAnalyse(List param, Long userId) { + public Workbook exportAnalyse(List ids) { + List analyses = htPatientReportDao.queryReportAnalyseScore(ids); -// PoiUtil. - return null; + + int total = 38; + List> rows = new ArrayList<>(); + // 标题 表头 + initAnalyseTitle(rows, total); + + if (CollectionUtil.isEmpty(analyses)) { + Workbook workbook = new XSSFWorkbook();; + PoiUtil.exportWB("报告单详情", rows, workbook); + return workbook; + } + // 填充数据 + for (int i = 0; i < analyses.size(); i++) { + + List row = new ArrayList<>(); + row.add(new PoiUtil.PoiUtilCell(String.valueOf(i+1),1,1)); + for (int j = 1; j < total; j++) { + row.add(new PoiUtil.PoiUtilCell("",1,1)); + } + fillAnalyse(row, analyses.get(i)); + rows.add(row); + } + + + + Workbook workbook = new XSSFWorkbook();; + PoiUtil.exportWB("报告单详情", rows, workbook); + return workbook; + } + + /** + * 填充导出分析 + * @param row 表格 + * @param analyse 分析 + */ + private void fillAnalyse(List row, PatientReportVo.Analyse analyse) { + row.get(1).setValue(DateUtil.format(new Date(analyse.getReportTime()), "yyyy.MM.dd")); + row.get(2).setValue(analyse.getPatientName()); + row.get(3).setValue(analyse.getSex() == 0 ? "男" : "女"); + row.get(4).setValue(String.valueOf(analyse.getPatientAge())); + row.get(5).setValue(Constant.Ht.getEducational(analyse.getEducationalStatus())); + row.get(6).setValue(Constant.Ht.getCareer(analyse.getCareer())); + row.get(7).setValue(analyse.getClinicalDiagnosis()); + row.get(8).setValue(Constant.Ht.getPasi(analyse.getPasi())); + if (CollectionUtil.isNotEmpty(analyse.getMmseScores())) { + analyse.getMmseScores().forEach(score->{ + switch (score.getCode()) { + case "DXL" : row.get(9).setValue(score.getScore().intValue() + "");break; + case "JYL" : row.get(10).setValue(score.getScore().intValue() + "");break; + case "ZYLHJSL" : row.get(11).setValue(score.getScore().intValue() + "");break; + case "HYNL" : row.get(12).setValue(score.getScore().intValue() + "");break; + case "YYNL" : row.get(13).setValue(score.getScore().intValue() + "");break; + case "JGNL" : row.get(14).setValue(score.getScore().intValue() + "");break; + } + }); + } + // MOCA匹配 + if (CollectionUtil.isNotEmpty(analyse.getMocaScores())) { + for (int i = 0; i < analyse.getMocaScores().size(); i++) { + PatientReportVo.MoCAScore score = analyse.getMocaScores().get(i); + if (score.getSort() <= 3) { + row.get(15+score.getSort()).setValue(score.getScore().intValue() + ""); + } else if (score.getSort() == 4 || score.getSort() == 5 || score.getSort() == 6) { + String value = row.get(19).getValue(); + int s = StrUtil.isEmpty(value) ? 0 : Integer.parseInt(value); + row.get(19).setValue(String.valueOf(s + score.getScore().intValue())); + } else if (score.getSort() >= 7 && score.getSort() <= 12) { + row.get(13+score.getSort()).setValue(score.getScore().intValue() + ""); + } else if (score.getSort() == 13 || score.getSort() == 14) { + String value = row.get(26).getValue(); + int s = StrUtil.isEmpty(value) ? 0 : Integer.parseInt(value); + row.get(26).setValue(String.valueOf(s + score.getScore().intValue())); + } else if (score.getSort() >= 15 && score.getSort() <= 17) { + row.get(12+score.getSort()).setValue(score.getScore().intValue() + ""); + } else if (score.getSort()== 20 || score.getSort() == 21) { + row.get(10+score.getSort()).setValue(score.getScore().intValue() + ""); + } else if (score.getSort() == 18) { + row.get(32).setValue(score.getScore().intValue() + ""); + } + } + } + + if (CollectionUtil.isNotEmpty(analyse.getTotalScores())) { + analyse.getTotalScores().forEach(totalScore -> { + switch (totalScore.getEvaluationCode()) { + case "MMSE": row.get(15).setValue(totalScore.getTotalScore().intValue() + "");break; + case "MoCA": row.get(33).setValue(totalScore.getTotalScore().intValue() + "");break; + case "ADL": row.get(34).setValue(totalScore.getTotalScore().intValue() + "");break; + case "HAMA": row.get(35).setValue(totalScore.getTotalScore().intValue() + "");break; + case "HAMD": row.get(36).setValue(totalScore.getTotalScore().intValue() + "");break; + case "NPI": row.get(37).setValue(totalScore.getTotalScore().intValue() + "");break; + } + }); + } + } + + private void initAnalyseTitle(List> rows, int total) { + List headRow = new ArrayList<>(); + PoiUtil.PoiUtilCell headCell = new PoiUtil.PoiUtilCell(); + headCell.setColspan(total); + headCell.setValue("认知功能神经心理量表检查报告单"); + headRow.add(headCell); + rows.add(headRow); + log.info("标题:{}", headCell); + List oneTitleRow = new ArrayList<>(); + oneTitleRow.add(new PoiUtil.PoiUtilCell("序号",1,2)); + oneTitleRow.add(new PoiUtil.PoiUtilCell("基本信息",8,1)); + for (int i = 0; i < 7; i++) { + oneTitleRow.add(new PoiUtil.PoiUtilCell("",1,1)); + } + + + oneTitleRow.add(new PoiUtil.PoiUtilCell("MMSE",7,1)); + for (int i = 0; i < 6; i++) { + oneTitleRow.add(new PoiUtil.PoiUtilCell("",1,1)); + } + oneTitleRow.add(new PoiUtil.PoiUtilCell("MoCA",18,1)); + for (int i = 0; i < 17; i++) { + oneTitleRow.add(new PoiUtil.PoiUtilCell("",1,1)); + } + oneTitleRow.add(new PoiUtil.PoiUtilCell("其他量表",4,1)); + for (int i = 0; i < 4; i++) { + oneTitleRow.add(new PoiUtil.PoiUtilCell("",1,1)); + } + rows.add(oneTitleRow); + + List titleRow = new ArrayList<>(); + // 基本信息 + titleRow.add(new PoiUtil.PoiUtilCell("")); + titleRow.add(new PoiUtil.PoiUtilCell("测评日期")); + titleRow.add(new PoiUtil.PoiUtilCell("姓名")); + titleRow.add(new PoiUtil.PoiUtilCell("性别")); + titleRow.add(new PoiUtil.PoiUtilCell("年龄")); + titleRow.add(new PoiUtil.PoiUtilCell("文化程度")); + titleRow.add(new PoiUtil.PoiUtilCell("职业")); + titleRow.add(new PoiUtil.PoiUtilCell("临床诊断")); + titleRow.add(new PoiUtil.PoiUtilCell("严重程度")); + // MMSE + titleRow.add(new PoiUtil.PoiUtilCell("定向力")); + titleRow.add(new PoiUtil.PoiUtilCell("记忆力")); + titleRow.add(new PoiUtil.PoiUtilCell("注意力和计算力")); + titleRow.add(new PoiUtil.PoiUtilCell("回忆能力")); + titleRow.add(new PoiUtil.PoiUtilCell("语言能力")); + titleRow.add(new PoiUtil.PoiUtilCell("结构能力")); + titleRow.add(new PoiUtil.PoiUtilCell("总分")); + + // MoCA + titleRow.add(new PoiUtil.PoiUtilCell("连线测验")); + titleRow.add(new PoiUtil.PoiUtilCell("立方体")); + titleRow.add(new PoiUtil.PoiUtilCell("画钟")); + // 命名 4-6 + titleRow.add(new PoiUtil.PoiUtilCell("命名")); + titleRow.add(new PoiUtil.PoiUtilCell("记忆1")); + titleRow.add(new PoiUtil.PoiUtilCell("记忆2")); + titleRow.add(new PoiUtil.PoiUtilCell("注意顺背")); + titleRow.add(new PoiUtil.PoiUtilCell("注意倒背")); + titleRow.add(new PoiUtil.PoiUtilCell("注意敲1")); + titleRow.add(new PoiUtil.PoiUtilCell("注意100-7")); + // 语言重复 13-14 + titleRow.add(new PoiUtil.PoiUtilCell("语言重复")); + titleRow.add(new PoiUtil.PoiUtilCell("流畅性1min")); + titleRow.add(new PoiUtil.PoiUtilCell("抽象")); + titleRow.add(new PoiUtil.PoiUtilCell("延迟回忆")); + // 20 + titleRow.add(new PoiUtil.PoiUtilCell("分类提示")); + // 21 + titleRow.add(new PoiUtil.PoiUtilCell("多选提示")); + titleRow.add(new PoiUtil.PoiUtilCell("定向")); + titleRow.add(new PoiUtil.PoiUtilCell("总分")); + + // 其他量表总分 + titleRow.add(new PoiUtil.PoiUtilCell("ADL总分")); + titleRow.add(new PoiUtil.PoiUtilCell("HAMA总分")); + titleRow.add(new PoiUtil.PoiUtilCell("HAMD总分")); + titleRow.add(new PoiUtil.PoiUtilCell("NPI总分")); + rows.add(titleRow); } - private List getReportScores(PatientReportDto.ExportCode param, List content, List reportScores) { + private List getReportScores(PatientReportDto.ExportCode param, List content, List reportScores, PatientReportVo.ReprotPatient reportPatient) { long reportId = param.getId(); //重新封装报告单信息 List scores = getReportScores(reportScores, reportId); @@ -663,7 +839,7 @@ public class PatientReportService implements IPatientReportService { int titleSpan = 2; PdfUtil.Cell initWordCell = addCell(row, "初步印象", titleSpan, 2); initWordCell.setHeight(PdfUtil.Cell.defaultHeight * 2); - String initialImpression = ""; + String initialImpression = reportPatient.getInitialImpression(); PdfUtil.Cell initImplCell = addCell(row, initialImpression, colNum - titleSpan, 2); initImplCell.setHeight(PdfUtil.Cell.defaultHeight * 2); initImplCell.setBorderRight(1); diff --git a/ht/src/main/java/com/ccsens/ht/uitl/Constant.java b/ht/src/main/java/com/ccsens/ht/uitl/Constant.java index 44a3f31f..a1aefe86 100644 --- a/ht/src/main/java/com/ccsens/ht/uitl/Constant.java +++ b/ht/src/main/java/com/ccsens/ht/uitl/Constant.java @@ -129,10 +129,52 @@ public class Constant { public final static byte SEX_MAN = 0; public final static byte SEX_WOMAN = 1; + //1:文盲 2:小学 3:初中 4:高中 5:大学 6:大学以上 7:其他 + public static String getEducational(int status) { + switch (status) { + case 1: return "文盲"; + case 2: return "小学"; + case 3: return "初中"; + case 4: return "高中"; + case 5: return "大学"; + case 6: return "大学以上"; + default: return "其他"; + } + } + + public static String getCareer(int status) { + switch (status) { + case 1: return "农林牧渔水利生产人员"; + case 2: return "教师"; + case 3: return "医务工作者"; + case 4: return "专业技术人员"; + case 5: return "生产、运输设备操作人员及有关人员"; + case 6: return "商业、服务业人员"; + case 7: return "国家机关、事业单位、企业负责人"; + case 8: return "商业、服务业人员"; + case 9: return "军人"; + case 10: return "媒体、文体类工作人员"; + case 11: return "在校学生"; + case 12: return "未就业"; + case 13: return "家务"; + default: return "其他"; + } + } + /**删除*/ public final static byte IS_DEL = 1; + public static String getPasi(Byte pasi) { + switch (pasi) { + case 0: return "正常"; + case 1: return "轻度"; + case 2: return "中度"; + case 3: return "重度"; + default: return ""; + } + } + public final static class QuestionRecord{ public static final byte RECORD_TYPE_CODE = 0; diff --git a/ht/src/main/resources/mapper_dao/HtPatientReportDao.xml b/ht/src/main/resources/mapper_dao/HtPatientReportDao.xml index 2d573a52..ed13cc55 100644 --- a/ht/src/main/resources/mapper_dao/HtPatientReportDao.xml +++ b/ht/src/main/resources/mapper_dao/HtPatientReportDao.xml @@ -48,6 +48,29 @@ + + + + + + + + + + + + + + + + + + + + + + + - select option_name as optionName, sum(score) as score from t_ht_patient_score where patient_report_id = #{id, jdbcType=BIGINT} and question_parent_code = 'NPI' @@ -357,6 +380,54 @@ q.sort, o.sort + \ No newline at end of file diff --git a/ht/src/main/resources/mapper_dao/HtQuestionDao.xml b/ht/src/main/resources/mapper_dao/HtQuestionDao.xml index 5ea00dc2..cbfcf214 100644 --- a/ht/src/main/resources/mapper_dao/HtQuestionDao.xml +++ b/ht/src/main/resources/mapper_dao/HtQuestionDao.xml @@ -38,7 +38,7 @@ replace into t_ht_question (id, evaluation_code, parent_code, sort, question, type, - record_type, record_content, relation_code, + record_type, record_content, relation_code, relation_id, operate_type, recode_starttime, time_wabei, allow_clear, clear_times, timing_length, remark, create_time, update_time, @@ -48,6 +48,14 @@ (#{question.id,jdbcType=BIGINT}, #{question.evaluationCode,jdbcType=VARCHAR}, #{question.parentCode,jdbcType=VARCHAR}, #{question.sort,jdbcType=INTEGER}, #{question.question,jdbcType=VARCHAR}, #{question.type,jdbcType=TINYINT}, #{question.recordType,jdbcType=VARCHAR}, #{question.recordContent,jdbcType=VARCHAR}, #{question.relationCode,jdbcType=VARCHAR}, + + + 0, + + + #{question.relationId}, + + #{question.operateType,jdbcType=TINYINT}, #{question.recodeStarttime,jdbcType=TINYINT}, #{question.timeWabei,jdbcType=TINYINT}, #{question.allowClear,jdbcType=TINYINT}, #{question.clearTimes,jdbcType=INTEGER}, #{question.timingLength,jdbcType=INTEGER}, #{question.remark,jdbcType=VARCHAR}, #{question.createTime,jdbcType=TIMESTAMP}, now(), 0 ) diff --git a/tall/src/main/resources/application.yml b/tall/src/main/resources/application.yml index eca66951..1d881c2f 100644 --- a/tall/src/main/resources/application.yml +++ b/tall/src/main/resources/application.yml @@ -1,4 +1,4 @@ spring: profiles: - active: test - include: util-test,common \ No newline at end of file + active: dev + include: util-dev,common \ No newline at end of file diff --git a/util/src/main/java/com/ccsens/util/PoiUtil.java b/util/src/main/java/com/ccsens/util/PoiUtil.java index efbd2ded..346dcdc5 100644 --- a/util/src/main/java/com/ccsens/util/PoiUtil.java +++ b/util/src/main/java/com/ccsens/util/PoiUtil.java @@ -1,11 +1,17 @@ package com.ccsens.util; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; import com.ccsens.util.exception.BaseException; +import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.apache.poi.POIXMLDocumentPart; +import org.apache.poi.common.usermodel.HyperlinkType; import org.apache.poi.hssf.usermodel.*; import org.apache.poi.ss.usermodel.DateUtil; import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.util.IOUtils; import org.apache.poi.xssf.usermodel.*; import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker; import org.springframework.stereotype.Component; @@ -20,17 +26,283 @@ import java.util.Map; /** * 导入导出excel + * @author wu */ @Slf4j @Component public class PoiUtil { + + @Data + public static class PoiUtilCell { + /** + * 单元格内容 + */ + private String value = ""; + /** + * 跨列 + */ + private int colspan = 1; + /** + * 跨行 + */ + private int rowspan = 1; + /** + * 水平居中 + */ + private HorizontalAlignment style = HorizontalAlignment.CENTER; + /** + * 垂直居中 + */ + private VerticalAlignment verticalAlignment = VerticalAlignment.CENTER; + /** + * 行高 + */ + private Integer height; + /** + * 列宽 + */ + private Integer wight; + + /** + * 跳转的路径 + */ + private String path; + /** + * 函数 + */ + private String function; + + /** + * 是否是数字格式 0否 1是 + */ + private byte num = 0; + + public PoiUtilCell() { + + } + + public PoiUtilCell(String value) { + this.value = value; + } + + public PoiUtilCell(String value,String function) { + this.value = value; + this.function = function; + } + + + public PoiUtilCell(String value, int colspan, int rowspan) { + this.value = value; + this.colspan = colspan; + this.rowspan = rowspan; + } + + public PoiUtilCell(String value, Integer height, Integer wight) { + this.value = value; + this.height = height; + this.wight = wight; + } + + public PoiUtilCell(String value, int colspan, int rowspan, Integer height, Integer wight) { + this.value = value; + this.colspan = colspan; + this.rowspan = rowspan; + this.height = height; + this.wight = wight; + } + + } + + + /** + * 导出Excel + * + * @param sheetName sheet名称 + * @param rows 行 + * @param wb XSSFWorkbook对象 无则创建 + * @return 返回生成的excel数据 + */ + public static Workbook exportWB(String sheetName, List> rows, Workbook wb) { + + // 第一步,创建一个XSSFWorkbook,对应一个Excel文件 + if (wb == null) { + wb = new XSSFWorkbook(); + } + if (rows == null) { + return wb; + } + // 第二步,在workbook中添加一个sheet,对应Excel文件中的sheet + Sheet sheet = wb.getSheet(sheetName); + if (ObjectUtil.isNull(sheet)) { + sheet = wb.createSheet(sheetName); + } + +// // 第三步,在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制 +// HSSFRow row = sheet.createRow(0); + + // 第四步,创建单元格,并设置值表头 设置表头居中 + for (int i = 0; i < rows.size(); i++) { + List cells = rows.get(i); + for (int j = 0; j < cells.size(); j++) { + PoiUtilCell cell = cells.get(j); + //设置列宽 + if (ObjectUtil.isNotNull(cell.wight)) { + sheet.setColumnWidth(j, cell.wight * 256); + } + mergedRegion(sheet, i, j, cells.get(j)); + } + } + + //创建内容 + for (int i = 0; i < rows.size(); i++) { + Row row = sheet.getRow(i); + if (ObjectUtil.isNull(row)) { + row = sheet.createRow(i); + } + List cells = rows.get(i); + for (int j = 0; j < cells.size(); j++) { + PoiUtilCell cell = cells.get(j); + if(ObjectUtil.isNull(cell)){ + continue; + } + //查找当前单元格 + Cell newCell = row.getCell(j); + if(ObjectUtil.isNull(newCell)){ + newCell = row.createCell(j); + } + //查找当前单元格的样式 + CellStyle style = newCell.getCellStyle(); + if(ObjectUtil.isNull(style)){ + style = wb.createCellStyle(); + } +// CellStyle style = wb.createCellStyle(); + //设置内容 + if (!WebConstant.CELL_NULL.equals(cell.value)){ +// if(cell.num == 1){ +// newCell.setCellValue(Integer.parseInt(cell.value)); +// }else { +// newCell.setCellValue(cell.value); +// } + if(ObjectUtil.isNull(cell.value)) { +// log.info("单元格内容为空:{}", cell.value); + }else { + if (cell.value.length() <= 14 && cell.value.matches("\\d+")) { + newCell.setCellValue(Long.parseLong(cell.value)); + } else { + newCell.setCellValue(cell.value); + } + } + } + //设置行高 + if (ObjectUtil.isNotNull(cell.height)) { + if (j == 0) { + row.setHeight(cell.height.shortValue()); + } + } + //设置水平居中和垂直居中 + style.setAlignment(cell.style); + style.setVerticalAlignment(cell.verticalAlignment); + //设置跳转路径 + if (StrUtil.isNotEmpty(cell.path)) { + XSSFCreationHelper createHelper = (XSSFCreationHelper) wb.getCreationHelper(); + XSSFHyperlink link = createHelper.createHyperlink(HyperlinkType.URL); + link.setAddress(cell.path); + newCell.setHyperlink(link); + //设置字体颜色 + Font font = wb.createFont(); + font.setColor(Font.COLOR_RED); + style.setFont(font); + } + //添加函数 + if(StrUtil.isNotEmpty(cell.getFunction())) { + newCell.setCellFormula(cell.getFunction()); + } + //设置自动换行 + style.setWrapText(true); + //将样式添加至单元格 + newCell.setCellStyle(style); + +// CellStyle style = wb.createCellStyle(); +// 将内容按顺序赋给对应的列对象 +// 如果value是cell_null代表次单元格不需要赋值 +// if (cell.value.equals(WebConstant.CELL_NULL)){ +// continue; +// } +// Cell newCell = row.createCell(j); +// //设置行高 +// if (ObjectUtil.isNotNull(cell.height)) { +// if (j == 0) { +// row.setHeight(cell.height.shortValue()); +// } +// } +// +// if(cell.num == 1){ +// newCell.setCellValue(Integer.parseInt(cell.value)); +// }else { +// newCell.setCellValue(cell.value); +// } +// style.setAlignment(cell.style); +// style.setVerticalAlignment(cell.verticalAlignment); + +// //设置跳转路径 +// if (StrUtil.isNotEmpty(cell.path)) { +// XSSFCreationHelper createHelper = (XSSFCreationHelper) wb.getCreationHelper(); +// XSSFHyperlink link = createHelper.createHyperlink(HyperlinkType.URL); +// link.setAddress(cell.path); +// newCell.setHyperlink(link); +// //设置字体颜色 +// Font font = wb.createFont(); +// font.setColor(Font.COLOR_RED); +// style.setFont(font); +// } +// //添加函数 +// if(StrUtil.isNotEmpty(cell.getFunction())) { +// newCell.setCellFormula(cell.getFunction()); +// } +// //设置自动换行 +// style.setWrapText(true); +// newCell.setCellStyle(style); + } + } + return wb; + } + + /** + * 合并单元格 + * + * @param sheet 当前sheet + * @param rows 行数 + * @param cols 列数 + * @param cell 单元格信息 + */ + private static void mergedRegion(Sheet sheet, int rows, int cols, PoiUtilCell cell) { +// +// int rowspan = cell.rowspan; +// if (rowspan > 1) { +// sheet.addMergedRegion(new CellRangeAddress(rows, rows + rowspan - 1, cols, cols)); +// } +// int colspan = cell.colspan; +// +// if (colspan > 1) { +// sheet.addMergedRegion(new CellRangeAddress(rows, rows, cols, cols + colspan - 1)); +// } + + int rowspan = cell.rowspan; + int colspan = cell.colspan; + if(rowspan > 1 || colspan > 1){ + sheet.addMergedRegion(new CellRangeAddress(rows, rows + rowspan - 1, cols, cols + colspan - 1)); + } + + } + + /** * @param file * @param sheetIndex * @param dataIndex 数据从第几行开始(0) * @return */ - public static List readExce(File file, int sheetIndex, String sheetName, int dataIndex, boolean hasImg) throws Exception{ + public static List readExce(File file, int sheetIndex, String sheetName, int dataIndex, boolean hasImg) throws Exception { if (!file.getPath().endsWith(".xls") && !file.getPath().endsWith(".xlsx")) { log.info("文件不是excel类型:{}", file.getName()); throw new BaseException(CodeEnum.FILE_FORMAT_ERROR); @@ -38,47 +310,52 @@ public class PoiUtil { log.info("导入解析开始,fileName:{}", file.getPath()); - List list = new ArrayList<>(); + List list = new ArrayList<>(); - Sheet sheet = createSheet(file, sheetIndex, sheetName); - //读取放在首列的图片 - Map imgMap = null; - if (hasImg) { - imgMap = getImg(file, sheet); - } - //获取sheet的行数 - int rows = sheet.getPhysicalNumberOfRows(); + Sheet sheet = createSheet(file, sheetIndex, sheetName); + if(ObjectUtil.isNull(sheet)){ + return list; + } + //读取放在首列的图片 + Map imgMap = null; + if (hasImg) { + imgMap = getImg(file, sheet); + } + //获取sheet的行数 + int rows = sheet.getPhysicalNumberOfRows(); - //读取数据 - for (int i = 0; i < rows; i++) { + //读取数据 + for (int i = 0; i < rows; i++) { - Row row = getRow(sheet, i, dataIndex); - if (row == null) { + Row row = getRow(sheet, i, dataIndex); + if (row == null || row.getLastCellNum() <= 0) { + continue; + } + System.out.println(row); + System.out.println(row.getLastCellNum()); + Object[] objects = new Object[row.getLastCellNum()]; + if (hasImg && imgMap != null) { + for (String key : imgMap.keySet()) { + if (key.startsWith(i + "-")) { + int index = Integer.parseInt(key.split("-")[1]); + objects[index] = imgMap.get(key); + } + } + } + for (int j = 0; j < row.getLastCellNum(); j++) { + Cell cell = row.getCell(j); + if (cell == null) { continue; } - Object[] objects = new Object[row.getLastCellNum()]; - if (hasImg && imgMap != null) { - for (String key: imgMap.keySet()) { - if (key.startsWith(i+"-")) { - int index = Integer.parseInt(key.split("-")[1]); - objects[index] = imgMap.get(key); - } - } + if (objects[j] == null) { + objects[j] = getCallValue(cell); } - for (int j = 0; j < row.getLastCellNum(); j++) { - Cell cell = row.getCell(j); - if (cell == null) { - continue; - } - if (objects[j] == null) { - objects[j] = getCallValue(cell); - } - } - list.add(objects); } - log.info("导入文件解析成功!"); - return list; + list.add(objects); + } + log.info("导入文件解析成功!"); + return list; } @@ -121,7 +398,6 @@ public class PoiUtil { } - private PoiUtil() { super(); } @@ -163,7 +439,7 @@ public class PoiUtil { String suffix = pictureData.suggestFileExtension(); //图片 byte[] data = pictureData.getData(); - String fileName = "/poi/img/" + cn.hutool.core.date.DateUtil.today() + "/"+ System.currentTimeMillis() + "." + suffix; + String fileName = "/poi/img/" + cn.hutool.core.date.DateUtil.today() + "/" + System.currentTimeMillis() + "." + suffix; String path = PropUtil.path + fileName; FileOutputStream out = null; @@ -215,6 +491,7 @@ public class PoiUtil { return map; } + /** * 获取当前行 */ @@ -241,7 +518,6 @@ public class PoiUtil { /** * 生成sheet - * * @param file * @param index * @return @@ -251,7 +527,7 @@ public class PoiUtil { InputStream inputStream = new FileInputStream(file); Workbook workbook; if (file.getPath().endsWith(".xls")) { - workbook = new HSSFWorkbook(inputStream); + workbook = new XSSFWorkbook(inputStream); } else { workbook = new XSSFWorkbook(inputStream); } @@ -261,17 +537,165 @@ public class PoiUtil { return workbook.getSheetAt(index); } - public static void main(String[] args) throws Exception { - File file = new File("D:\\1.xlsx"); - List list = readExce(file, 0, null, 3, true); - for (Object[] arr : list) { - for (Object t : arr) { - System.out.print(t + "---"); + /** + * 插入图片 + * @param row1:起始行 + * @param row2:终止行 + * @param col1:起始列 + * @param col2:终止列 + * @throws IOException + */ + public static Workbook setImg(Workbook wb,String sheetName,String imgPath,int row1,int row2,int col1,int col2) throws IOException { + // 第一步,创建一个XSSFWorkbook,对应一个Excel文件 + if (wb == null) { + wb = new XSSFWorkbook(); + } + // 第二步,在workbook中添加一个sheet,对应Excel文件中的sheet + Sheet sheet = wb.getSheet(sheetName); + if (ObjectUtil.isNull(sheet)) { + sheet = wb.createSheet(sheetName); + } + // 插入 PNG 图片至 Excel + InputStream is = new FileInputStream(imgPath); + if(ObjectUtil.isNull(is)){ + return wb; + } + byte[] bytes = IOUtils.toByteArray(is); + int pictureIdx = wb.addPicture(bytes, Workbook.PICTURE_TYPE_PNG); + + CreationHelper helper = wb.getCreationHelper(); + Drawing drawing = sheet.createDrawingPatriarch(); + ClientAnchor anchor = helper.createClientAnchor(); + + // 图片插入坐标 + anchor.setDx1(0); + anchor.setDy1(0); + anchor.setDx2(0); + anchor.setDy2(0); + anchor.setRow1(row1); + anchor.setRow2(row2); + anchor.setCol1(col1); + anchor.setCol2(col2); + // 插入图片 + Picture pict = drawing.createPicture(anchor, pictureIdx); + return wb; + } + + + + /** + * 获取excel的列号 + * @param num 第几列(从1开始) + * @return 返回列号 + */ + public static String toRadix(Integer num) throws Exception{ + String[] array = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"}; + int count = 26; + String out = ""; + if(num > count){ + if(num % count == 0){ + out = array[(num / count) - 1 - 1] + array[count - 1]; + }else { + out = array[(num / count) - 1] + array[(num % count) - 1]; } - System.out.println("============"); + }else{ + out = array[num - 1]; } + return out; } + public static void main(String[] args) throws Exception { + String s = toRadix(3); + System.out.println(s); + + +// File file = new File("F:\\wenjian\\3.xlsx"); +// file.createNewFile(); +// InputStream inputStream = new FileInputStream(file); + Workbook workbook = new XSSFWorkbook(); +// XSSFSheet sheet = (XSSFSheet) workbook.getSheetAt(0); +// XSSFRow row = sheet.getRow(6); +// XSSFCell newCell = row.createCell(2); +// XSSFCell newCell1 = row.createCell(3); +// //添加公式 +// newCell.setCellFormula("A7+B7"); +// newCell1.setCellFormula("A8/B8"); +// //设置打印区域 +// workbook.setPrintArea( +// 0, //工作薄 下标0开始 +// 0, //起始列 下标0开始 +// 20, //终止列 下标0开始 +// 0, //起始行 下标0开始 +// 20 //终止行 下标0开始 +// ); +//// CellStyle style = workbook.createCellStyle(); +//// style.setFillBackgroundColor(); +// +// OutputStream stream = new FileOutputStream(new File("D:\\1.xlsx")); +// workbook.write(stream); +// stream.close(); + + + + PoiUtilCell poiUtilCell = new PoiUtilCell(); + poiUtilCell.setValue("111222333"); + poiUtilCell.setColspan(2); + poiUtilCell.setRowspan(1); + PoiUtilCell poiUtilCell1 = new PoiUtilCell(); + poiUtilCell1.setValue("1112222"); + PoiUtilCell poiUtilCell3 = new PoiUtilCell(); + poiUtilCell3.setValue("123"); + + PoiUtilCell poiUtilCell2 = new PoiUtilCell(); + poiUtilCell2.setValue(""); + poiUtilCell2.setFunction("SUM(A1:C1)"); + + + List cells = new ArrayList<>(); + cells.add(poiUtilCell); + cells.add(poiUtilCell1); + cells.add(poiUtilCell3); + + cells.add(poiUtilCell2); + + List> list = new ArrayList<>(); + list.add(cells); + + + +// list.add(cells); +// +// List cells1 = new ArrayList<>(); +// cells1.add(new PoiUtilCell("两列一行", 2, 1)); +// list.add(cells1); +// +// List cells2 = new ArrayList<>(); +// cells2.add(new PoiUtilCell("一列两行", 1, 2)); +// list.add(cells2); +// List cells3 = new ArrayList<>(); +// cells3.add(new PoiUtilCell("5")); +// cells3.add(new PoiUtilCell("6")); +// list.add(cells3); +// List cells4 = new ArrayList<>(); +// list.add(cells4); +// List cells5 = new ArrayList<>(); +// cells5.add(new PoiUtilCell("9", 2, 2)); +// cells5.add(new PoiUtilCell("9")); +// list.add(cells5); + String fileName = "zzz/" + cn.hutool.core.date.DateUtil.today() + "/" + System.currentTimeMillis() + ".xlsx"; + String path = WebConstant.UPLOAD_PATH_BASE + fileName; + File tmpFile = new File(path); + if (!tmpFile.getParentFile().exists()) { + tmpFile.getParentFile().mkdirs(); + } + + Workbook wbs = exportWB("Sheet1", list, workbook); + OutputStream stream = new FileOutputStream(tmpFile); + wbs.write(stream); + stream.close(); + + + } -} +} \ No newline at end of file diff --git a/util/src/main/java/com/ccsens/util/WebConstant.java b/util/src/main/java/com/ccsens/util/WebConstant.java index f4893d02..219c128c 100644 --- a/util/src/main/java/com/ccsens/util/WebConstant.java +++ b/util/src/main/java/com/ccsens/util/WebConstant.java @@ -6,7 +6,8 @@ import java.io.File; public class WebConstant { - + /**cell内容不赋值*/ + public static final String CELL_NULL = "cell_null"; /**数据存在*/ public static final byte STATUS_EXIT = 0; /**数据已删除*/