From 086c474de53bbe39df61ac71ae3905a2e6eb32d5 Mon Sep 17 00:00:00 2001 From: "han\\hanst" Date: Fri, 15 Aug 2025 16:33:07 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=BC=E5=87=BAPDF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 4 + .../controller/LabelSettingController.java | 61 +++++++++ .../service/Impl/PdfExportServiceImpl.java | 117 ++++++++++++++++++ .../base/service/PdfExportService.java | 22 ++++ 4 files changed, 204 insertions(+) create mode 100644 src/main/java/com/gaotao/modules/base/service/Impl/PdfExportServiceImpl.java create mode 100644 src/main/java/com/gaotao/modules/base/service/PdfExportService.java diff --git a/build.gradle b/build.gradle index da0c080..aad341f 100644 --- a/build.gradle +++ b/build.gradle @@ -105,6 +105,10 @@ dependencies { // easyexcel implementation 'com.alibaba:easyexcel:3.1.2' + // PDF生成依赖 + implementation 'com.itextpdf:itext7-core:7.2.5' + implementation 'com.itextpdf:html2pdf:4.0.5' + } test { diff --git a/src/main/java/com/gaotao/modules/base/controller/LabelSettingController.java b/src/main/java/com/gaotao/modules/base/controller/LabelSettingController.java index fc68d12..2ec4764 100644 --- a/src/main/java/com/gaotao/modules/base/controller/LabelSettingController.java +++ b/src/main/java/com/gaotao/modules/base/controller/LabelSettingController.java @@ -9,7 +9,9 @@ import com.gaotao.modules.base.service.ReportLabelListService; import com.gaotao.modules.base.service.ReportPaperListService; import com.gaotao.modules.base.dto.*; import com.gaotao.modules.base.vo.PaperUsageCheckResponse; +import com.gaotao.modules.base.service.PdfExportService; import com.gaotao.modules.sys.controller.AbstractController; +import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -28,6 +30,8 @@ public class LabelSettingController extends AbstractController { private ReportLabelListService reportLabelListService; @Autowired private ReportPaperListService reportPaperListService; + @Autowired + private PdfExportService pdfExportService; /** * @description: 查询打印标签的定义参数 @@ -860,4 +864,61 @@ public class LabelSettingController extends AbstractController { } } + /** + * @description: 导出预览图为PDF + * @author Kiro + * @date 2025/1/24 + * @version 1.0 + */ + @PostMapping("exportPreviewToPdf") + public void exportPreviewToPdf(@RequestBody Map params, + HttpServletResponse response) { + try { + log.info("收到PDF导出请求: {}", params); + + String reportId = (String) params.get("reportId"); + String imageData = (String) params.get("imageData"); + + if (reportId == null || reportId.trim().isEmpty()) { + response.setStatus(400); + response.getWriter().write("标签ID不能为空"); + return; + } + + if (imageData == null || imageData.trim().isEmpty()) { + response.setStatus(400); + response.getWriter().write("预览图数据不能为空"); + return; + } + + log.info("开始生成PDF: reportId={}", reportId); + + // 生成PDF + java.io.ByteArrayOutputStream pdfStream = pdfExportService.exportPreviewToPdf(imageData, reportId); + + // 设置响应头 + response.setContentType("application/pdf"); + response.setHeader("Content-Disposition", + "attachment; filename=\"label_preview_" + reportId + "_" + + java.time.LocalDateTime.now().format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss")) + + ".pdf\""); + response.setContentLength(pdfStream.size()); + + // 输出PDF + response.getOutputStream().write(pdfStream.toByteArray()); + response.getOutputStream().flush(); + + log.info("PDF导出成功: reportId={}, size={}KB", reportId, pdfStream.size() / 1024); + + } catch (Exception e) { + log.error("PDF导出失败: {}", e.getMessage(), e); + try { + response.setStatus(500); + response.getWriter().write("PDF导出失败: " + e.getMessage()); + } catch (Exception ex) { + log.error("写入错误响应失败", ex); + } + } + } + } diff --git a/src/main/java/com/gaotao/modules/base/service/Impl/PdfExportServiceImpl.java b/src/main/java/com/gaotao/modules/base/service/Impl/PdfExportServiceImpl.java new file mode 100644 index 0000000..f10a6e3 --- /dev/null +++ b/src/main/java/com/gaotao/modules/base/service/Impl/PdfExportServiceImpl.java @@ -0,0 +1,117 @@ +package com.gaotao.modules.base.service.Impl; + +import com.gaotao.modules.base.service.PdfExportService; +import com.itextpdf.io.image.ImageData; +import com.itextpdf.io.image.ImageDataFactory; +import com.itextpdf.kernel.colors.ColorConstants; +import com.itextpdf.kernel.colors.DeviceRgb; +import com.itextpdf.kernel.geom.PageSize; +import com.itextpdf.kernel.pdf.PdfDocument; +import com.itextpdf.kernel.pdf.PdfWriter; +import com.itextpdf.layout.Document; +import com.itextpdf.layout.borders.SolidBorder; +import com.itextpdf.layout.element.Image; +import com.itextpdf.layout.element.Paragraph; +import com.itextpdf.layout.properties.HorizontalAlignment; +import com.itextpdf.layout.properties.TextAlignment; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.net.URL; +import java.util.Base64; + +/** + * PDF导出服务实现 - Java 21兼容版本 + * @author Kiro + * @date 2025/1/24 + */ +@Slf4j +@Service +public class PdfExportServiceImpl implements PdfExportService { + + @Override + public ByteArrayOutputStream exportPreviewToPdf(String imageUrl, String reportId) throws Exception { + log.info("开始导出预览图为PDF: reportId={}", reportId); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PdfWriter writer = new PdfWriter(baos); + PdfDocument pdfDoc = new PdfDocument(writer); + Document document = new Document(pdfDoc, PageSize.A4); + + try { + // 处理图片 - 直接添加预览图,不需要标题和时间戳 + ImageData imageData = getImageData(imageUrl); + if (imageData != null) { + Image image = new Image(imageData); + + // 调整图片大小以适应页面,留更多空间给图片 + float pageWidth = PageSize.A4.getWidth() - 72; + float pageHeight = PageSize.A4.getHeight() - 72; + + if (image.getImageWidth() > pageWidth || image.getImageHeight() > pageHeight) { + image.scaleToFit(pageWidth, pageHeight); + } + + // 直接添加带边框的图片,无需容器 + image.setBorder(new SolidBorder(new DeviceRgb(221, 221, 221), 1)); + image.setHorizontalAlignment(HorizontalAlignment.CENTER); + document.add(image); + } else { + // 如果无法加载图片,显示简单的错误信息 + Paragraph errorParagraph = new Paragraph("无法加载预览图片"); + errorParagraph.setTextAlignment(TextAlignment.CENTER); + errorParagraph.setFontSize(12); + document.add(errorParagraph); + } + + log.info("PDF导出成功: reportId={}", reportId); + + } finally { + document.close(); + } + + return baos; + } + + /** + * 获取图片数据 + */ + private ImageData getImageData(String imageSource) { + try { + if (imageSource == null || imageSource.trim().isEmpty()) { + return null; + } + + // 检查是否是Base64数据 + if (imageSource.startsWith("data:image/")) { + String base64Data = imageSource.substring(imageSource.indexOf(",") + 1); + byte[] imageBytes = Base64.getDecoder().decode(base64Data); + return ImageDataFactory.create(imageBytes); + } + + // 检查是否是网络URL + if (imageSource.startsWith("http://") || imageSource.startsWith("https://")) { + return ImageDataFactory.create(new URL(imageSource)); + } + + // 尝试作为本地文件路径处理 + return ImageDataFactory.create(imageSource); + + } catch (Exception e) { + log.error("获取图片数据失败: {}", e.getMessage()); + return null; + } + } + + + + /** + * 通过Labelary API生成预览图 + */ + private String generatePreviewImage(String zplCode, String paperSize, Integer dpi) throws IOException { + log.warn("ZPL预览图生成功能需要实现Labelary API调用"); + return null; + } +} diff --git a/src/main/java/com/gaotao/modules/base/service/PdfExportService.java b/src/main/java/com/gaotao/modules/base/service/PdfExportService.java new file mode 100644 index 0000000..377de6b --- /dev/null +++ b/src/main/java/com/gaotao/modules/base/service/PdfExportService.java @@ -0,0 +1,22 @@ +package com.gaotao.modules.base.service; + +import org.springframework.stereotype.Service; +import java.io.ByteArrayOutputStream; + +/** + * PDF导出服务接口 + * @author Kiro + * @date 2025/1/24 + */ +@Service +public interface PdfExportService { + + /** + * 将预览图片导出为PDF + * @param imageUrl 预览图片URL或Base64数据 + * @param reportId 标签ID + * @return PDF字节数组 + */ + ByteArrayOutputStream exportPreviewToPdf(String imageUrl, String reportId) throws Exception; + +}