pdf两个A5合并

This commit is contained in:
jiangs 2025-09-22 16:32:00 +08:00
parent d730f5a962
commit 73959671db
10 changed files with 265 additions and 165 deletions

View File

@ -48,20 +48,22 @@
<groupId>org.apache.xmlgraphics</groupId> <groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-all</artifactId> <artifactId>batik-all</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
</dependency>
<dependency> <dependency>
<groupId>com.czlis</groupId> <groupId>com.czlis</groupId>
<artifactId>lisresources</artifactId> <artifactId>lisresources</artifactId>
</dependency> </dependency>
<!-- iText 7 核心库 -->
<dependency> <dependency>
<groupId>org.apache.pdfbox</groupId> <groupId>com.itextpdf</groupId>
<artifactId>pdfbox-tools</artifactId> <artifactId>kernel</artifactId>
</dependency> </dependency>
<!-- iText 7 布局库 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>layout</artifactId>
</dependency>
</dependencies> </dependencies>

View File

@ -2,35 +2,35 @@ package com.czlis.interfaceCommon.utils;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.codec.Base64;
import com.czlis.common.config.RuoYiConfig; import com.czlis.common.config.RuoYiConfig;
import com.czlis.common.core.domain.Result; import com.czlis.common.core.domain.Result;
import com.czlis.common.utils.file.FileUtils;
import com.czlis.common.utils.ip.IpUtils; import com.czlis.common.utils.ip.IpUtils;
import com.czlis.common.utils.uuid.UUID;
import com.czlis.interfaceCommon.mapper.BackPaperMapper; import com.czlis.interfaceCommon.mapper.BackPaperMapper;
import com.czlis.interfaceCommon.pojo.entity.BackPaperDetail; import com.czlis.interfaceCommon.pojo.entity.BackPaperDetail;
import com.czlis.interfaceCommon.pojo.entity.BackPaperParam; import com.czlis.interfaceCommon.pojo.entity.BackPaperParam;
import com.czlis.interfaceCommon.pojo.entity.LabRptgetruledetailCX; import com.czlis.interfaceCommon.pojo.entity.LabRptgetruledetailCX;
import com.czlis.interfaceCommon.pojo.entity.BarCodeParam; import com.czlis.interfaceCommon.pojo.entity.BarCodeParam;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.element.Image;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.sf.jasperreports.engine.JREmptyDataSource; import net.sf.jasperreports.engine.JREmptyDataSource;
import org.apache.pdfbox.printing.PDFPrintable;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.print.*;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Copies;
import java.awt.print.*;
import java.io.File; import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.printing.Scaling;
import javax.print.attribute.standard.OrientationRequested;
@ -104,128 +104,6 @@ public class ReportUtil {
} }
} }
/**
* 打印 Base64 编码的 PDF
* @param base64Pdf Base64 编码的 PDF 字符串
* @param printerName 打印机名称(可为 null,使用默认打印机)
* @param copies 打印份数
* @throws Exception 异常
*/
public static void printBase64Pdf(String base64Pdf, String printerName, int copies) throws Exception {
// 1. Base64 解码为 PDF 字节数组
byte[] pdfBytes = Base64.getDecoder().decode(base64Pdf);
// 2. 加载 PDF 文档
try (PDDocument document = PDDocument.load(pdfBytes)) {
// 3. 获取打印服务
PrinterJob job = PrinterJob.getPrinterJob();
// 选择打印机(若指定名称)
if (printerName != null && !printerName.isEmpty()) {
PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
for (PrintService service : services) {
if (service.getName().contains(printerName)) {
job.setPrintService(service);
break;
}
}
}
// 4. 配置打印属性
PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
attributes.add(new Copies(copies));
attributes.add(OrientationRequested.LANDSCAPE);
// 5. 配置页面格式和可打印区域
Book book = new Book();
PageFormat pageFormat = job.defaultPage();
Paper paper = new Paper();
//paper.setSize(595, 842); // A4 宽度和高度(1/72 英寸)
paper.setSize(419, 595); // A5 宽度和高度(1/72 英寸)
paper.setImageableArea(0, 0, 419, 595); // 边距 40 点,可打印区域宽 515、高 762
pageFormat.setPaper(paper);
// 设置打印缩放
//ACTUAL_SIZE 不缩放,按 PDF 实际尺寸打印
//SCALE_TO_FIT 按比例缩放,使 PDF 内容适应纸张(宽、高同时适配,保持纵横比)
PDFPrintable printable = new PDFPrintable(document, Scaling.ACTUAL_SIZE);
book.append(printable, pageFormat, document.getNumberOfPages());
job.setPageable(book);
// 6. 执行打印
job.print(attributes);
}
}
/**
* 打印已存在的 PDF 文件(兼容各版本 PDFBox)
* @param pdfFilePath PDF 文件路径
* @param printerName 目标打印机名称(null 则使用默认打印机)
* @throws IOException PDF 文件加载异常
* @throws javax.print.PrintException 打印服务异常
*/
public static void printPdf(String pdfFilePath, String printerName) throws IOException, javax.print.PrintException {
// 1. 加载 PDF 文档
try (PDDocument document = PDDocument.load(new File(pdfFilePath))) {
// 2. 创建打印任务
PrinterJob job = PrinterJob.getPrinterJob();
// 5. 选择打印机
if (printerName != null && !printerName.isEmpty()) {
PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
PrintService targetService = null;
for (PrintService service : services) {
if (service.getName().contains(printerName)) {
targetService = service;
break;
}
}
if (targetService == null) {
throw new javax.print.PrintException("未找到打印机:" + printerName);
}
job.setPrintService(targetService);
} else {
// 使用默认打印机
PrintService defaultService = PrintServiceLookup.lookupDefaultPrintService();
if (defaultService != null) {
job.setPrintService(defaultService);
} else {
throw new javax.print.PrintException("未找到默认打印机");
}
}
// 3. 配置打印内容(使用 PDFPrintable)
PDFPrintable printable = new PDFPrintable(document, Scaling.ACTUAL_SIZE); // 原始模式
// 4. 设置页面格式和打印属性
Book book = new Book();
PageFormat pageFormat = job.defaultPage();
// 设置打印方向(纵向PORTRAIT/横向LANDSCAPE)
pageFormat.setOrientation(PageFormat.LANDSCAPE); // 纵向
// 2. 自定义纸张大小(例如 A4:210×297 毫米,转换为 1/72 英寸:(210/25.4)*72 ≈ 595,(297/25.4)*72 ≈ 842)
//(A5纸张:148*210 (148/25.4)*72 = 419.5 (210/25.4)*72 = 595.3)
Paper paper = new Paper();
//paper.setSize(595, 842); // A4 宽度和高度(1/72 英寸)
paper.setSize(419, 595); // A5 宽度和高度(1/72 英寸)
paper.setImageableArea(0, 0, 419, 595); // 边距 40 点,可打印区域宽 515、高 762
pageFormat.setPaper(paper);
book.append(printable, pageFormat, document.getNumberOfPages());
job.setPageable(book);
// 6. 提交打印任务
job.print();
System.out.println("打印任务已提交至:" + job.getPrintService().getName());
} catch (PrinterException e) {
throw new RuntimeException(e);
}
}
public Result printToPdf(BarCodeParam barCodeParam, String pdfName){ public Result printToPdf(BarCodeParam barCodeParam, String pdfName){
String templatePath = RuoYiConfig.getProfile()+"/templates/barcode_zy.jrxml"; // 模板文件路径 String templatePath = RuoYiConfig.getProfile()+"/templates/barcode_zy.jrxml"; // 模板文件路径
@ -317,6 +195,105 @@ public class ReportUtil {
} }
} }
/**
* 将两个PDF文件的第一页横向(左右)合并到一个页面
* @param Base64input1 左侧PDF BASE64
* @param Base64input2 右侧PDF BASE64
* @param output 合并后的PDF文件路径
*/
public void mergePdfsHorizontally(String Base64input1, String Base64input2, String output) throws IOException {
//把base64数据生成pdf文件
String path1 = RuoYiConfig.getProfile() +"/config/static/printPDF/"+UUID.randomUUID().toString()+".pdf";
Base64.decodeToFile(Base64input1, new File(path1));
String path2 = RuoYiConfig.getProfile() +"/config/static/printPDF/"+UUID.randomUUID().toString()+".pdf";
Base64.decodeToFile(Base64input2, new File(path2));
try (PdfWriter writer = new PdfWriter(output);
PdfDocument pdfDoc = new PdfDocument(writer);
PdfDocument pdf1 = new PdfDocument(new PdfReader(path1));
PdfDocument pdf2 = new PdfDocument(new PdfReader(path2))) {
// 1. 获取两个PDF页面的真实尺寸(处理旋转和裁剪框)
Rectangle pageSize1 = pdf1.getFirstPage().getPageSize();
Rectangle pageSize2 = pdf2.getFirstPage().getPageSize();
// Rectangle rect1 = getActualPageRect(page1); // 左侧页面真实尺寸
// Rectangle rect2 = getActualPageRect(page2); // 右侧页面真实尺寸
// 2. 计算左右排列的合并页尺寸
float mergedWidth = pageSize1.getWidth() + pageSize2.getWidth();// 宽度=两页宽度之和
float mergedHeight = Math.max(pageSize1.getHeight(), pageSize2.getHeight()); // 高度=两页最大高度// 高度=两页最大高度
Rectangle mergedPageSize = new Rectangle(mergedWidth, mergedHeight);
// 3. 创建指定尺寸的合并页
PdfPage mergedPage = pdfDoc.addNewPage();
mergedPage.setMediaBox(mergedPageSize);
mergedPage.setCropBox(mergedPageSize);
// 4. 创建画布
try (Canvas canvas = new Canvas(mergedPage,pdfDoc.getDefaultPageSize())) {
// 5. 左侧页面定位:左下角对齐合并页左下角(x=0, y=0)
Image image1 = new Image(pdf1.getFirstPage().copyAsFormXObject(pdfDoc));
image1.setWidth(pageSize1.getWidth()) // 固定宽度为左侧页面真实宽度
.setHeight(pageSize1.getHeight()); // 固定高度为左侧页面真实高度
image1.setFixedPosition(0, 0); // 左侧页面左上角坐标
canvas.add(image1);
// 6. 右侧页面定位:左下角对齐左侧页面的右下角(x=左侧宽度, y=0)
Image image2 = new Image(pdf2.getFirstPage().copyAsFormXObject(pdfDoc));
image2.setWidth(pageSize2.getWidth()) // 固定宽度为右侧页面真实宽度
.setHeight(pageSize2.getHeight()); // 固定高度为右侧页面真实高度
image2.setFixedPosition(pageSize1.getWidth(), 0); // 右侧页面左上角坐标(x=左侧宽度)
canvas.add(image2);
}
}
FileUtils.deleteFile(path1);
FileUtils.deleteFile(path2);
}
/**
* 将PDF文件的指定页面旋转90度(顺时针)
* @param input 输入PDF路径
* @param output 输出PDF路径
* @param pageNumber 要旋转的页码(从1开始)
* @throws IOException 处理PDF时可能抛出的异常
*/
public void rotatePdf90Degrees(String input, String output, int pageNumber) throws IOException {
// 创建读取器和写入器
PdfReader reader = new PdfReader(input);
PdfWriter writer = new PdfWriter(output);
// 打开PDF文档
PdfDocument pdfDoc = new PdfDocument(reader, writer);
try {
// 检查页码是否有效
if (pageNumber < 1 || pageNumber > pdfDoc.getNumberOfPages()) {
throw new IllegalArgumentException("无效的页码: " + pageNumber);
}
// 获取指定页面
PdfPage page = pdfDoc.getPage(pageNumber);
// 获取当前旋转角度(0、90、180、270)
int currentRotation = page.getRotation();
// 计算新的旋转角度(顺时针旋转90度,取模360确保在有效范围内)
int newRotation = (currentRotation + 90) % 360;
// 设置新的旋转角度
page.setRotation(newRotation);
System.out.println("页面 " + pageNumber + " 已旋转90度,当前总旋转角度: " + newRotation + "度");
} finally {
// 关闭文档
pdfDoc.close();
reader.close();
writer.close();
}
}
/*** 获取服务器当前的数据库连接事务对象 /*** 获取服务器当前的数据库连接事务对象
* 通过@Qualifier获取实际当前连接事务对象,一般是DynamicDataSource * 通过@Qualifier获取实际当前连接事务对象,一般是DynamicDataSource
* 传递服务器获取连接(使用 Spring 工具类确保连接与事务同步) * 传递服务器获取连接(使用 Spring 工具类确保连接与事务同步)

View File

@ -90,4 +90,20 @@ public class SysLoginController {
List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId); List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
return AjaxResult.success(menuService.buildMenus(menus)); return AjaxResult.success(menuService.buildMenus(menus));
} }
/**
* 单点登录
* @param loginBody
* @return
*/
@PostMapping("/loginAnonymous")
public AjaxResult loginAnonymous(@RequestBody LoginBody loginBody) {
AjaxResult ajax = AjaxResult.success();
// 生成令牌
String token = loginService.loginAnonymous(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
loginBody.getUuid());
ajax.put(Constants.TOKEN, token);
return ajax;
}
} }

