Java实现pdf文件合并

在maven项目中引入以下依赖包

xml 复制代码
    <dependencies>
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox-examples</artifactId>
            <version>3.0.1</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.9.0</version>
        </dependency>
    </dependencies>

创建一个工具类

java 复制代码
package org.apache.pdfbox.utils;

import org.apache.commons.io.FileUtils;
import org.apache.pdfbox.examples.util.PDFMergerExample;
import org.apache.pdfbox.io.RandomAccessRead;
import org.apache.pdfbox.io.RandomAccessReadMemoryMappedFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @author: guanglai.zhou
 * @date: 2023/12/14 13:15
 */
public class PdfMergerUtils {

    /**
     * 合并指定目录中的pdf文件
     *
     * @param fromDir  指定目录
     * @param descFile 目标pdf文件
     * @return 目标pdf文件
     * @throws IOException
     */
    public static File merge(String fromDir, String descFile) throws IOException {
        final File resultFile = new File(descFile);
        File file = new File(fromDir);
        List<File> files = new ArrayList<>();
        list(file, new Predicate<File>() {
            @Override
            public boolean test(File file) {
                return true;
            }
        }, new Predicate<File>() {
            // 选择pdf文件
            @Override
            public boolean test(File file) {
                return file.getPath().endsWith(".pdf");
            }
        }, files);
        if (files.isEmpty()) {
            throw new RuntimeException("源文件不存在pdf格式文档?");
        }
//        files.sort(Comparator.comparing(File::getName));
        if (resultFile.exists()) {
            FileUtils.forceDelete(resultFile);
        }
        mergePdfs(resultFile, files);
        return resultFile;
    }

    /**
     * 针对文件进行遍历 如果文件夹满足directoryPredicate,则继续遍历文件夹,如果是文件,则判断是否满足filePredicate,如果满足则添加到
     * collector结果集当中
     *
     * @param file               文件夹
     * @param directoryPredicate 文件夹预期 为null 则不针对文件夹做过滤
     * @param filePredicate      文件预期 为null 则不针对文件做过滤
     * @param collector          收集器 收集所有符合条件的文件
     */
    public static void list(File file, Predicate<File> directoryPredicate, Predicate<File> filePredicate, List<File> collector) {
        File[] childFiles = file.listFiles();
        if (childFiles == null) {
            return;
        }
        // 根据脚本名称进行排序
        List<File> fileList = Arrays.stream(childFiles).sorted(Comparator.comparing(File::getName)).collect(Collectors.toList());
        for (File childFile : fileList) {
            if (childFile.isDirectory()) {
                boolean pass = directoryPredicate == null || directoryPredicate.test(childFile);
                if (pass) {
                    // 继续遍历子文件夹目录
                    list(childFile, directoryPredicate, filePredicate, collector);
                }
            } else {
                boolean pass = filePredicate == null || filePredicate.test(childFile);
                if (pass) {
                    collector.add(childFile);
                }
            }
        }
    }

    private static void mergePdfs(File resultFile, List<File> files) throws IOException {
        PDFMergerExample example = new PDFMergerExample();
        List<RandomAccessRead> sources = new ArrayList<>();
        for (File currFile : files) {
            sources.add(new RandomAccessReadMemoryMappedFile(currFile));
        }
        InputStream inputStream = example.merge(sources);
        FileUtils.copyInputStreamToFile(inputStream, resultFile);
    }

}

将需要合并的pdf文件都拷贝到指定目录a中,调用该工具类将该目录作为第一个参数,第二个参数传入输出文件对象即可。

相关推荐
工业互联网专业13 分钟前
基于协同过滤算法的小说推荐系统_django+spider
python·django·毕业设计·源码·课程设计·spider·协同过滤算法
星星的月亮叫太阳20 分钟前
large-scale-DRL-exploration 代码阅读 总结
python·算法
wfsm28 分钟前
flowable使用01
java·前端·servlet
员大头硬花生32 分钟前
七、InnoDB引擎-架构-后台线程
java·数据库·mysql
Q_Q196328847538 分钟前
python+django/flask基于Echarts+Python的图书零售监测系统设计与实现(带大屏)
spring boot·python·django·flask·node.js·php
拾荒的小海螺1 小时前
JAVA:Spring Boot3 新特性解析的技术指南
java·开发语言·spring boot
深度学习lover1 小时前
<数据集>yolo航拍交通目标识别数据集<目标检测>
人工智能·python·yolo·目标检测·计算机视觉·航拍交通目标识别
程序猿20231 小时前
Python每日一练---第二天:合并两个有序数组
开发语言·python
权泽谦1 小时前
用 Flask + OpenAI API 打造一个智能聊天机器人(附完整源码与部署教程)
python·机器人·flask
暹罗软件开发1 小时前
快速搭建分布式链路追踪系统:SkyWalking全攻略
java·skywalking