当前位置: 首页 > news >正文

Java实现pdf文件合并

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

    <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>

创建一个工具类

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>() {@Overridepublic boolean test(File file) {return true;}}, new Predicate<File>() {// 选择pdf文件@Overridepublic 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中,调用该工具类将该目录作为第一个参数,第二个参数传入输出文件对象即可。

相关文章:

Java实现pdf文件合并

在maven项目中引入以下依赖包 <dependencies><dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox-examples</artifactId><version>3.0.1</version></dependency><dependency><groupId>co…...

ArcGIS导入excel中的经纬度信息,绘制矢量

1.首先整理坐标信息 2.其次转成2003格式的excel文件 3.导入arcgis&#xff0c;点击右键添加excel数据 4.显示xy数据 5.显示经度和纬度信息 6&#xff1a;点击【地理坐标系】->【World】->【WGS 1984】->【确定】 7.投影带的确定方式&#xff1a; 因为自己一直…...

【Hadoop】

Hadoop是一个开源的分布式离线数据处理框架&#xff0c;底层是用Java语言编写的&#xff0c;包含了HDFS、MapReduce、Yarn三大部分。 组件配置文件启动进程备注Hadoop HDFS需修改需启动 NameNode(NN)作为主节点 DataNode(DN)作为从节点 SecondaryNameNode(SNN)主节点辅助分…...

GitHub帐户管理更改电子邮件

登录到您的 GitHub 帐户&#xff1a; 前往 GitHub 网站并使用您的凭据登录。 访问个人设置&#xff1a; 单击右上角的您的头像&#xff0c;然后选择“Settings”&#xff08;设置&#xff09;。 选择电子邮件选项卡&#xff1a; 在左侧边栏中选择“Emails”&#xff08;电子邮…...

InsCode实践分享

一、背景介绍 随着社交媒体的普及&#xff0c;越来越多的品牌和商家开始关注如何利用社交媒体平台来提高品牌知名度和销售额。其中&#xff0c;Instagram作为一个以图片和视频为主要内容的社交媒体平台&#xff0c;已经成为了很多品牌和商家进行营销的重要渠道。InsCode是Inst…...

大一C语言作业 12.14

1.A A&#xff1a;将pa指向的元素赋值给x&#xff0c;即x a[0] B&#xff1a;将a数组第二个元素的值赋给x&#xff0c;即x a[1] C&#xff1a;将pa指向的下一个元素的值赋给x&#xff0c;即x a[1] D&#xff1a;将a数组第二个元素的值赋给x&#xff0c;即x a[1] 2. 6 2 3 …...

微服务技术 RabbitMQ SpringAMQP P61-P76

B站学习视频https://www.bilibili.com/video/BV1LQ4y127n4?p61&vd_source8665d6da33d4e2277ca40f03210fe53a 文档资料: 链接&#xff1a;https://pan.baidu.com/s/1P_Ag1BYiPaF52EI19A0YRw?pwdd03r 提取码&#xff1a;d03r 一 初始MQ 1. 同步通讯 2. 异步通讯 3. MQ常…...

BearPi Std 板从入门到放弃 - 先天神魂篇(3)(RT-Thread I2C设备 读取光照强度BH1750)

简介 使用BearPi IOT Std开发板及其扩展板E53_SC1&#xff0c; SC1上有I2C1 的光照强度传感器BH1750 和 EEPROM AT24C02&#xff0c; 本次主要就是读取光照强度; 主板: 主芯片: STM32L431RCT6LED : PC13 \ 推挽输出\ 高电平点亮串口: Usart1I2C使用 : I2C1E53_SC1扩展板 : LE…...

中文分词演进(查词典,hmm标注,无监督统计)新词发现

查词典和字标注 目前中文分词主要有两种思路&#xff1a;查词典和字标注。 首先&#xff0c;查词典的方法有&#xff1a;机械的最大匹配法、最少词数法&#xff0c;以及基于有向无环图的最大概率组合&#xff0c;还有基于语言模型的最大概率组合&#xff0c;等等。 查词典的方法…...

Docker容器数据卷

一、概念 1.定义 卷就是目录或文件&#xff0c;存在于一个或多个容器中&#xff0c;由docker挂载到容器&#xff0c;但不属于联合文件系统&#xff0c;因此能够绕过Union File System提供一些用于持续存储或共享数据的特性。 卷的设计目的就是数据的持久化&#xff0c;完全独…...

chatGPT 国内版,嵌入midjourney AI创作工具

聊天GPT国内入口,免切网直达,可直接多语言对话,操作简单,无需复杂注册,智能高效,即刻使用.可以用作个人助理,学习助理,智能创作、新媒体文案创作、智能创作等各种应用场景! 地址&#xff1a; https://ai.wboat.cn/...

Yum仓库架构解析与搭建实践

1.Yum仓库搭建 1.1本地Yum仓库图解 1.2Linux本地仓库搭建 配置本地光盘镜像仓库 1&#xff09;挂载 [roothadoop101 ~]# mount -t iso996 /dev/cdrom/mnt 2&#xff09;查看 [rooothadoop101 ~] # df -h | |grep -i mnt /dev/sr0 4.6G 4.4G 3&#xf…...

ElementPlus中的分页逻辑与实现

ElementPlus中的分页逻辑与实现 分页是web开发中必不可少的组件&#xff0c;element团队提供了简洁美观的分页组件&#xff0c;配合table数据可以实现即插即用的分页效果。分页的实现可以分成两种&#xff0c;一是前端分页&#xff0c;二是后端分页。这两种分页分别适用于不同…...

实验01:静态路由配置实验

1.实验目的&#xff1a; 本次实验的主要目的是了解静态路由的配置和实现原理&#xff0c;熟悉路由器的基本操作&#xff0c;掌握在网络中进行静态路由配置的方法和技巧。 2.实验内容&#xff1a; 搭建网络拓扑&#xff0c;包括三台路由器和两台PC。配置路由器的IP地址和路由…...

C#中简单的继承和多态

今天我们来聊一聊继承&#xff0c;说实话今天也是我第一次接触。 继承的概念是什么呢&#xff1f;就是一个类可以继承另一个类的属性和方法&#xff08;成员&#xff09; 继承是面向对象编程中的一个非常重要的特性。 好了&#xff0c;废话不多说&#xff0c;下面切入正题&a…...

15、lambda表达式、右值引用、移动语义

前言 返回值后置 auto 函数名 (形参表) ->decltype(表达式) lambda表达式 lambda表达式的名称是一个表达式 (外观类似函数)&#xff0c;但本质绝非如此 语法规则 [捕获表] (参数表) 选项 -> 返回类型 { 函数体; }lambda表达式的本质 lambda表达式本质其实是一个类…...

spring boot 实现直播聊天室(二)

spring boot 实现直播聊天室(二) 技术方案: spring bootnettyrabbitmq 目录结构 引入依赖 <dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.96.Final</version> </dependency>Si…...

alibaba fastjson GET List传参 和 接收解析

之前一直都是 get传的都是单字符串&#xff08;例如 xxxxxxxxx?name{name};name“woaini”;&#xff09;&#xff0c;并没有传list的. GET List传参 问题场景 String url"xxxxxxxx?id{id}"; HashMap<String,Object> param new HashMap<>(); param.pu…...

API自动化测试是什么?我们该如何做API自动化测试呢?

API测试已经成为测试工作中的常规任务之一。为了提高测试效率并减少重复的手工操作&#xff0c;API自动化测试变得越来越重要。本文总结了API自动化测试方面的经验和心得&#xff0c;旨在与读者分享。 掌握自动化技能已经成为高级测试工程师的必备技能。敏捷和持续测试改变了传…...

PyTorch 的 10 条内部用法

欢迎阅读这份有关 PyTorch 原理的简明指南[1]。无论您是初学者还是有一定经验&#xff0c;了解这些原则都可以让您的旅程更加顺利。让我们开始吧&#xff01; 1. 张量&#xff1a;构建模块 PyTorch 中的张量是多维数组。它们与 NumPy 的 ndarray 类似&#xff0c;但可以在 GPU …...

【独家首发】ElevenLabs马拉雅拉姆文支持状态实测报告(含ISO 639-2代码验证、音素对齐误差率<0.8%)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;ElevenLabs马拉雅拉姆文支持的现状与战略意义 ElevenLabs 作为全球领先的语音合成平台&#xff0c;自2023年11月起正式将马拉雅拉姆语&#xff08;Malayalam&#xff0c;ISO 639-1: ml&#xff09;纳入…...

RT-Thread SMP启动流程深度解析:从多核同步到调度就绪

1. 项目概述&#xff1a;从单核到多核&#xff0c;RT-Thread的启动逻辑变迁如果你是从RT-Thread 3.x版本一路用过来的老用户&#xff0c;或者刚开始接触RT-Thread 4.x&#xff0c;可能会发现一个显著的变化&#xff1a;启动流程变“复杂”了。以前&#xff0c;一个main函数或者…...

别再只懂install_github了!深入聊聊R包管理:GitHub PAT、依赖与Linux系统库的那些事儿

别再只懂install_github了&#xff01;深入聊聊R包管理&#xff1a;GitHub PAT、依赖与Linux系统库的那些事儿 在数据科学和统计分析的世界里&#xff0c;R语言凭借其强大的包生态系统和活跃的开源社区&#xff0c;已经成为许多专业人士的首选工具。然而&#xff0c;当我们从个…...

第一章-04-路径参数_Path类型注解

1.路径参数出现在什么位置URL 路径的一部分 /book/{id}2.如何为路径参数添加类型注解Python 原生注解 和 Path 注解3.练习需求&#xff1a;定义两个接口&#xff0c;携带路径参数&#xff0c;并使用 Path 来实现类型注解 具体如下&#xff1a; 接口1&#xff1a;以 新闻分类 …...

Node.js 服务端项目接入 Taotoken 多模型 API 的完整步骤

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 Node.js 服务端项目接入 Taotoken 多模型 API 的完整步骤 对于使用 Node.js 构建后端服务的开发者而言&#xff0c;统一接入多个大…...

L1正则与次梯度

L1&#xff1a;稀疏权重、解易落在轴上、特征选择&#xff08;应用场景&#xff09;、w0w0w0不可导需次梯度subgradient&#xff1a;∂f(x){g∣f(y)≥f(x)gT(y−x),∀ y∈dom f}\partial f(x)\{g|f(y)\geq f(x) g^T(y-x),\forall\ y\in \text{dom}\ f \}∂f(x){g∣f(y)≥f(x)g…...

每日大赛间歇期通过Taotoken模型广场探索新模型特性

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 每日大赛间歇期通过Taotoken模型广场探索新模型特性 对于每日参与各类AI应用开发或创意大赛的选手而言&#xff0c;比赛间歇期并非…...

独立开发者利用Taotoken Token Plan套餐实现个人项目的长期成本规划

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 独立开发者利用Taotoken Token Plan套餐实现个人项目的长期成本规划 对于独立开发者或小型工作室而言&#xff0c;运营多个集成大语…...

MobaXterm远程桌面实战:在Ubuntu上配置与连接RDP服务

1. 为什么选择MobaXterm连接Ubuntu远程桌面 作为一名常年和Linux服务器打交道的开发者&#xff0c;我深知纯命令行操作有时会遇到效率瓶颈。特别是当需要处理图形界面应用或者进行复杂配置时&#xff0c;SSH终端就显得力不从心了。这时候&#xff0c;RDP远程桌面协议就成了救命…...

从‘点一下’到‘连一连’:Qt6中PushButton信号与槽的5种连接方式详解(含Lambda表达式实战)

从‘点一下’到‘连一连’&#xff1a;Qt6中PushButton信号与槽的5种连接方式详解&#xff08;含Lambda表达式实战&#xff09; 在Qt框架中&#xff0c;PushButton作为最基础的交互控件之一&#xff0c;其信号与槽机制是构建响应式用户界面的核心。随着Qt6的发布&#xff0c;信…...