检查报告打印

This commit is contained in:
余文财 2025-06-26 11:33:08 +08:00
parent bd99a1e915
commit 52b13b73e0
10 changed files with 133 additions and 204 deletions

View File

@ -17,7 +17,7 @@
</parent>
<properties>
<java.version>11</java.version>
<java.version>1.8</java.version>
<hutool.version>5.8.36</hutool.version>
<jna.version>5.17.0</jna.version>
<pdfbox.version>3.0.2</pdfbox.version>

View File

@ -1,5 +1,6 @@
package com.dpkj.modules.print.controller;
import com.alibaba.fastjson.JSONObject;
import com.dpkj.common.dto.LexMarkResultDTO;
import com.dpkj.common.vo.Result;
import com.dpkj.modules.print.request.MS439Request;
@ -33,18 +34,19 @@ public class MS439Controller {
/**
* 检验报告打印
*
* @return
*/
@PostMapping("/printJY")
public Result<LexMarkResultDTO<?>> printJY() {
MS439Request ms439Request = new MS439Request();
public Result<LexMarkResultDTO<?>> printJY(@RequestBody JSONObject jsonObject) {
JSONObject params = jsonObject.getJSONObject("reportResult");
// 获取检验报告PDF
String path = ms439PrintService.getJYPDFPath();
ms439Request.setPagesource("A5");
String path = ms439PrintService.getJYPDFPath(params);
MS439Request ms439Request = new MS439Request();
ms439Request.setPagesource("A4");
ms439Request.setFileDir(path);
// LexMarkResultDTO<?> result = ms439PrintService.printImage(ms439Request);
return Result.ok(null);
LexMarkResultDTO<?> result = ms439PrintService.printImage(ms439Request);
// 打印完成后删除临时PDF文件
ms439PrintService.deleteSysFileByPath(path);
return Result.ok(result);
}
@PostMapping("/getStatus")

View File

@ -1,5 +1,6 @@
package com.dpkj.modules.print.service;
import com.alibaba.fastjson.JSONObject;
import com.dpkj.common.dto.LexMarkResultDTO;
import com.dpkj.modules.print.request.MS439Request;
import com.dpkj.modules.print.vo.PrinterStatus;
@ -10,5 +11,7 @@ public interface MS439PrintService {
LexMarkResultDTO<PrinterStatus> getStatus(String papersource);
String getJYPDFPath();
String getJYPDFPath(JSONObject params);
void deleteSysFileByPath(String path);
}

View File

@ -1,5 +1,6 @@
package com.dpkj.modules.print.service.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dpkj.common.config.PrinterConfig;
import com.dpkj.common.dto.LexMarkDTO;
@ -44,7 +45,6 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -215,19 +215,19 @@ public class MS439PrintServiceImpl implements MS439PrintService {
}
@Override
public String getJYPDFPath() {
public String getJYPDFPath(JSONObject params) {
// 1. 准备输出路径
String dirPath = "D:/TempJYPDF/";
File dir = new File(dirPath);// 确保目录存在
if (!dir.exists()) {
dir.mkdirs();
}
String fileName = "report_jy_" + System.currentTimeMillis() + ".pdf";
String fileName = "jiancha_" + params.getString("reportId") + "_" + System.currentTimeMillis() + ".pdf";
String pdfPath = dirPath + fileName;
try {
// 2. 准备模板数据
Map<String, Object> data = prepareReportData();
Map<String, Object> data = prepareReportData(params);
// 3. 渲染Thymeleaf模板
String htmlContent = renderThymeleafTemplate(data);
// 4. 生成PDF文件
@ -240,6 +240,26 @@ public class MS439PrintServiceImpl implements MS439PrintService {
}
}
@Override
public void deleteSysFileByPath(String path) {
if (path == null || path.isEmpty()) {
return;
}
try {
File file = new File(path);
if (file.exists() && file.isFile()) {
boolean deleted = file.delete();
if (!deleted) {
System.err.println("文件删除失败: " + path);
}
} else {
System.err.println("文件不存在: " + path);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void createPdfFromHtml(String html, String outputPath)
throws IOException, DocumentException {
@ -290,41 +310,59 @@ public class MS439PrintServiceImpl implements MS439PrintService {
}
// 报告数据准备根据实际业务实现
private Map<String, Object> prepareReportData() {
private Map<String, Object> prepareReportData(JSONObject params) {
Map<String, Object> data = new HashMap<>();
// 患者信息
Map<String, String> patient = new HashMap<>();
patient.put("name", "余文财");
patient.put("gender", "");
patient.put("age", "25岁");
patient.put("medicalRecord", "20240624001");
patient.put("department", "内科");
patient.put("bedNumber", "A301");
data.put("patient", patient);
// 基本信息
Map<String, String> baseInfo = new HashMap<>();
baseInfo.put("reportId", params.getString("reportId"));// 报告id(标本编号)
baseInfo.put("lspcmName", params.getString("lspcmName"));// 标本名称
JSONObject patInfo = params.getJSONObject("pat_info");
baseInfo.put("patName", patInfo.getString("pat_name"));// 姓名
baseInfo.put("patSex", patInfo.getString("pat_sex"));// 性别
baseInfo.put("patAge", patInfo.getString("pat_age"));// 年龄
baseInfo.put("patHomePhno", patInfo.getString("pat_home_phno"));// 电话
JSONObject pv1Info = params.getJSONObject("pv1_info");
baseInfo.put("deptName", pv1Info.getString("dept_name"));// 科室
baseInfo.put("inpBedNo", pv1Info.getString("inp_bed_no"));// 床号
JSONObject applyInfoFirst = params.getJSONArray("apply_info").getJSONObject(0);
baseInfo.put("placerName", applyInfoFirst.getString("placer_name"));// 申请医生
baseInfo.put("spcmClctor", applyInfoFirst.getString("spcm_clctor"));// 标本采集人
baseInfo.put("citemContent", params.getString("citemContent"));// 申请项目
data.put("baseInfo", baseInfo);
// 检验项目数据
List<Map<String, Object>> items = new ArrayList<>();
addItem(items, "白细胞计数", "7.26", "3.5-9.5", "10^9/L", false);
addItem(items, "血红蛋白", "165", "115-150", "g/L", true);
// ...其他检验项
data.put("items", items);
JSONArray rptInfoList = params.getJSONArray("rpt_info");
// 系统信息
data.put("reportTime", new Date());
data.put("doctor", "李医师");
data.put("reviewer", "王主任");
for (int i = 0; i < rptInfoList.size(); i++) {
JSONObject obj = rptInfoList.getJSONObject(i);
// 项目名称loitem_cname,
// 结果order_rpt_result,
// 参考区间loitem_rv,
// 单位loitem_unit,
// 测试方法inspection_method,
// 结果异常标志:oaflag
addItem(items, obj.getString("loitem_cname"),
obj.getString("order_rpt_result"),
obj.getString("loitem_rv"),
obj.getString("loitem_unit"),
obj.getString("inspection_method"),
obj.getString("oaflag"));
}
data.put("items", items);
return data;
}
private void addItem(List<Map<String, Object>> items, String name,
String value, String range, String unit, boolean abnormal) {
String value, String range, String unit, String method, String oaflag) {
Map<String, Object> item = new HashMap<>();
item.put("name", name);
item.put("result", value);
item.put("referenceRange", range);
item.put("unit", unit);
item.put("isAbnormal", abnormal);
item.put("loitemCname", name);// 项目名称
item.put("orderRptResult", value);// 结果
item.put("loitemRv", range);// 参考区间
item.put("loitemUnit", unit);// 单位
item.put("inspectionMethod", method);// 测试方法
item.put("oaflag", oaflag);// 结果异常标志|-1-不计算改指标的参考1-正常2-偏低3-偏高4-阳性(异常)5-警戒下限6-警戒上限7-复查下限8-复查上限9-线性异常
items.add(item);
}
}

View File

@ -2,6 +2,8 @@ package com.dpkj.modules.print.utils;
import com.itextpdf.text.pdf.BaseFont;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
/**
@ -15,17 +17,27 @@ public class FontLoader {
if (fontStream == null) {
throw new IllegalArgumentException("字体文件未找到: " + resourcePath);
}
// 创建支持中文的 BaseFont
byte[] fontBytes = toByteArray(fontStream);
return BaseFont.createFont(
resourcePath,
BaseFont.IDENTITY_H,
BaseFont.EMBEDDED,
false,
fontStream.readAllBytes(),
fontBytes,
null
);
} catch (Exception e) {
throw new RuntimeException("字体加载失败: " + resourcePath, e);
}
}
private static byte[] toByteArray(InputStream input) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[4096];
while ((nRead = input.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
return buffer.toByteArray();
}
}

View File

@ -74,7 +74,7 @@
<div style="margin-left: 20px;font-size: 36px;word-break: break-all;">打印时间:<span th:text="${printTime}"></span>
</div>
<div style="margin-left: 20px;font-size: 36px;word-break: break-all;">
<span>温馨提示:请取走缴费凭证,并妥善保管。如果对缴费存在疑问,请到人工窗口咨询!</span>
<span>温馨提示:请妥善保管好您的缴费凭条,如果对缴费存在疑问,请到人工窗口咨询。</span>
</div>
</div>
</body>

View File

@ -31,7 +31,7 @@
<div style="margin-left: 20px;font-size: 36px;">终端编号:<span th:text="${terminalNumber}"></span></div>
<div style="margin-left: 20px;font-size: 36px;">打印时间:<span th:text="${printTime}"></span></div>
<div style="margin-left: 20px;font-size: 36px;">
<span>温馨提示:请取走缴费凭证,并妥善保管。如果对缴费存在疑问,请到人工窗口咨询!</span>
<span>温馨提示:请妥善保管好您的缴费凭条,如果对缴费存在疑问,请到人工窗口咨询。</span>
</div>
</div>
</body>

View File

@ -29,7 +29,7 @@
<div style="margin-left: 20px;font-size: 36px;">终端编号:<span th:text="${terminalNumber}"></span></div>
<div style="margin-left: 20px;font-size: 36px;">打印时间:<span th:text="${printTime}"></span></div>
<div style="margin-left: 20px;font-size: 36px;">
<span>温馨提示:请取走缴费凭证,并妥善保管。如果对缴费存在疑问,请到人工窗口咨询!</span>
<span>温馨提示:请妥善保管好您的缴费凭条,如果对缴费存在疑问,请到人工窗口咨询。</span>
</div>
</div>
</body>

View File

@ -39,7 +39,7 @@
<div style="margin-left: 20px;font-size: 36px;">终端编号:<span th:text="${terminalNumber}"></span></div>
<div style="margin-left: 20px;font-size: 36px;">打印时间:<span th:text="${printTime}"></span></div>
<div style="margin-left: 20px;font-size: 36px;">
<span>温馨提示:请取走挂号凭证,并妥善保管。如果对缴费存在疑问,请到人工窗口咨询!</span>
<span>温馨提示:请妥善保管好您的缴费凭条,如果对缴费存在疑问,请到人工窗口咨询。</span>
</div>
</div>
</body>

View File

@ -9,7 +9,7 @@
<!-- 医院标题 -->
<div style="text-align: center;">
<div style="font-size: 18px; font-weight: bold;">
澜沧拉祜族自治县中医医院粪便常规检验报告单
澜沧拉祜族自治县中医医院<span th:text="${baseInfo.lspcmName}"></span>报告单
</div>
</div>
<div style="height: 10px;"></div>
@ -20,13 +20,13 @@
<tr>
<td style="width: 33%;">
<span>姓名:</span>
<span style="display: inline-block; min-width: 150px; ">张某某</span>
<span style="display: inline-block; min-width: 150px;" th:text="${baseInfo.patName}"></span>
</td>
<td style="width: 33%;">
</td>
<td style="width: 33%;">
<span>标本编号:</span>
<span style="display: inline-block; min-width: 150px; ">FS20230615008</span>
<span style="display: inline-block; min-width: 150px;" th:text="${baseInfo.reportId}"></span>
</td>
</tr>
@ -34,15 +34,15 @@
<tr>
<td style="width: 33%;">
<span>性别:</span>
<span style="display: inline-block;"></span>
<span style="display: inline-block;" th:text="${baseInfo.patSex}"></span>
</td>
<td style="width: 33%;">
<span>科室:</span>
<span style="display: inline-block;">消化内科</span>
<span style="display: inline-block;" th:text="${baseInfo.deptName}"></span>
</td>
<td style="width: 33%;">
<span>标本类型:</span>
<span style="display: inline-block;">粪便</span>
<span style="display: inline-block;" th:text="${baseInfo.lspcmName}"></span>
</td>
</tr>
@ -50,15 +50,15 @@
<tr>
<td style="width: 33%;">
<span>年龄:</span>
<span style="display: inline-block;">42岁</span>
<span style="display: inline-block;" th:text="${baseInfo.patAge}"></span>
</td>
<td style="width: 33%;">
<span>床号:</span>
<span style="display: inline-block;">15</span>
<span style="display: inline-block;" th:text="${baseInfo.inpBedNo}"></span>
</td>
<td style="width: 33%;">
<span>标本形态:</span>
<span style="display: inline-block; ">新鲜</span>
<span style="display: inline-block;"></span>
</td>
</tr>
@ -66,15 +66,15 @@
<tr>
<td style="width: 33%;">
<span>患者电话:</span>
<span style="display: inline-block;">138****5678</span>
<span style="display: inline-block;" th:text="${baseInfo.patHomePhno}"></span>
</td>
<td style="width: 33%;">
<span>申请医生:</span>
<span style="display: inline-block;">李医生</span>
<span style="display: inline-block;" th:text="${baseInfo.placerName}"></span>
</td>
<td style="width: 33%;">
<span>采样者:</span>
<span style="display: inline-block; ">护士A</span>
<span style="display: inline-block;" th:text="${baseInfo.spcmClctor}"></span>
</td>
</tr>
@ -82,15 +82,15 @@
<tr>
<td style="width: 33%;">
<span>申请项目:</span>
<span style="display: inline-block; min-width: 80px; ">粪便常规</span>
<span style="display: inline-block; min-width: 80px;" th:text="${baseInfo.citemContent}"></span>
</td>
<td style="width: 33%;">
<span>临床诊断:</span>
<span style="display: inline-block; min-width: 100px; ">腹痛待查</span>
<span style="display: inline-block; min-width: 80px;"></span>
</td>
<td style="width: 33%;">
<span>采样人:</span>
<span style="display: inline-block; min-width: 80px; ">检验科</span>
<span style="display: inline-block; min-width: 80px;" th:text="${baseInfo.spcmClctor}"></span>
</td>
</tr>
@ -98,7 +98,7 @@
<tr>
<td style="width: 33%;">
<span>仪器:</span>
<span style="display: inline-block; min-width: 130px; ">科瑞杰粪便分析仪</span>
<span style="display: inline-block; min-width: 130px;"></span>
</td>
<td style="width: 33%;">
</td>
@ -113,151 +113,28 @@
<tr style="background-color: #f0f0f0;height:30px;">
<th style="padding: 8px 5px; width: 25%;">项目名称</th>
<th style="padding: 8px 5px; width: 20%;">结果</th>
<th style="padding: 8px 5px; width: 10%;">单位</th>
<th style="padding: 8px 5px; width: 25%;">参考区间</th>
<th style="padding: 8px 5px; width: 15%;">单位</th>
<th style="padding: 8px 5px; width: 20%;">参考区间</th>
<th style="padding: 8px 5px; width: 20%;">测试方法</th>
</tr>
</thead>
<tbody style="text-align: center;">
<tr>
<td style="padding: 8px 5px;">颜色</td>
<td style="padding: 8px 5px;">黄褐色</td>
<td style="padding: 8px 5px;"></td>
<td style="padding: 8px 5px;">黄褐色</td>
<td style="padding: 8px 5px;">目测法</td>
<!-- 动态行渲染+异常值红色高亮 -->
<tr th:each="item : ${items}"
th:style="${item.oaflag=='1'} ? '' : 'background-color: #f9f9f9;color:red;'">
<td style="padding: 8px 5px;" th:text="${item.loitemCname}"></td>
<td style="padding: 8px 5px;" th:text="${item.orderRptResult}"></td>
<td style="padding: 8px 5px;" th:text="${item.loitemUnit}"></td>
<td style="padding: 8px 5px;" th:text="${item.loitemRv}"></td>
<td style="padding: 8px 5px;" th:text="${item.inspectionMethod}"></td>
</tr>
<tr style="background-color: #f9f9f9;">
<td style="padding: 8px 5px;">性状</td>
<td style="padding: 8px 5px;">软便</td>
<td style="padding: 8px 5px;"></td>
<td style="padding: 8px 5px;">软便</td>
<td style="padding: 8px 5px;">目测法</td>
</tr>
<tr>
<td style="padding: 8px 5px;">红细胞</td>
<td style="padding: 8px 5px;">未见</td>
<td style="padding: 8px 5px;">/HP</td>
<td style="padding: 8px 5px;">未见</td>
<td style="padding: 8px 5px;">镜检法</td>
</tr>
<tr style="background-color: #f9f9f9;">
<td style="padding: 8px 5px;">白细胞</td>
<td style="padding: 8px 5px;">0-2</td>
<td style="padding: 8px 5px;">/HP</td>
<td style="padding: 8px 5px;">0-3</td>
<td style="padding: 8px 5px;">镜检法</td>
</tr>
<tr>
<td style="padding: 8px 5px;">吞噬细胞</td>
<td style="padding: 8px 5px;">未见</td>
<td style="padding: 8px 5px;"></td>
<td style="padding: 8px 5px;">未见</td>
<td style="padding: 8px 5px;">镜检法</td>
</tr>
<tr style="background-color: #f9f9f9;">
<td style="padding: 8px 5px;">寄生虫卵</td>
<td style="padding: 8px 5px;">未找到</td>
<td style="padding: 8px 5px;"></td>
<td style="padding: 8px 5px;">未找到</td>
<td style="padding: 8px 5px;">镜检法</td>
</tr>
<tr>
<td style="padding: 8px 5px;">脂肪球</td>
<td style="padding: 8px 5px;">少量</td>
<td style="padding: 8px 5px;"></td>
<td style="padding: 8px 5px;">未见</td>
<td style="padding: 8px 5px;">苏丹III染色</td>
</tr>
<tr>
<td style="padding: 8px 5px;">颜色</td>
<td style="padding: 8px 5px;">黄褐色</td>
<td style="padding: 8px 5px;"></td>
<td style="padding: 8px 5px;">黄褐色</td>
<td style="padding: 8px 5px;">目测法</td>
</tr>
<tr style="background-color: #f9f9f9;">
<td style="padding: 8px 5px;">性状</td>
<td style="padding: 8px 5px;">软便</td>
<td style="padding: 8px 5px;"></td>
<td style="padding: 8px 5px;">软便</td>
<td style="padding: 8px 5px;">目测法</td>
</tr>
<tr>
<td style="padding: 8px 5px;">红细胞</td>
<td style="padding: 8px 5px;">未见</td>
<td style="padding: 8px 5px;">/HP</td>
<td style="padding: 8px 5px;">未见</td>
<td style="padding: 8px 5px;">镜检法</td>
</tr>
<tr style="background-color: #f9f9f9;">
<td style="padding: 8px 5px;">白细胞</td>
<td style="padding: 8px 5px;">0-2</td>
<td style="padding: 8px 5px;">/HP</td>
<td style="padding: 8px 5px;">0-3</td>
<td style="padding: 8px 5px;">镜检法</td>
</tr>
<tr>
<td style="padding: 8px 5px;">吞噬细胞</td>
<td style="padding: 8px 5px;">未见</td>
<td style="padding: 8px 5px;"></td>
<td style="padding: 8px 5px;">未见</td>
<td style="padding: 8px 5px;">镜检法</td>
</tr>
<tr style="background-color: #f9f9f9;">
<td style="padding: 8px 5px;">寄生虫卵</td>
<td style="padding: 8px 5px;">未找到</td>
<td style="padding: 8px 5px;"></td>
<td style="padding: 8px 5px;">未找到</td>
<td style="padding: 8px 5px;">镜检法</td>
</tr>
<tr>
<td style="padding: 8px 5px;">脂肪球</td>
<td style="padding: 8px 5px;">少量</td>
<td style="padding: 8px 5px;"></td>
<td style="padding: 8px 5px;">未见</td>
<td style="padding: 8px 5px;">苏丹III染色</td>
</tr>
<tr>
<td style="padding: 8px 5px;">颜色</td>
<td style="padding: 8px 5px;">黄褐色</td>
<td style="padding: 8px 5px;"></td>
<td style="padding: 8px 5px;">黄褐色</td>
<td style="padding: 8px 5px;">目测法</td>
</tr>
<tr style="background-color: #f9f9f9;">
<td style="padding: 8px 5px;">性状</td>
<td style="padding: 8px 5px;">软便</td>
<td style="padding: 8px 5px;"></td>
<td style="padding: 8px 5px;">软便</td>
<td style="padding: 8px 5px;">目测法</td>
</tr>
<tr>
<td style="padding: 8px 5px;">红细胞</td>
<td style="padding: 8px 5px;">未见</td>
<td style="padding: 8px 5px;">/HP</td>
<td style="padding: 8px 5px;">未见</td>
<td style="padding: 8px 5px;">镜检法</td>
</tr>
<tr style="background-color: #f9f9f9;">
<td style="padding: 8px 5px;">白细胞</td>
<td style="padding: 8px 5px;">0-2</td>
<td style="padding: 8px 5px;">/HP</td>
<td style="padding: 8px 5px;">0-3</td>
<td style="padding: 8px 5px;">镜检法</td>
</tr>
<tr>
<td style="padding: 8px 5px;">吞噬细胞</td>
<td style="padding: 8px 5px;">未见</td>
<td style="padding: 8px 5px;"></td>
<td style="padding: 8px 5px;">未见</td>
<td style="padding: 8px 5px;">镜检法</td>
</tr>
<tr style="background-color: #f9f9f9;">
<td style="padding: 8px 5px;">寄生虫卵</td>
<td style="padding: 8px 5px;">未找到</td>
<td style="padding: 8px 5px;"></td>
<td style="padding: 8px 5px;">未找到</td>
<td style="padding: 8px 5px;">镜检法</td>
<!-- 补齐空行 -->
<tr th:each="i : ${#numbers.sequence(1, 10 - items.size())}" th:if="${items.size()} < 10">
<td style="padding: 8px 5px;">&nbsp;</td>
<td style="padding: 8px 5px;">&nbsp;</td>
<td style="padding: 8px 5px;">&nbsp;</td>
<td style="padding: 8px 5px;">&nbsp;</td>
<td style="padding: 8px 5px;">&nbsp;</td>
</tr>
</tbody>
</table>
@ -265,10 +142,7 @@
<!-- 建议与解释 -->
<div>
<div style="padding-top: 10px;">
建议与解释:您的粪便检查结果显示存在轻度脂肪滴和少量未消化食物残渣。建议:
1注意饮食结构调整避免高脂、高蛋白饮食
2可补充消化酶类药物
3一周后复查。如有持续腹痛或腹泻症状请及时复诊。
建议与解释:
</div>
</div>
</div>