Browse Source

feat:[试验管理][试验方法]导出

master
HanLong 4 days ago
parent
commit
8a735e48d2
6 changed files with 382 additions and 7 deletions
  1. +33
    -2
      hxhq-modules/hxhq-system/src/main/java/com/hxhq/business/controller/StudyMethodController.java
  2. +1
    -0
      hxhq-modules/hxhq-system/src/main/java/com/hxhq/business/service/IStudyMethodReadService.java
  3. +9
    -0
      hxhq-modules/hxhq-system/src/main/java/com/hxhq/business/service/impl/StudyMethodReadServiceImpl.java
  4. +1
    -0
      hxhq-modules/hxhq-system/src/main/java/com/hxhq/business/service/impl/StudyMethodServiceImpl.java
  5. +72
    -5
      hxhq-modules/hxhq-system/src/main/java/com/hxhq/business/utils/PdfUtil.java
  6. +266
    -0
      hxhq-modules/hxhq-system/src/main/java/com/hxhq/business/utils/StudyMethodFileUtil.java

+ 33
- 2
hxhq-modules/hxhq-system/src/main/java/com/hxhq/business/controller/StudyMethodController.java View File

@ -1,14 +1,19 @@
package com.hxhq.business.controller; package com.hxhq.business.controller;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hxhq.business.domain.StudyMethodRead;
import com.hxhq.business.form.study.StudyMethodForm; import com.hxhq.business.form.study.StudyMethodForm;
import com.hxhq.business.form.study.StudyMethodReadForm; import com.hxhq.business.form.study.StudyMethodReadForm;
import com.hxhq.business.form.study.StudyMethodSearchForm; import com.hxhq.business.form.study.StudyMethodSearchForm;
import com.hxhq.business.service.IStudyMethodReadService;
import com.hxhq.business.utils.StudyMethodFileUtil;
import com.hxhq.common.core.domain.MpBaseEntity;
import com.hxhq.common.security.utils.SecurityUtils; import com.hxhq.common.security.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import com.hxhq.business.domain.StudyMethod; import com.hxhq.business.domain.StudyMethod;
@ -30,6 +35,12 @@ public class StudyMethodController extends BaseController {
@Autowired @Autowired
private IStudyMethodService studyMethodService; private IStudyMethodService studyMethodService;
@Autowired
private IStudyMethodReadService studyMethodReadService;
@Autowired
private StudyMethodFileUtil studyMethodFileUtil;
/** /**
* 查询试验-试验方法列表 * 查询试验-试验方法列表
*/ */
@ -64,4 +75,24 @@ public class StudyMethodController extends BaseController {
studyMethodService.read(form); studyMethodService.read(form);
return AjaxResult.success(); return AjaxResult.success();
} }
@GetMapping(value = "/read/list")
public AjaxResult getReadList(Long studyMethodId) {
List<StudyMethodRead> list = studyMethodReadService.queryList(studyMethodId);
return AjaxResult.success(list);
}
@GetMapping(value = "/test")
public AjaxResult test(Long studyMethodId) {
StudyMethod studyMethod = studyMethodService.getById(studyMethodId);
if(studyMethod == null) {
return error("试验方法不存在或已删除");
}
List<StudyMethodRead> list = studyMethodReadService.queryList(studyMethodId);
String exportStudyMethodFilePath = studyMethodFileUtil.exportStudyMethodFile(studyMethod, list);
Map<String, String> result = new HashMap<>();
result.put("fileUrl", exportStudyMethodFilePath);
return AjaxResult.success(result);
}
} }

+ 1
- 0
hxhq-modules/hxhq-system/src/main/java/com/hxhq/business/service/IStudyMethodReadService.java View File

@ -15,4 +15,5 @@ import java.util.List;
*/ */
public interface IStudyMethodReadService extends IService<StudyMethodRead> public interface IStudyMethodReadService extends IService<StudyMethodRead>
{ {
List<StudyMethodRead> queryList(Long studyMethodId);
} }

+ 9
- 0
hxhq-modules/hxhq-system/src/main/java/com/hxhq/business/service/impl/StudyMethodReadServiceImpl.java View File

