Java实现图片保存到pdf的某个位置

Java实现图片保存到pdf的某个位置

1、依赖--maven
xml 复制代码
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.13</version>
        </dependency>
2、上代码
java 复制代码
package com.hxlinks.hxiot.controller;


import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.awt.geom.Point2D;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Base64;

@Controller
public class PdfApiController {

    @PostMapping("/api/save-image-to-pdf")
    public ResponseEntity<String> saveImageToPdf(@RequestBody JsonNode jsonNode) {
        try {
            // 解析前端传来的JSON数据
            int pageNumber = jsonNode.get("pageNumber").asInt();
            Point2D.Float position = new Point2D.Float(jsonNode.get("imagePosition").get("x").floatValue(), jsonNode.get("imagePosition").get("y").floatValue());
            String base64Image = jsonNode.get("base64Image").toString();

            // 将Base64编码的图片转换为字节数组
            byte[] imageBytes = Base64.getDecoder().decode(base64Image.split(",")[1]);

            // 假设有一个默认的PDF文件路径
            File originalPdf = new File("D:\\templateFilePath\\测试.pdf");
            File tempPdf = File.createTempFile("temp", ".pdf");

            // 使用iText处理PDF
            insertImageIntoPdf(originalPdf, tempPdf, pageNumber, position, imageBytes);

            // 下载处理后的PDF到D盘
            downloadPdf(tempPdf, "modified_pdf_page_" + pageNumber + ".pdf");

            return ResponseEntity.ok("图片已成功添加到PDF并保存到D盘。");
        } catch (IOException | DocumentException e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("处理PDF时出错。");
        }
    }

    private void insertImageIntoPdf(File originalPdf, File tempPdf, int pageNumber, Point2D.Float position, byte[] imageBytes) throws IOException, DocumentException {
        PdfReader reader = new PdfReader(new FileInputStream(originalPdf));
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(tempPdf));
        PdfContentByte canvas = stamper.getOverContent(pageNumber);

        Image img = Image.getInstance(imageBytes);
        img.setAbsolutePosition(position.x, position.y);
        img.scaleToFit(100, 100); // 示例:调整图片大小,根据需要调整
        canvas.addImage(img);

        stamper.close();
        reader.close();
    }

    private void downloadPdf(File tempPdf, String fileName) throws IOException {
        Path sourcePath = tempPdf.toPath();
        Path targetDir = Paths.get("D:/");
        Path targetPath = targetDir.resolve(System.currentTimeMillis() + ".pdf");

        // 检查目标文件是否已存在,根据需求决定是否覆盖或提示错误
        if (Files.exists(targetPath)) {
            // 这里可以根据实际情况选择抛出异常、覆盖文件或修改文件名
            throw new IOException("目标文件已存在:" + targetPath);
            // 或者
            // Files.delete(targetPath); // 如果决定覆盖,则先删除原有文件
        }

        // 确保目标目录存在
        Files.createDirectories(targetDir);

        // 执行移动操作
        Files.move(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING); // REPLACE_EXISTING 用于允许覆盖已存在的文件
    }

}
3、jsonNode参数,根据需要调整
json 复制代码
{
    "pageNumber":2,//pdf页码数
    "base64Image":"data:image/png;base64,i...................",//base64
    "imagePosition":{//在pdf中的坐标,左下角为(0,0)
        "x":100,
        "y":0
    },
    "imageSize":{//在pdf中的图片大小
        "width":100,
        "height":100
    }
}
相关推荐
Dicky-_-zhang2 小时前
系统容量规划与压测实战:从1万到100万QPS的科学扩容
java·jvm
Highcharts.js7 小时前
倒置百分比堆叠面积图表示列详解|Highcharts大气成分图表代码
开发语言·信息可视化·highcharts·图表开发·面积图·图表示例·推叠图
csdn_aspnet7 小时前
C语言 Lomuto分区算法(Lomuto Partition Algorithm)
c语言·开发语言·算法
Dicky-_-zhang7 小时前
消息队列Kafka/RocketMQ选型与高可用架构:从单体到100万TPS的演进
java·jvm
晨曦中的暮雨7 小时前
4.15腾讯 CSIG云服务产线 一面
java·开发语言
存在morning7 小时前
【GO语言开发实践】二 GO 并发快速上手
大数据·开发语言·golang
fake_ss1987 小时前
AI时代学习全栈项目开发的新范式
java·人工智能·学习·架构·个人开发·学习方法
asdzx677 小时前
使用 Python 为 PDF 添加页码 (详细教程)
python·pdf·页码
茉莉玫瑰花茶8 小时前
工作流的常见模式 [ 1 ]
java·服务器·前端
未若君雅裁8 小时前
Spring AOP、日志切面与声明式事务原理
java·后端·spring