新增检验报告打印接口
This commit is contained in:
parent
25597dcfc9
commit
97aa3efef6
23
pom.xml
23
pom.xml
|
@ -17,7 +17,7 @@
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<java.version>1.8</java.version>
|
<java.version>11</java.version>
|
||||||
<hutool.version>5.8.36</hutool.version>
|
<hutool.version>5.8.36</hutool.version>
|
||||||
<jna.version>5.17.0</jna.version>
|
<jna.version>5.17.0</jna.version>
|
||||||
<pdfbox.version>3.0.2</pdfbox.version>
|
<pdfbox.version>3.0.2</pdfbox.version>
|
||||||
|
@ -159,6 +159,27 @@
|
||||||
<groupId>jakarta.xml.bind</groupId>
|
<groupId>jakarta.xml.bind</groupId>
|
||||||
<artifactId>jakarta.xml.bind-api</artifactId>
|
<artifactId>jakarta.xml.bind-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- 报告打印转PDF -->
|
||||||
|
<!-- iText 核心 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.itextpdf</groupId>
|
||||||
|
<artifactId>itextpdf</artifactId>
|
||||||
|
<version>5.5.13.3</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- XML Worker (HTML 转 PDF) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.itextpdf.tool</groupId>
|
||||||
|
<artifactId>xmlworker</artifactId>
|
||||||
|
<version>5.5.13.3</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 中文字体支持 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.itextpdf</groupId>
|
||||||
|
<artifactId>itext-asian</artifactId>
|
||||||
|
<version>5.2.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,13 @@ import com.dpkj.common.dto.LexMarkResultDTO;
|
||||||
import com.dpkj.common.vo.Result;
|
import com.dpkj.common.vo.Result;
|
||||||
import com.dpkj.modules.print.request.MS439Request;
|
import com.dpkj.modules.print.request.MS439Request;
|
||||||
import com.dpkj.modules.print.service.MS439PrintService;
|
import com.dpkj.modules.print.service.MS439PrintService;
|
||||||
import com.dpkj.modules.print.vo.PrinterStatus;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MS439控制层,利盟打印机
|
* MS439控制层,利盟打印机
|
||||||
|
@ -24,12 +27,28 @@ public class MS439Controller {
|
||||||
private MS439PrintService ms439PrintService;
|
private MS439PrintService ms439PrintService;
|
||||||
|
|
||||||
@PostMapping("/print")
|
@PostMapping("/print")
|
||||||
public Result<LexMarkResultDTO<?>> print(@Validated @RequestBody MS439Request request){
|
public Result<LexMarkResultDTO<?>> print(@Validated @RequestBody MS439Request request) {
|
||||||
return Result.ok(ms439PrintService.printImage(request));
|
return Result.ok(ms439PrintService.printImage(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检验报告打印
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping("/printJY")
|
||||||
|
public Result<LexMarkResultDTO<?>> printJY() {
|
||||||
|
MS439Request ms439Request = new MS439Request();
|
||||||
|
// 获取检验报告PDF
|
||||||
|
String path = ms439PrintService.getJYPDFPath();
|
||||||
|
ms439Request.setPagesource("A5");
|
||||||
|
ms439Request.setFileDir(path);
|
||||||
|
LexMarkResultDTO<?> result = ms439PrintService.printImage(ms439Request);
|
||||||
|
return Result.ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/getStatus")
|
@PostMapping("/getStatus")
|
||||||
public Result<String> print(@RequestParam(defaultValue = "A4") String papersource){
|
public Result<String> print(@RequestParam(defaultValue = "A4") String papersource) {
|
||||||
this.ms439PrintService.getStatus(papersource);
|
this.ms439PrintService.getStatus(papersource);
|
||||||
return Result.ok();
|
return Result.ok();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,12 @@ package com.dpkj.modules.print.service;
|
||||||
import com.dpkj.common.dto.LexMarkResultDTO;
|
import com.dpkj.common.dto.LexMarkResultDTO;
|
||||||
import com.dpkj.modules.print.request.MS439Request;
|
import com.dpkj.modules.print.request.MS439Request;
|
||||||
import com.dpkj.modules.print.vo.PrinterStatus;
|
import com.dpkj.modules.print.vo.PrinterStatus;
|
||||||
import javassist.compiler.Lex;
|
|
||||||
|
|
||||||
public interface MS439PrintService {
|
public interface MS439PrintService {
|
||||||
|
|
||||||
LexMarkResultDTO<?> printImage(MS439Request request);
|
LexMarkResultDTO<?> printImage(MS439Request request);
|
||||||
|
|
||||||
LexMarkResultDTO<PrinterStatus> getStatus(String papersource);
|
LexMarkResultDTO<PrinterStatus> getStatus(String papersource);
|
||||||
|
|
||||||
|
String getJYPDFPath();
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,17 +6,48 @@ import com.dpkj.common.dto.LexMarkDTO;
|
||||||
import com.dpkj.common.dto.LexMarkResultDTO;
|
import com.dpkj.common.dto.LexMarkResultDTO;
|
||||||
import com.dpkj.common.exception.RRException;
|
import com.dpkj.common.exception.RRException;
|
||||||
import com.dpkj.common.utils.ThirdService;
|
import com.dpkj.common.utils.ThirdService;
|
||||||
import com.dpkj.modules.print.enums.*;
|
import com.dpkj.modules.print.enums.MS439DeviceStatusEnum;
|
||||||
|
import com.dpkj.modules.print.enums.MS439InkStatusEnum;
|
||||||
|
import com.dpkj.modules.print.enums.MS439MediaStatusEnum;
|
||||||
|
import com.dpkj.modules.print.enums.MS439PaperStatusEnum;
|
||||||
|
import com.dpkj.modules.print.enums.MS439StampStatusEnum;
|
||||||
|
import com.dpkj.modules.print.enums.MS439TonerStatusEnum;
|
||||||
import com.dpkj.modules.print.request.MS439Request;
|
import com.dpkj.modules.print.request.MS439Request;
|
||||||
import com.dpkj.modules.print.service.MS439PrintService;
|
import com.dpkj.modules.print.service.MS439PrintService;
|
||||||
import com.dpkj.modules.print.utils.FolderUtils;
|
import com.dpkj.modules.print.utils.FolderUtils;
|
||||||
|
import com.dpkj.modules.print.utils.FontLoader;
|
||||||
import com.dpkj.modules.print.utils.PDFUtils;
|
import com.dpkj.modules.print.utils.PDFUtils;
|
||||||
import com.dpkj.modules.print.vo.PrinterStatus;
|
import com.dpkj.modules.print.vo.PrinterStatus;
|
||||||
|
import com.itextpdf.text.BaseColor;
|
||||||
|
import com.itextpdf.text.Document;
|
||||||
|
import com.itextpdf.text.DocumentException;
|
||||||
|
import com.itextpdf.text.Font;
|
||||||
|
import com.itextpdf.text.PageSize;
|
||||||
|
import com.itextpdf.text.pdf.BaseFont;
|
||||||
|
import com.itextpdf.text.pdf.PdfWriter;
|
||||||
|
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
|
||||||
|
import com.itextpdf.tool.xml.XMLWorkerHelper;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebApplicationContext;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.thymeleaf.TemplateEngine;
|
||||||
|
import org.thymeleaf.context.Context;
|
||||||
|
import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
|
||||||
|
import org.thymeleaf.templatemode.TemplateMode;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 利盟MS439打印机服务
|
* 利盟MS439打印机服务
|
||||||
|
@ -49,7 +80,7 @@ public class MS439PrintServiceImpl implements MS439PrintService {
|
||||||
PrinterStatus ms439 = status.getData();
|
PrinterStatus ms439 = status.getData();
|
||||||
|
|
||||||
// 如果是要盖章,校验盖章机器是否正常
|
// 如果是要盖章,校验盖章机器是否正常
|
||||||
if ( request.getStamp() == 1) {
|
if (request.getStamp() == 1) {
|
||||||
String deviceExStatus = ms439.getStDeviceExStatus();
|
String deviceExStatus = ms439.getStDeviceExStatus();
|
||||||
if (deviceExStatus == null || deviceExStatus.equals("")) {
|
if (deviceExStatus == null || deviceExStatus.equals("")) {
|
||||||
throw new RRException("获取打印机设备状态出问题");
|
throw new RRException("获取打印机设备状态出问题");
|
||||||
|
@ -60,7 +91,7 @@ public class MS439PrintServiceImpl implements MS439PrintService {
|
||||||
}
|
}
|
||||||
String device = devices[1];
|
String device = devices[1];
|
||||||
// 校验盖章机是否正常,除了HEALTHY都抛异常
|
// 校验盖章机是否正常,除了HEALTHY都抛异常
|
||||||
if (!device.equals(MS439StampStatusEnum.HEALTHY.getPrintCode()) ) {
|
if (!device.equals(MS439StampStatusEnum.HEALTHY.getPrintCode())) {
|
||||||
throw new RRException(MS439StampStatusEnum.getPCode(device),
|
throw new RRException(MS439StampStatusEnum.getPCode(device),
|
||||||
MS439StampStatusEnum.getMessage(device));
|
MS439StampStatusEnum.getMessage(device));
|
||||||
}
|
}
|
||||||
|
@ -72,7 +103,7 @@ public class MS439PrintServiceImpl implements MS439PrintService {
|
||||||
lexMarkDTO.setDevName("HtmPrinter");
|
lexMarkDTO.setDevName("HtmPrinter");
|
||||||
lexMarkDTO.setPluginMethod("exec");
|
lexMarkDTO.setPluginMethod("exec");
|
||||||
|
|
||||||
JSONObject param = new JSONObject();
|
JSONObject param = new JSONObject();
|
||||||
|
|
||||||
// printType 选择箱子
|
// printType 选择箱子
|
||||||
// param.put("prtData", String.format("PrintType=%d;pagesource=%s;copies=%d;file[0]=%s;stamp=%d;duplex=%d;color=%d;direction=%d",
|
// param.put("prtData", String.format("PrintType=%d;pagesource=%s;copies=%d;file[0]=%s;stamp=%d;duplex=%d;color=%d;direction=%d",
|
||||||
|
@ -104,7 +135,7 @@ public class MS439PrintServiceImpl implements MS439PrintService {
|
||||||
lexMarkDTO.setParam(param.toString());
|
lexMarkDTO.setParam(param.toString());
|
||||||
LexMarkResultDTO<LexMarkResultDTO.Param> paramLexMarkResultDTO = thirdService.callDevice(lexMarkDTO, LexMarkResultDTO.Param.class);
|
LexMarkResultDTO<LexMarkResultDTO.Param> paramLexMarkResultDTO = thirdService.callDevice(lexMarkDTO, LexMarkResultDTO.Param.class);
|
||||||
|
|
||||||
if ( paramLexMarkResultDTO.getData().getResult() != 0){
|
if (paramLexMarkResultDTO.getData().getResult() != 0) {
|
||||||
throw new RRException(500, paramLexMarkResultDTO.getData().getResult() + "");
|
throw new RRException(500, paramLexMarkResultDTO.getData().getResult() + "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +163,7 @@ public class MS439PrintServiceImpl implements MS439PrintService {
|
||||||
lexMarkDTO.setPluginMethod("exec");
|
lexMarkDTO.setPluginMethod("exec");
|
||||||
|
|
||||||
LexMarkResultDTO<PrinterStatus> status = thirdService.callDevice(lexMarkDTO, PrinterStatus.class);
|
LexMarkResultDTO<PrinterStatus> status = thirdService.callDevice(lexMarkDTO, PrinterStatus.class);
|
||||||
if ( status.getResult() != 0){
|
if (status.getResult() != 0) {
|
||||||
thirdService.open("HtmPrinter", 0);
|
thirdService.open("HtmPrinter", 0);
|
||||||
status = thirdService.callDevice(lexMarkDTO, PrinterStatus.class);
|
status = thirdService.callDevice(lexMarkDTO, PrinterStatus.class);
|
||||||
}
|
}
|
||||||
|
@ -142,7 +173,7 @@ public class MS439PrintServiceImpl implements MS439PrintService {
|
||||||
throw new RRException("获取打印机纸张状态出问题");
|
throw new RRException("获取打印机纸张状态出问题");
|
||||||
}
|
}
|
||||||
String[] papers = stPaperEx.split("\\|");
|
String[] papers = stPaperEx.split("\\|");
|
||||||
if ( papers.length < 2) {
|
if (papers.length < 2) {
|
||||||
throw new RRException("打印机纸盒数量不对");
|
throw new RRException("打印机纸盒数量不对");
|
||||||
}
|
}
|
||||||
String paperStatus = "";
|
String paperStatus = "";
|
||||||
|
@ -154,13 +185,13 @@ public class MS439PrintServiceImpl implements MS439PrintService {
|
||||||
if (papersource.equals("A5")) {
|
if (papersource.equals("A5")) {
|
||||||
paperStatus = printerConfig.getLevelOne().equals("A5") ? papers[0] : papers[1];
|
paperStatus = printerConfig.getLevelOne().equals("A5") ? papers[0] : papers[1];
|
||||||
}
|
}
|
||||||
if ( !(paperStatus.equals(MS439PaperStatusEnum.PAPERFULL.getPrintCode()) || paperStatus.equals(MS439PaperStatusEnum.PAPERLOW.getPrintCode()))){
|
if (!(paperStatus.equals(MS439PaperStatusEnum.PAPERFULL.getPrintCode()) || paperStatus.equals(MS439PaperStatusEnum.PAPERLOW.getPrintCode()))) {
|
||||||
throw new RRException(500, paperStatus);
|
throw new RRException(500, paperStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
PrinterStatus ms439 = status.getData();
|
PrinterStatus ms439 = status.getData();
|
||||||
// 校验打印机是否正常,除了HEALTHY都抛异常
|
// 校验打印机是否正常,除了HEALTHY都抛异常
|
||||||
if (!ms439.getStDeviceStatus().equals(MS439DeviceStatusEnum.HEALTHY.getPrintCode()) ) {
|
if (!ms439.getStDeviceStatus().equals(MS439DeviceStatusEnum.HEALTHY.getPrintCode())) {
|
||||||
throw new RRException(500, ms439.getStDeviceStatus());
|
throw new RRException(500, ms439.getStDeviceStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,19 +201,131 @@ public class MS439PrintServiceImpl implements MS439PrintService {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 校验磁带 满或者少才放行
|
// 校验磁带 满或者少才放行
|
||||||
if ( !(ms439.getStToner().equals(MS439TonerStatusEnum.TONERFULL.getPrintCode()) || ms439.getStToner().equals(MS439TonerStatusEnum.TONERLOW.getPrintCode()))){
|
if (!(ms439.getStToner().equals(MS439TonerStatusEnum.TONERFULL.getPrintCode()) || ms439.getStToner().equals(MS439TonerStatusEnum.TONERLOW.getPrintCode()))) {
|
||||||
throw new RRException(500, ms439.getStToner());
|
throw new RRException(500, ms439.getStToner());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 校验墨盒 满或者少才放行,当前获取为未知
|
// 校验墨盒 满或者少才放行,当前获取为未知
|
||||||
if ( false && !(ms439.getStInk().equals(MS439InkStatusEnum.INKFULL.getPrintCode()) || ms439.getStInk().equals(MS439InkStatusEnum.INKLOW.getPrintCode())
|
if (false && !(ms439.getStInk().equals(MS439InkStatusEnum.INKFULL.getPrintCode()) || ms439.getStInk().equals(MS439InkStatusEnum.INKLOW.getPrintCode())
|
||||||
|| ms439.getStInk().equals(MS439InkStatusEnum.INKUNKNOWN.getPrintCode()))){
|
|| ms439.getStInk().equals(MS439InkStatusEnum.INKUNKNOWN.getPrintCode()))) {
|
||||||
throw new RRException(500, ms439.getStInk());
|
throw new RRException(500, ms439.getStInk());
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getJYPDFPath() {
|
||||||
|
// 1. 准备输出路径
|
||||||
|
String dirPath = "D:/TempJYPDF/";
|
||||||
|
File dir = new File(dirPath);// 确保目录存在
|
||||||
|
if (!dir.exists()) {
|
||||||
|
dir.mkdirs();
|
||||||
|
}
|
||||||
|
String fileName = "report_jy_" + System.currentTimeMillis() + ".pdf";
|
||||||
|
String pdfPath = dirPath + fileName;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 2. 准备模板数据
|
||||||
|
Map<String, Object> data = prepareReportData();
|
||||||
|
// 3. 渲染Thymeleaf模板
|
||||||
|
String htmlContent = renderThymeleafTemplate(data);
|
||||||
|
// 4. 生成PDF文件
|
||||||
|
createPdfFromHtml(htmlContent, pdfPath);
|
||||||
|
|
||||||
|
return pdfPath;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace(); // 打印完整异常堆栈
|
||||||
|
throw new RuntimeException("PDF生成失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createPdfFromHtml(String html, String outputPath)
|
||||||
|
throws IOException, DocumentException {
|
||||||
|
|
||||||
|
// 大小为A5纸
|
||||||
|
Document document = new Document(PageSize.A5);
|
||||||
|
try (OutputStream os = Files.newOutputStream(Paths.get(outputPath))) {
|
||||||
|
PdfWriter writer = PdfWriter.getInstance(document, os);
|
||||||
|
document.open();
|
||||||
|
|
||||||
|
// 加载自定义字体
|
||||||
|
BaseFont simfangFont = FontLoader.loadFont("/font/simfang.ttf");
|
||||||
|
|
||||||
|
// 创建自定义字体提供器
|
||||||
|
XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider() {
|
||||||
|
@Override
|
||||||
|
public Font getFont(String fontname, String encoding, boolean embedded, float size, int style, BaseColor color) {
|
||||||
|
return new Font(simfangFont, size, style, color);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 解析 HTML 并生成 PDF
|
||||||
|
XMLWorkerHelper.getInstance().parseXHtml(
|
||||||
|
writer, document,
|
||||||
|
new ByteArrayInputStream(html.getBytes(StandardCharsets.UTF_8)),
|
||||||
|
null, StandardCharsets.UTF_8,
|
||||||
|
fontProvider // 注入字体提供器
|
||||||
|
);
|
||||||
|
document.close(); // 这里关闭,确保 OutputStream 还没被关闭
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 模板渲染方法(保持不变)
|
||||||
|
private String renderThymeleafTemplate(Map<String, Object> data) {
|
||||||
|
// 设置模板数据
|
||||||
|
Context context = new Context();
|
||||||
|
context.setVariables(data);
|
||||||
|
|
||||||
|
// 填充数据到html
|
||||||
|
TemplateEngine templateEngine = new TemplateEngine();
|
||||||
|
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
|
||||||
|
resolver.setPrefix("classpath:/templates/");
|
||||||
|
resolver.setSuffix(".html");
|
||||||
|
resolver.setTemplateMode(TemplateMode.HTML);
|
||||||
|
resolver.setCacheable(true);
|
||||||
|
resolver.setApplicationContext(new AnnotationConfigReactiveWebApplicationContext());
|
||||||
|
templateEngine.setTemplateResolver(resolver);
|
||||||
|
return templateEngine.process("reportJY", context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 报告数据准备(根据实际业务实现)
|
||||||
|
private Map<String, Object> prepareReportData() {
|
||||||
|
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);
|
||||||
|
|
||||||
|
// 检验项目数据
|
||||||
|
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);
|
||||||
|
|
||||||
|
// 系统信息
|
||||||
|
data.put("reportTime", new Date());
|
||||||
|
data.put("doctor", "李医师");
|
||||||
|
data.put("reviewer", "王主任");
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addItem(List<Map<String, Object>> items, String name,
|
||||||
|
String value, String range, String unit, boolean abnormal) {
|
||||||
|
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);
|
||||||
|
items.add(item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.dpkj.modules.print.utils;
|
||||||
|
|
||||||
|
import com.itextpdf.text.pdf.BaseFont;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 余文财
|
||||||
|
* @description 字体加载
|
||||||
|
* @date 2025.6.24
|
||||||
|
*/
|
||||||
|
public class FontLoader {
|
||||||
|
public static BaseFont loadFont(String resourcePath) {
|
||||||
|
try (InputStream fontStream = FontLoader.class.getResourceAsStream(resourcePath)) {
|
||||||
|
if (fontStream == null) {
|
||||||
|
throw new IllegalArgumentException("字体文件未找到: " + resourcePath);
|
||||||
|
}
|
||||||
|
// 创建支持中文的 BaseFont
|
||||||
|
return BaseFont.createFont(
|
||||||
|
resourcePath,
|
||||||
|
BaseFont.IDENTITY_H,
|
||||||
|
BaseFont.EMBEDDED,
|
||||||
|
false,
|
||||||
|
fontStream.readAllBytes(),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("字体加载失败: " + resourcePath, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,69 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8"/>
|
||||||
|
<title>检验报告单</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<!-- 标题区域 -->
|
||||||
|
<div style="text-align:center; margin-bottom:20px;">
|
||||||
|
<h2 style="color:#003366;">澜沧拉祜族自治县中医医院血常规检验报告单</h2>
|
||||||
|
<p>报告时间: <span th:text="${#dates.format(reportTime, 'yyyy-MM-dd HH:mm')}"></span></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 患者信息表格 -->
|
||||||
|
<div>
|
||||||
|
<table style="width:100%; border-collapse:collapse;">
|
||||||
|
<tr>
|
||||||
|
<td style="width:15%; padding:5px; border:1px solid #ddd;">姓名</td>
|
||||||
|
<td style="width:35%; padding:5px; border:1px solid #ddd;" th:text="${patient.name}"></td>
|
||||||
|
<td style="width:15%; padding:5px; border:1px solid #ddd;">性别</td>
|
||||||
|
<td style="width:35%; padding:5px; border:1px solid #ddd;" th:text="${patient.gender}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding:5px; border:1px solid #ddd;">年龄</td>
|
||||||
|
<td style="padding:5px; border:1px solid #ddd;" th:text="${patient.age}"></td>
|
||||||
|
<td style="padding:5px; border:1px solid #ddd;">病历号</td>
|
||||||
|
<td style="padding:5px; border:1px solid #ddd;" th:text="${patient.medicalRecord}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding:5px; border:1px solid #ddd;">科室</td>
|
||||||
|
<td style="padding:5px; border:1px solid #ddd;" th:text="${patient.department}"></td>
|
||||||
|
<td style="padding:5px; border:1px solid #ddd;">床号</td>
|
||||||
|
<td style="padding:5px; border:1px solid #ddd;" th:text="${patient.bedNumber}"></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 检测结果表格 -->
|
||||||
|
<table style="width:100%; border-collapse:collapse; margin-top:20px;">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="border:1px solid #ddd; padding:8px; text-align:center; background-color:#f2f2f2;">检测项目</th>
|
||||||
|
<th style="border:1px solid #ddd; padding:8px; text-align:center; background-color:#f2f2f2;">结果</th>
|
||||||
|
<th style="border:1px solid #ddd; padding:8px; text-align:center; background-color:#f2f2f2;">参考范围</th>
|
||||||
|
<th style="border:1px solid #ddd; padding:8px; text-align:center; background-color:#f2f2f2;">单位</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<!-- 动态行渲染+异常值红色高亮 -->
|
||||||
|
<tr th:each="item : ${items}"
|
||||||
|
th:style="${item.isAbnormal} ? 'color:red;' : ''">
|
||||||
|
<td style="border:1px solid #ddd; padding:8px; text-align:center;" th:text="${item.name}"></td>
|
||||||
|
<td style="border:1px solid #ddd; padding:8px; text-align:center;" th:text="${item.result}"></td>
|
||||||
|
<td style="border:1px solid #ddd; padding:8px; text-align:center;" th:text="${item.referenceRange}"></td>
|
||||||
|
<td style="border:1px solid #ddd; padding:8px; text-align:center;" th:text="${item.unit}"></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- 页脚声明 -->
|
||||||
|
<div style="margin-top:30px; text-align:right;">
|
||||||
|
<div>检验医生: <span th:text="${doctor}"></span></div>
|
||||||
|
<div>审核医生: <span th:text="${reviewer}"></span></div>
|
||||||
|
<div>声明: 本报告仅对此标本负责,如有疑问请3日内联系检验科</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue