JAVA 有关PDF文件和图片文件合并并生产一个PDF

情景:

1.文件列表包含多个图片和PDF时需要对文件进行合并

2.合并时保持文件顺序

开淦:

一、导入POM

XML 复制代码
  <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>2.0.24</version>
        </dependency>
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>fontbox</artifactId>
            <version>2.0.24</version>
        </dependency>
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>xmpbox</artifactId>
            <version>2.0.24</version>
        </dependency>
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox-tools</artifactId>
            <version>2.0.24</version>
        </dependency>

二、Java 代码

java 复制代码
package com.aisino.datadocking;

import org.apache.pdfbox.io.MemoryUsageSetting;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * @description: ImgPDF
 * @author: Stiven
 * @create: 2023-12-20 16:57
 **/
public class MergeImgPDFUntil {
    public static void main(String[] args) throws Exception {
        String[] urls={"http://+IP+wKgFOGV7uYuAMWldAAMsi8rvZ3Y062.jpg"
                ,"http:+IP+/group1/M01/03/76/wKgFOGWKOA6AZ5i-eecoQ405.pdf"
                ,"http://+IP+/group1/M01/02/FF/wKgFOGV7ubyAb6q3AATSEcwOiu8024.jpg"
           };
        //文件临时存储位置(必须) 同时需要定时清理
        String target = "/Users/stiven/IdeaProjects/tmp/";
        List<String> fileList = new ArrayList<>();
        for(String url:urls){
            fileList.add(downloadFile(url,target));
        }
        // 执行合并
        mergePDFAndImages(fileList,target);
    }

    /**
     * 文件和图片同时合并
     * @param FileList     需要合并的文件地址list
     * @param mergedFilePath  合并后文件存储位置
     * @throws Exception
     */
    public static String mergePDFAndImages( List<String> FileList, String mergedFilePath) throws Exception {
// 创建一个 PDFMergerUtility 对象
        PDFMergerUtility merger = new PDFMergerUtility();
        for (String filePath : FileList) {
            String extension = "";
            int dotIndex = filePath.lastIndexOf(".");
            if (dotIndex > 0 && dotIndex < filePath.length() - 1) {
                extension = filePath.substring(dotIndex + 1).toLowerCase();
            }
            if(extension.equals("pdf")){
                merger.addSource(new File(filePath));
            }else if(extension.equals("png")||extension.equals("jpg")||extension.equals("jpeg")){
                merger.addSource(convertImageToPdf(new File(filePath),mergedFilePath));
            }
        }
        String mergeTmpFilePath=mergedFilePath+UUID.randomUUID().toString() +"_merged.pdf";
        // 合并所有文件并写入指定文件
        merger.setDestinationFileName(mergeTmpFilePath);
        merger.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());
        return mergeTmpFilePath;
    }
    /**
     * 图片转pdf
     * @param imageFile
     * @return
     * @throws IOException
     */
    private static String convertImageToPdf(File imageFile,String mergedFilePath) throws IOException {
        //图片临时记录pdf文件存储,未做删除。
        String tempPdfFilename = mergedFilePath+UUID.randomUUID().toString() + ".pdf";
        BufferedImage image = ImageIO.read(imageFile);
        float width = image.getWidth();
        float height = image.getHeight();
        PDDocument document = new PDDocument();
        PDPage page = new PDPage();
        document.addPage(page);
        try (FileInputStream fis = new FileInputStream(imageFile)) {
            PDImageXObject pdImage = LosslessFactory.createFromImage(document, ImageIO.read(fis));
            float pageWidth = page.getMediaBox().getWidth();
            float pageHeight = page.getMediaBox().getHeight();
           //图片高宽自适应pdf
            if (width > pageWidth || height > pageHeight) {
                float scale = Math.min(pageWidth / width, pageHeight / height);
                float scaledWidth = width * scale;
                float scaledHeight = height * scale;
                float x = (pageWidth - scaledWidth) / 2;
                float y = (pageHeight - scaledHeight) / 2;
                page.setCropBox(new PDPage().getMediaBox());
                page.setMediaBox(new PDPage().getMediaBox());
                page.setBleedBox(new PDPage().getMediaBox());
                page.setTrimBox(new PDPage().getMediaBox());
                page.setArtBox(new PDPage().getMediaBox());
                PDPageContentStream contentStream = new PDPageContentStream(document, page);
                contentStream.drawImage(pdImage, x, y, scaledWidth, scaledHeight);
                contentStream.close();
            } else {
                PDPageContentStream contentStream = new PDPageContentStream(document, page);
                contentStream.drawImage(pdImage, 0, 0);
                contentStream.close();
            }
        }
        document.save(tempPdfFilename);
        document.close();
        return tempPdfFilename;
    }

    /**
     * 文件下载
     * @param fileUrl
     * @param targetDirectory
     * @throws IOException
     */
    public static String  downloadFile(String fileUrl, String targetDirectory) throws IOException {
        URL url = new URL(fileUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        String filePath="";
        try (InputStream inputStream = new BufferedInputStream(connection.getInputStream())) {
            String fileName = getFileNameFromUrl(fileUrl);
             filePath = targetDirectory + fileName;

            try (FileOutputStream outputStream = new FileOutputStream(filePath)) {
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
            }
        }

        connection.disconnect();
        return filePath;
    }

    /**
     * 获取文件名称
     * @param fileUrl
     * @return
     */
    public static String getFileNameFromUrl(String fileUrl) {
        int lastIndexOfSlash = fileUrl.lastIndexOf("/");
        if (lastIndexOfSlash != -1 && lastIndexOfSlash < fileUrl.length() - 1) {
            return fileUrl.substring(lastIndexOfSlash + 1);
        }
        return "";
    }
    }
相关推荐
AI英德西牛仔1 小时前
豆包导出 pdf 颜色不一样怎么办,选用 AI 导出鸭优化文档导出,结合行业白皮书数据解析色彩失真成因
人工智能·ai·chatgpt·pdf·deepseek·ai导出鸭
薰珞婷紫小亭子4 小时前
如何解决IEEE期刊LaTeX 模版编译pdf出现大空白的问题
经验分享·pdf
Hello-FPGA6 小时前
AI 如何自动通过 PDF 原理图生成管脚映射
人工智能·fpga开发·pdf
阿部多瑞 ABU8 小时前
告别手工核图:基于 .NET + MuPDFCore 的 CAD 等轴测 PDF 材料表提取与新旧版本对比实战
后端·算法·ui·pdf·c#
2601_963906781 天前
可自由切割与合并的 PDF 尺寸调整与打印工具
pdf
2601_965912911 天前
PDF转Word与拆分组合操作实测:从格式保真到批量处理的方案对比
pdf·word
海兰1 天前
【应用】ClawPDF 完全指南:安装、部署与使用
人工智能·pdf·openclaw
XLYcmy1 天前
PDF论文处理器 - 功能总结
数据库·python·pdf·csv·pymupdf·dify·文本分割
阿伟玩不懂1 天前
AI帮你读PDF——自建文档解析与智能问答工具
人工智能·pdf
霸道流氓气质2 天前
基于本地 PaddleOCR 的 PDF 文字识别完整技术文档
开发语言·r语言·pdf