View File

@ -156,4 +156,43 @@ public class SysLoginService {
sysUser.setLoginDate(DateUtils.getNowDate()); sysUser.setLoginDate(DateUtils.getNowDate());
userService.updateUserProfile(sysUser); userService.updateUserProfile(sysUser);
} }
/**
* 登录验证
*
* @param username 用户名
* @param password 密码
* @param code 验证码
* @param uuid 唯一标识
* @return 结果
*/
public String loginAnonymous(String username, String password, String code, String uuid) {
// 验证码校验
validateCaptcha(username, code, uuid);
// 登录前置校验
//loginPreCheck(username, password);
// 用户验证
Authentication authentication = null;
try {
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
AuthenticationContextHolder.setContext(authenticationToken);
// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
authentication = authenticationManager.authenticate(authenticationToken);
} catch (Exception e) {
if (e instanceof BadCredentialsException) {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
throw new UserPasswordNotMatchException();
} else {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
throw new ServiceException(e.getMessage());
}
} finally {
AuthenticationContextHolder.clearContext();
}
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
LoginUser loginUser = (LoginUser) authentication.getPrincipal();
recordLoginInfo(loginUser.getUserId());
// 生成token
return tokenService.createToken(loginUser);
}
} }

View File

@ -2,10 +2,12 @@ package com.czlis.liswork.controller.dict;
import com.czlis.common.annotation.Anonymous; import com.czlis.common.annotation.Anonymous;
import com.czlis.common.annotation.Log;
import com.czlis.common.core.controller.BaseController; import com.czlis.common.core.controller.BaseController;
import com.czlis.common.core.domain.Result; import com.czlis.common.core.domain.Result;
import com.czlis.common.core.page.TableDataInfo; import com.czlis.common.core.page.TableDataInfo;
import com.czlis.common.core.domain.entity.lis.ComDict; import com.czlis.common.core.domain.entity.lis.ComDict;
import com.czlis.common.enums.BusinessType;
import com.czlis.common.utils.poi.ExcelUtil; import com.czlis.common.utils.poi.ExcelUtil;
import com.czlis.liswork.service.ComDictService; import com.czlis.liswork.service.ComDictService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
@ -55,6 +57,7 @@ public class DictController extends BaseController {
@ApiOperation("新增字典") @ApiOperation("新增字典")
@PostMapping("/add") @PostMapping("/add")
@Log(title = "常见字典" ,businessType = BusinessType.INSERT)
public Result add(@RequestBody ComDict comDict) { public Result add(@RequestBody ComDict comDict) {
log.info("调用新增字典{}", comDict); log.info("调用新增字典{}", comDict);
return comDictService.insertComDict(comDict); return comDictService.insertComDict(comDict);
@ -63,6 +66,7 @@ public class DictController extends BaseController {
@ApiOperation("删除字典") @ApiOperation("删除字典")
@DeleteMapping("/del") @DeleteMapping("/del")
@Log(title = "常见字典" ,businessType = BusinessType.DELETE)
public Result del(@RequestBody ComDict comDict) { public Result del(@RequestBody ComDict comDict) {
log.info("调用删除字典接口{}", comDict); log.info("调用删除字典接口{}", comDict);
return comDictService.delComDict(comDict); return comDictService.delComDict(comDict);
@ -70,6 +74,7 @@ public class DictController extends BaseController {
@ApiOperation("修改字典") @ApiOperation("修改字典")
@PostMapping("/update") @PostMapping("/update")
@Log(title = "常见字典" ,businessType = BusinessType.UPDATE)
public Result update(@RequestBody ComDict comDict) { public Result update(@RequestBody ComDict comDict) {
log.info("调用修改字典接口{}", comDict); log.info("调用修改字典接口{}", comDict);
return comDictService.updateComDict(comDict); return comDictService.updateComDict(comDict);

View File

@ -1,9 +1,11 @@
package com.czlis.liswork.controller.dict; package com.czlis.liswork.controller.dict;
import com.czlis.common.annotation.Log;
import com.czlis.common.core.controller.BaseController; import com.czlis.common.core.controller.BaseController;
import com.czlis.common.core.domain.Result; import com.czlis.common.core.domain.Result;
import com.czlis.common.core.page.TableDataInfo; import com.czlis.common.core.page.TableDataInfo;
import com.czlis.common.core.domain.entity.lis.LabInstr; import com.czlis.common.core.domain.entity.lis.LabInstr;
import com.czlis.common.enums.BusinessType;
import com.czlis.liswork.service.InstrService; import com.czlis.liswork.service.InstrService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
@ -39,18 +41,21 @@ public class InstrController extends BaseController {
} }
@ApiOperation("新增数据") @ApiOperation("新增数据")
@PostMapping("/add") @PostMapping("/add")
@Log(title = "仪器维护" ,businessType = BusinessType.INSERT)
public Result add(LabInstr labInstr){ public Result add(LabInstr labInstr){
return instrService.add(labInstr); return instrService.add(labInstr);
} }
@ApiOperation("修改数据") @ApiOperation("修改数据")
@PostMapping("/update") @PostMapping("/update")
@Log(title = "仪器维护" ,businessType = BusinessType.UPDATE)
public Result update(LabInstr labInstr){ public Result update(LabInstr labInstr){
return instrService.update(labInstr); return instrService.update(labInstr);
} }
@ApiOperation("删除数据") @ApiOperation("删除数据")
@DeleteMapping("/del") @DeleteMapping("/del")
@Log(title = "仪器维护" ,businessType = BusinessType.DELETE)
public Result delete(String yq){ public Result delete(String yq){
return instrService.delete(yq); return instrService.delete(yq);
} }

View File

@ -1,9 +1,11 @@
package com.czlis.liswork.controller.dict; package com.czlis.liswork.controller.dict;
import com.czlis.common.annotation.Log;
import com.czlis.common.core.controller.BaseController; import com.czlis.common.core.controller.BaseController;
import com.czlis.common.core.domain.Result; import com.czlis.common.core.domain.Result;
import com.czlis.common.core.page.TableDataInfo; import com.czlis.common.core.page.TableDataInfo;
import com.czlis.common.core.domain.entity.lis.XmBase; import com.czlis.common.core.domain.entity.lis.XmBase;
import com.czlis.common.enums.BusinessType;
import com.czlis.liswork.service.XmBaseService; import com.czlis.liswork.service.XmBaseService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
@ -35,18 +37,21 @@ public class XmBaseController extends BaseController {
@ApiOperation("新增报告项目") @ApiOperation("新增报告项目")
@PostMapping("/add") @PostMapping("/add")
@Log(title = "报告项目" ,businessType = BusinessType.INSERT)
public Result add(@RequestBody XmBase xmBase){ public Result add(@RequestBody XmBase xmBase){
return xmBaseService.add(xmBase); return xmBaseService.add(xmBase);
} }
@ApiOperation("删除报告项目") @ApiOperation("删除报告项目")
@DeleteMapping("/del") @DeleteMapping("/del")
@Log(title = "报告项目" ,businessType = BusinessType.DELETE)
public Result delete(@RequestBody String xmdh){ public Result delete(@RequestBody String xmdh){
return xmBaseService.delete(xmdh); return xmBaseService.delete(xmdh);
} }
@ApiOperation("修改报告项目") @ApiOperation("修改报告项目")
@PostMapping("/update") @PostMapping("/update")
@Log(title = "报告项目" ,businessType = BusinessType.UPDATE)
public Result update(@RequestBody @NotBlank(message = "参数不能为空!") XmBase xmBase){ public Result update(@RequestBody @NotBlank(message = "参数不能为空!") XmBase xmBase){
return xmBaseService.update(xmBase); return xmBaseService.update(xmBase);
} }

View File

@ -1,9 +1,11 @@
package com.czlis.liswork.controller.dict; package com.czlis.liswork.controller.dict;
import com.czlis.common.annotation.Log;
import com.czlis.common.core.controller.BaseController; import com.czlis.common.core.controller.BaseController;
import com.czlis.common.core.domain.Result; import com.czlis.common.core.domain.Result;
import com.czlis.common.core.page.TableDataInfo; import com.czlis.common.core.page.TableDataInfo;
import com.czlis.common.core.domain.entity.lis.XmReqitemVsReportitem; import com.czlis.common.core.domain.entity.lis.XmReqitemVsReportitem;
import com.czlis.common.enums.BusinessType;
import com.czlis.liswork.service.XmReqitemVsReportitemService; import com.czlis.liswork.service.XmReqitemVsReportitemService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
@ -36,18 +38,21 @@ public class XmReqitemVsReportitemController extends BaseController {
@ApiOperation("新增收费项目报告项目对照") @ApiOperation("新增收费项目报告项目对照")
@PostMapping("/add") @PostMapping("/add")
@Log(title = "收费项目报告项目" ,businessType = BusinessType.INSERT)
public Result add(XmReqitemVsReportitem xmReqitemVsReportitem){ public Result add(XmReqitemVsReportitem xmReqitemVsReportitem){
return xmReqitemVsReportitemService.add(xmReqitemVsReportitem); return xmReqitemVsReportitemService.add(xmReqitemVsReportitem);
} }
@ApiOperation("删除收费项目报告项目对照") @ApiOperation("删除收费项目报告项目对照")
@DeleteMapping("/del") @DeleteMapping("/del")
@Log(title = "收费项目报告项目" ,businessType = BusinessType.DELETE)
public Result delete(String sqxmdh,String yq,String xmdh,String tdh){ public Result delete(String sqxmdh,String yq,String xmdh,String tdh){
return xmReqitemVsReportitemService.delete(sqxmdh,yq,xmdh,tdh); return xmReqitemVsReportitemService.delete(sqxmdh,yq,xmdh,tdh);
} }
@ApiOperation("修改收费项目报告项目对照") @ApiOperation("修改收费项目报告项目对照")
@PostMapping("/update") @PostMapping("/update")
@Log(title = "收费项目报告项目" ,businessType = BusinessType.UPDATE)
public Result update(XmReqitemVsReportitem xmReqitemVsReportitem){ public Result update(XmReqitemVsReportitem xmReqitemVsReportitem){
return xmReqitemVsReportitemService.update(xmReqitemVsReportitem); return xmReqitemVsReportitemService.update(xmReqitemVsReportitem);
} }

18
pom.xml
View File

@ -43,8 +43,7 @@
<jasperreports.version>6.8.0</jasperreports.version> <jasperreports.version>6.8.0</jasperreports.version>
<itext.version>2.1.7</itext.version> <itext.version>2.1.7</itext.version>
<barbecue.version>1.5-beta1</barbecue.version> <barbecue.version>1.5-beta1</barbecue.version>
<pdfbox.version>2.0.29</pdfbox.version> <itextpdf.version>7.2.5</itextpdf.version>
<pdfboxTools.version>2.0.29</pdfboxTools.version>
<!-- override dependency version --> <!-- override dependency version -->
<tomcat.version>9.0.98</tomcat.version> <tomcat.version>9.0.98</tomcat.version>
@ -331,17 +330,18 @@
<artifactId>batik-all</artifactId> <artifactId>batik-all</artifactId>
<version>${batik.version}</version> <version>${batik.version}</version>
</dependency> </dependency>
<!-- iText 7 核心库 -->
<dependency> <dependency>
<groupId>org.apache.pdfbox</groupId> <groupId>com.itextpdf</groupId>
<artifactId>pdfbox</artifactId> <artifactId>kernel</artifactId>
<version>${pdfbox.version}</version> <version>${itextpdf.version}</version>
</dependency> </dependency>
<!-- iText 7 布局库 -->
<dependency> <dependency>
<groupId>org.apache.pdfbox</groupId> <groupId>com.itextpdf</groupId>
<artifactId>pdfbox-tools</artifactId> <artifactId>layout</artifactId>
<version>${pdfboxTools.version}</version> <version>${itextpdf.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -1,6 +1,7 @@
package com.czlis.zybgcx.service.impl; package com.czlis.zybgcx.service.impl;
import cn.hutool.core.codec.Base64; import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil; import cn.hutool.core.io.IoUtil;
@ -8,6 +9,7 @@ import cn.hutool.core.util.StrUtil;
import com.czlis.common.config.RuoYiConfig; import com.czlis.common.config.RuoYiConfig;
import com.czlis.common.core.domain.Result; import com.czlis.common.core.domain.Result;
import com.czlis.common.core.domain.entity.lis.LabReqreportPdffile; import com.czlis.common.core.domain.entity.lis.LabReqreportPdffile;
import com.czlis.common.utils.file.FileUtils;
import com.czlis.common.utils.ip.IpUtils; import com.czlis.common.utils.ip.IpUtils;
import com.czlis.common.utils.uuid.UUID; import com.czlis.common.utils.uuid.UUID;
import com.czlis.interfaceCommon.utils.CommonUtil; import com.czlis.interfaceCommon.utils.CommonUtil;
@ -29,10 +31,7 @@ import javax.print.PrintException;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.*;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Service @Service
@ -43,6 +42,8 @@ public class ZybgcxServcieImpl implements ZybgcxService {
private ZybgcxMapper zybgcxMapper; private ZybgcxMapper zybgcxMapper;
@Autowired @Autowired
private CommonUtil commonUtil; private CommonUtil commonUtil;
@Autowired
ReportUtil reportUtil;
/** /**
* 获取报告信息 * 获取报告信息
@ -72,10 +73,11 @@ public class ZybgcxServcieImpl implements ZybgcxService {
*/ */
@Override @Override
public Result printReport(String[] bgdh) { public Result printReport(String[] bgdh) {
List<String> bgdhBase64List = new ArrayList<>(); List<Map<String,Object>> bgdhBase64List = new ArrayList<>();
List<String> mergeBgdhList = new ArrayList<>();
for (String string : bgdh) { for (String string : bgdh) {
String[] stringParam = StrUtil.splitToArray(string, "_"); String[] stringParam = StrUtil.splitToArray(string, "_");
if(stringParam.length != 3) return new Result("-1","传入的报告单号不对!"); if(stringParam.length != 3) return new Result("-1","传入的报告单号不对!"+ Arrays.toString(stringParam));
String jyrqStr = stringParam[0]; String jyrqStr = stringParam[0];
String yq = stringParam[1]; String yq = stringParam[1];
String ybh = stringParam[2]; String ybh = stringParam[2];
@ -83,22 +85,66 @@ public class ZybgcxServcieImpl implements ZybgcxService {
if(labReqreportPdffileOne == null) continue; if(labReqreportPdffileOne == null) continue;
String base64PDF = labReqreportPdffileOne.getBASE64PDF(); String base64PDF = labReqreportPdffileOne.getBASE64PDF();
if(base64PDF == null || base64PDF.equals("")) continue; if(base64PDF == null || base64PDF.equals("")) continue;
bgdhBase64List.add(base64PDF); Map<String,Object> map = new HashMap<>();
map.put("data", base64PDF);
//判断使用的纸张类型
String pageType = reportUtil.getReportPaperSize(DateUtil.parse(jyrqStr, "yyyyMMdd"), yq, ybh);
map.put("pageType", pageType);
bgdhBase64List.add(map);
} }
//过滤A4的报告单
List<Map<String, Object>> collectA4 = bgdhBase64List.stream().filter(bgdhBase64 -> bgdhBase64.get("pageType").equals("A4")).collect(Collectors.toList());
for (Map<String, Object> stringObjectMap : collectA4) {
mergeBgdhList.add(stringObjectMap.get("data").toString());
}
//过滤A5格式报告单
List<Map<String, Object>> collectA5 = bgdhBase64List.stream().filter(bgdhBase64 -> bgdhBase64.get("pageType").equals("A5")).collect(Collectors.toList());
//合并A5格式的pdf为A4格式
for (int i = 0; i < collectA5.size(); i++) {
if(i+1 >= collectA5.size()){
//代表到了最后一个单数
mergeBgdhList.add(collectA5.get(i).get("data").toString());
break;
}
String path = RuoYiConfig.getProfile() +"/config/static/printPDF/"+UUID.randomUUID().toString()+".pdf";
String path1 = RuoYiConfig.getProfile() +"/config/static/printPDF/"+UUID.randomUUID().toString()+".pdf";
try {
reportUtil.mergePdfsHorizontally(collectA5.get(i).get("data").toString(),collectA5.get(i+1).get("data").toString(),path);
//旋转90度
reportUtil.rotatePdf90Degrees(path,path1,1);
File file = new File(path1);
mergeBgdhList.add(Base64.encode(file));
//删除文件
FileUtils.deleteFile(path);
FileUtils.deleteFile(path1);
} catch (IOException e) {
e.printStackTrace();
log.error("合并报告单出错:",e);
return new Result("-1","合并报告单出错"+e.getMessage());
}
i=i+1;
}
String encode = "";
try {
//合并成一个pdf
String pdfName = UUID.randomUUID().toString(); String pdfName = UUID.randomUUID().toString();
String path = RuoYiConfig.getProfile() +"/config/static/printPDF/"+pdfName+".pdf"; String path = RuoYiConfig.getProfile() +"/config/static/printPDF/"+pdfName+".pdf";
//合并pdf LisUtil.mergeToFile(mergeBgdhList,path);
try { //String httpPath = reportUtil.getPrintURL(pdfName);
LisUtil.mergeToFile(bgdhBase64List,path); //转成base64字符串
File file = new File(path);
encode = Base64.encode(file);
//删除pdf文件
FileUtils.deleteFile(path);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
log.error("合并pdf:{}报告失败:{}",bgdh,e); log.error("合并pdf:{}报告失败:{}",bgdh,e);
return new Result("-1",e.getMessage()); return new Result("-1",e.getMessage());
} }
//String httpPath = reportUtil.getPrintURL(pdfName);
//转成base64字符串
File file = new File(path);
String encode = Base64.encode(file);
return new Result("0","打印成功!",encode); return new Result("0","打印成功!",encode);
} }