package com.ruoyi.cwgl.utils; import com.itextpdf.text.*; import com.itextpdf.text.pdf.*; import com.ruoyi.common.config.RuoYiConfig; import com.ruoyi.cwgl.domain.vo.DispatchOrderAttachmentVo; import java.io.FileOutputStream; import java.net.URL; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.UUID; public class MultiPagePdfWithImageUtils { public static String createPdf(List dispatchOrderAttachmentVos, String no) throws Exception { String fileName = no+ "_凭证_"+ UUID.randomUUID() +".pdf"; String path = RuoYiConfig.getDownloadPath() + fileName; Document document = new Document(PageSize.A4, 36, 36, 36, 36); PdfWriter writer = PdfWriter.getInstance(document, Files.newOutputStream(Paths.get(path))); document.open(); BaseFont baseFont = BaseFont.createFont("simhei.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED); Font font = new Font(baseFont, 11, Font.NORMAL); int totalPages = dispatchOrderAttachmentVos.size(); for (int i = 0; i < totalPages; i++) { if (i > 0) document.newPage(); DispatchOrderAttachmentVo dispatchOrderAttachmentVo = dispatchOrderAttachmentVos.get(i); String currency = Optional.ofNullable(dispatchOrderAttachmentVo.getCurrency()).orElse("人民币"); String currentStr; if ("人民币".equals(currency)){ currentStr = "总金额:港币 0;人民币:"+dispatchOrderAttachmentVo.getAccount()+";"; }else{ currentStr = "总金额:港币 "+dispatchOrderAttachmentVo.getAccount()+";人民币:0;"; } PdfPTable wrapperTable = new PdfPTable(1); wrapperTable.setWidthPercentage(100); wrapperTable.setKeepTogether(true); // ▶ 页眉表格 PdfPTable headerTable = new PdfPTable(2); headerTable.setWidthPercentage(100); headerTable.setWidths(new int[]{3, 2}); headerTable.addCell(createCell("调度单号:"+no, font)); headerTable.addCell(createCell(currentStr, font)); PdfPCell headerCell = new PdfPCell(headerTable); headerCell.setBorder(Rectangle.BOX); wrapperTable.addCell(headerCell); // ▶ 图片 Image image = Image.getInstance(new URL(dispatchOrderAttachmentVo.getImageUrl())); // 限制图片最大尺寸 float maxImgWidth = 500f; float maxImgHeight = 700f; image.scaleToFit(maxImgWidth, maxImgHeight); image.setAlignment(Image.ALIGN_CENTER); // 创建图片单元格并设置固定高度(确保整体表格不分页) PdfPCell imageCell = new PdfPCell(); imageCell.setPadding(10); imageCell.setBorder(Rectangle.BOX); imageCell.setFixedHeight(maxImgHeight + 20); // 加一点 padding 空间 imageCell.setHorizontalAlignment(Element.ALIGN_CENTER); imageCell.setVerticalAlignment(Element.ALIGN_MIDDLE); imageCell.addElement(image); wrapperTable.addCell(imageCell); // ▶ 页脚表格 PdfPTable footerTable = new PdfPTable(4); footerTable.setWidthPercentage(100); footerTable.setWidths(new int[]{3, 2, 2, 3}); footerTable.addCell(createCell("费用类:"+dispatchOrderAttachmentVo.getFeeItem(), font)); footerTable.addCell(createCell("金额:"+dispatchOrderAttachmentVo.getAccount(), font)); footerTable.addCell(createCell("币制:"+dispatchOrderAttachmentVo.getCurrency(), font)); footerTable.addCell(createCell("第 " + (i + 1) + " 页 / 共 " + totalPages + " 页", font)); PdfPCell footerCell = new PdfPCell(footerTable); footerCell.setBorder(Rectangle.BOX); wrapperTable.addCell(footerCell); // 添加总表格 document.add(wrapperTable); } document.close(); writer.close(); System.out.println("PDF 生成成功!"); return path; } public static void main(String[] args) throws Exception { Document document = new Document(PageSize.A4, 36, 36, 36, 36); PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("bordered_receipt.pdf")); document.open(); BaseFont baseFont = BaseFont.createFont("simhei.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED); Font font = new Font(baseFont, 11, Font.NORMAL); List imageUrls = Arrays.asList( "https://xiongbenda-shengzheng.oss-cn-shenzhen.aliyuncs.com/cz/ImageViewServlet%20%281%29.gif", "https://xiongbenda-shengzheng.oss-cn-shenzhen.aliyuncs.com/cz/ImageViewServlet.gif" ); int totalPages = imageUrls.size(); for (int i = 0; i < totalPages; i++) { if (i > 0) document.newPage(); // ▶ 构造一个总表格(3行,1列),包住所有内容,控制边框与分页 PdfPTable wrapperTable = new PdfPTable(1); wrapperTable.setWidthPercentage(100); wrapperTable.setKeepTogether(true); // ▶ 页眉表格 PdfPTable headerTable = new PdfPTable(2); headerTable.setWidthPercentage(100); headerTable.setWidths(new int[]{3, 2}); headerTable.addCell(createCell("调度单号:LD2507260028", font)); headerTable.addCell(createCell("总金额:港币 280;人民币:0", font)); PdfPCell headerCell = new PdfPCell(headerTable); headerCell.setBorder(Rectangle.BOX); wrapperTable.addCell(headerCell); // ▶ 图片 Image image = Image.getInstance(new URL(imageUrls.get(i))); // 限制图片最大尺寸 float maxImgWidth = 500f; float maxImgHeight = 700f; image.scaleToFit(maxImgWidth, maxImgHeight); image.setAlignment(Image.ALIGN_CENTER); // 创建图片单元格并设置固定高度(确保整体表格不分页) PdfPCell imageCell = new PdfPCell(); imageCell.setPadding(10); imageCell.setBorder(Rectangle.BOX); imageCell.setFixedHeight(maxImgHeight + 20); // 加一点 padding 空间 imageCell.setHorizontalAlignment(Element.ALIGN_CENTER); imageCell.setVerticalAlignment(Element.ALIGN_MIDDLE); imageCell.addElement(image); wrapperTable.addCell(imageCell); // ▶ 页脚表格 PdfPTable footerTable = new PdfPTable(4); footerTable.setWidthPercentage(100); footerTable.setWidths(new int[]{3, 2, 2, 3}); footerTable.addCell(createCell("费用类:登记费 HKD", font)); footerTable.addCell(createCell("金额:250.00", font)); footerTable.addCell(createCell("币制:港币", font)); footerTable.addCell(createCell("第 " + (i + 1) + " 页 / 共 " + totalPages + " 页", font)); PdfPCell footerCell = new PdfPCell(footerTable); footerCell.setBorder(Rectangle.BOX); wrapperTable.addCell(footerCell); // 添加总表格 document.add(wrapperTable); } document.close(); writer.close(); System.out.println("PDF 生成成功!"); } // 默认左对齐、含内边距、含边框 private static PdfPCell createCell(String text, Font font) { PdfPCell cell = new PdfPCell(new Phrase(text, font)); cell.setPadding(6); cell.setHorizontalAlignment(Element.ALIGN_LEFT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); return cell; } }