@ -1,5 +1,6 @@
package com.hxhq.business.service.impl; package com.hxhq.business.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hxhq.business.domain.StudyMethod; import com.hxhq.business.domain.StudyMethod;
@ -9,6 +10,7 @@ import com.hxhq.business.mapper.StudyMethodMapper;
import com.hxhq.business.mapper.StudyMethodReadMapper; import com.hxhq.business.mapper.StudyMethodReadMapper;
import com.hxhq.business.service.IStudyMethodReadService; import com.hxhq.business.service.IStudyMethodReadService;
import com.hxhq.business.service.IStudyMethodService; import com.hxhq.business.service.IStudyMethodService;
import com.hxhq.common.core.domain.MpBaseEntity;
import com.hxhq.system.api.domain.SysUser; import com.hxhq.system.api.domain.SysUser;
import com.hxhq.system.service.ISysUserService; import com.hxhq.system.service.ISysUserService;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
@ -28,4 +30,11 @@ public class StudyMethodReadServiceImpl extends ServiceImpl
{ {
@Override
public List<StudyMethodRead> queryList(Long studyMethodId) {
LambdaQueryWrapper<StudyMethodRead> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(StudyMethodRead::getStudyMethodId, studyMethodId);
queryWrapper.orderByDesc(MpBaseEntity::getId);
return this.list(queryWrapper);
}
} }

+ 1
- 0
hxhq-modules/hxhq-system/src/main/java/com/hxhq/business/service/impl/StudyMethodServiceImpl.java View File

@ -94,6 +94,7 @@ public class StudyMethodServiceImpl extends ServiceImpl
studyMethodRead.setStudyMethodId(studyMethod.getId()); studyMethodRead.setStudyMethodId(studyMethod.getId());
studyMethodRead.setQmrId(qmr.getUserId()); studyMethodRead.setQmrId(qmr.getUserId());
studyMethodRead.setQmrMc(qmr.getNickName()); studyMethodRead.setQmrMc(qmr.getNickName());
studyMethodRead.setRemark(form.getRemark());
studyMethodRead.setQmyy("阅读"); studyMethodRead.setQmyy("阅读");
studyMethodReadService.save(studyMethodRead); studyMethodReadService.save(studyMethodRead);
} }

+ 72
- 5
hxhq-modules/hxhq-system/src/main/java/com/hxhq/business/utils/PdfUtil.java View File

@ -4,8 +4,6 @@ import com.hxhq.common.core.utils.DateUtils;
import com.itextpdf.text.*; import com.itextpdf.text.*;
import com.itextpdf.text.Font; import com.itextpdf.text.Font;
import com.itextpdf.text.pdf.*; import com.itextpdf.text.pdf.*;
import com.itextpdf.text.pdf.draw.LineSeparator;
import lombok.SneakyThrows;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -24,13 +22,80 @@ public class PdfUtil {
private static final Logger log = LoggerFactory.getLogger(PdfUtil.class); private static final Logger log = LoggerFactory.getLogger(PdfUtil.class);
public static void appendWithPdfStamper(String sourcePDF, String destPDF, String content)
throws IOException, DocumentException {
// 读取原始PDF
PdfReader reader = new PdfReader(sourcePDF);
// 获取总页数
int pageCount = reader.getNumberOfPages();
// 创建PdfStamper
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(destPDF));
// 获取PdfContentByte
PdfContentByte canvas = stamper.getOverContent(pageCount); // 最后一页添加
// 或者创建新页
stamper.insertPage(pageCount + 1, reader.getPageSize(1));
canvas = stamper.getOverContent(pageCount + 1);
// 开始写入内容
ColumnText ct = new ColumnText(canvas);
// 设置写入位置
ct.setSimpleColumn(36, 36, 559, 806); // 页面边距
// 添加内容
ct.addElement(new Paragraph("追加内容:"));
ct.addElement(new Paragraph(content));
ct.addElement(new Paragraph(new java.util.Date().toString()));
// 执行写入
ct.go();
stamper.close();
reader.close();
System.out.println("追加完成!");
}
public static void main(String[] args) { public static void main(String[] args) {
String fileDir="d:/";
/* String fileDir="d:/";
exportForm("张三 2025-12-12 14:52:52",fileDir); exportForm("张三 2025-12-12 14:52:52",fileDir);
exportTable("张三 2025-12-12 14:52:52",fileDir);
exportTable("张三 2025-12-12 14:52:52",fileDir);*/
/*try {
appendWithPdfStamper("D:\\hxhq\\uploadPath\\2026\\01\\08\\20260108135814A001.pdf", "D:\\hxhq\\uploadPath\\2026\\01\\08\\output.pdf",
"这是使用iText 5追加的内容。");
} catch (Exception e) {
e.printStackTrace();
}*/
exportTable("张三 2025-12-12 14:52:52","D:\\hxhq\\uploadPath\\2026\\01\\08");
} }
/** /**
* 复制原有PDF的所有页面到新Document中
*/
private static void copyOriginalPagesToDocument(Document doc, PdfWriter writer, PdfReader reader) throws DocumentException {
int pageCount = reader.getNumberOfPages();
PdfContentByte canvas = writer.getDirectContent(); // 获取直接内容画布
for (int i = 1; i <= pageCount; i++) {
doc.newPage(); // 新建一页与原PDF页面一一对应
// 5.5.11中通过PdfImportedPage导入原有页面
PdfImportedPage importedPage = writer.getImportedPage(reader, i);
// 将原有页面绘制到新文档的当前页
canvas.addTemplate(importedPage, 0, 0);
}
}
/**
* 导出form * 导出form
* @param headerText * @param headerText
* @param fileDir * @param fileDir
@ -145,6 +210,8 @@ public class PdfUtil {
document.addCreator("华西海圻"); document.addCreator("华西海圻");
document.addCreationDate(); document.addCreationDate();
document.open(); document.open();
// 6. 设置中文字体 // 6. 设置中文字体
@ -170,7 +237,7 @@ public class PdfUtil {
// 11. 表格数据 // 11. 表格数据
int rowNum = 0; int rowNum = 0;
for (int i = 0; i < 3; i ++) {
for (int i = 0; i < 300; i ++) {
// 交替行颜色 // 交替行颜色
if (rowNum % 2 == 0) { if (rowNum % 2 == 0) {
table.getDefaultCell().setBackgroundColor(BaseColor.WHITE); table.getDefaultCell().setBackgroundColor(BaseColor.WHITE);

+ 266
- 0
hxhq-modules/hxhq-system/src/main/java/com/hxhq/business/utils/StudyMethodFileUtil.java View File

@ -0,0 +1,266 @@
package com.hxhq.business.utils;
import com.hxhq.business.domain.StudyMethod;
import com.hxhq.business.domain.StudyMethodRead;
import com.hxhq.common.core.utils.DateUtils;
import com.hxhq.common.security.utils.SecurityUtils;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.*;
import java.util.List;
/**
* OpenPDF工具类 - 支持保存到本地文件
*/
@Component
public class StudyMethodFileUtil {
private static final Logger log = LoggerFactory.getLogger(StudyMethodFileUtil.class);
/**
* 资源映射路径 前缀
*/
@Value("${file.prefix}")
public String localFilePrefix;
/**
* 域名或本机访问地址
*/
@Value("${file.domain}")
public String domain;
/**
* 上传文件存储在本地的根路径
*/
@Value("${file.path}")
private String localFilePath;
public String exportStudyMethodFile(StudyMethod studyMethod, List<StudyMethodRead> list) {
String fileUrl = studyMethod.getFileUrl();
fileUrl = fileUrl.replaceFirst(localFilePrefix, "");
int indexOf = fileUrl.lastIndexOf("/");
String path = fileUrl.substring(0, indexOf);
String exportFileName = exportTable(SecurityUtils.getNickName() + DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD_HH_MM_SS), list,
localFilePath + fileUrl, localFilePath + File.separator + path);
return localFilePrefix + path + File.separator + exportFileName;
}
/**
* 复制原有PDF的所有页面到新Document中
*/
private static void copyOriginalPagesToDocument(Document doc, PdfWriter writer, PdfReader reader) throws DocumentException {
int pageCount = reader.getNumberOfPages();
PdfContentByte canvas = writer.getDirectContent(); // 获取直接内容画布
for (int i = 1; i <= pageCount; i++) {
doc.newPage(); // 新建一页与原PDF页面一一对应
// 5.5.11中通过PdfImportedPage导入原有页面
PdfImportedPage importedPage = writer.getImportedPage(reader, i);
// 将原有页面绘制到新文档的当前页
canvas.addTemplate(importedPage, 0, 0);
}
}
/**
* 导出table
* @param headerText
* @param fileDir
* @return
*/
public static String exportTable(String headerText, List<StudyMethodRead> list, String SRC_PDF, String fileDir) {
Document document = null;
FileOutputStream fos = null;
String filePath = "";
String fileName = "";
try {
// 1. 生成文件名
fileName = generateFileName();
// 2. 确保目录存在
File dir = new File(fileDir);
if (!dir.exists()) {
dir.mkdirs();
}
// 3. 完整文件路径
filePath = Paths.get(fileDir, fileName).toString();
// 创建PDF文档 设置文档边距避免内容遮挡页眉页脚
// 1. 读取原有PDF获取页面尺寸保证新文档与原文档格式一致
PdfReader srcReader = new PdfReader(SRC_PDF);
Rectangle pageSize = srcReader.getPageSize(1); // 取第一页尺寸作为新文档尺寸
// 2. 初始化DocumentiText 5的核心高层类
document = new Document(pageSize);
fos = new FileOutputStream(filePath);
// 3. 关联PdfWriter绑定Document和输出流5.5.11必须先创建Writer再open Document
PdfWriter writer = PdfWriter.getInstance(document, fos);
// 设置页面事件每页添加文字页眉
writer.setPageEvent(new TextHeaderEvent(headerText));
// 4. 设置PDF属性
document.addTitle("华西海圻");
document.addAuthor("华西海圻");
document.addCreator("华西海圻");
document.addCreationDate();
document.open();
// 5. 复制原有PDF的所有页面到新Document中
copyOriginalPagesToDocument(document, writer, srcReader);
// 6. 设置中文字体
BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
Font headerFont = new Font(bfChinese, 12, Font.BOLD);
Font contentFont = new Font(bfChinese, 10, Font.NORMAL);
// 7. 表格设置到新的一页
document.newPage();
// 8. 创建表格
PdfPTable table = new PdfPTable(4);
table.setWidthPercentage(100);
table.setSpacingBefore(10);
// 9. 表头
String[] headers = {"签名人", "签名意义", "签名时间", "备注"};
for (String header : headers) {
PdfPCell cell = new PdfPCell(new Phrase(header, headerFont));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setBackgroundColor(BaseColor.WHITE);
cell.setPadding(8);
cell.setBorderWidth(1);
table.addCell(cell);
}
// 10. 表格数据
int rowNum = 0;
for (StudyMethodRead studyMethodRead : list) {
// 交替行颜色
if (rowNum % 2 == 0) {
table.getDefaultCell().setBackgroundColor(BaseColor.WHITE);
} else {
table.getDefaultCell().setBackgroundColor(BaseColor.WHITE);
}
table.addCell(createCell(studyMethodRead.getQmrMc(), contentFont));
table.addCell(createCell(studyMethodRead.getQmyy(), contentFont));
table.addCell(createCell(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, studyMethodRead.getCreateTime()), contentFont));
table.addCell(createCell(studyMethodRead.getRemark(), contentFont));
rowNum++;
}
document.add(table);
log.info("生成成功:{}", filePath);
} catch (Exception e) {
log.error("生成失败", e);
throw new RuntimeException("生成失败: " + e.getMessage());
} finally {
if (document != null) {
document.close();
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
log.error("关闭文件流失败", e);
}
}
}
return fileName;
}
/**
* 创建表格
*/
private static PdfPCell createCell(String content, Font font) {
PdfPCell cell = new PdfPCell(new Phrase(content, font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setPadding(6);
cell.setMinimumHeight(25);
return cell;
}
/**
* 生成文件名
*/
private static String generateFileName() {
Random random= new Random();
String timestamp = DateUtils.dateTimeNow("yyyyMMddHHmmss");
return String.format("%s_%s.pdf", timestamp,random.nextInt(1000));
}
/**
* 页面事件处理类 - 每页添加文字页眉
*/
static class TextHeaderEvent extends PdfPageEventHelper {
private String headerText;
private BaseFont baseFont;
public TextHeaderEvent(String headerText) throws Exception {
this.headerText = headerText;
// 创建字体支持中文
this.baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
}
@Override
public void onEndPage(PdfWriter writer, Document document) {
try {
// 获取页面尺寸
Rectangle pageSize = document.getPageSize();
float pageWidth = pageSize.getWidth();
float pageHeight = pageSize.getHeight();
// 设置页眉参数
float topMargin = 15; // 顶部边距
float fontSize = 10; // 字体大小
// 计算文字宽度用于居中
float textWidth = baseFont.getWidthPoint(headerText, fontSize);
// 计算居中位置
float textX = (pageWidth - textWidth) / 2;
float textY = pageHeight - topMargin;
// 获取画布
PdfContentByte canvas = writer.getDirectContent();
// 添加页眉文字
canvas.beginText();
canvas.setFontAndSize(baseFont, fontSize);
canvas.setTextMatrix(textX, textY);
canvas.showText(headerText);
canvas.endText();
// 添加页眉分隔线可选
addHeaderLine(canvas, pageWidth, textY - 10);
} catch (Exception e) {
e.printStackTrace();
}
}
private void addHeaderLine(PdfContentByte canvas, float pageWidth, float yPos) {
canvas.setLineWidth(0.5f);
canvas.moveTo(50, yPos);
canvas.lineTo(pageWidth - 50, yPos);
canvas.stroke();
}
}
}

Loading…
Cancel
Save