文章目录

  • 前言
  • 实现
    • 依赖引入
    • 工具类编写

前言

最近接了一个需求,客户觉得一个合同导出多项类型的pdf数据,不够直接明了,需要将多个pdf文件 合并 成一个pdf

实现

依赖引入

编写工具类之前,需要先引入对应的依赖库信息。
本次使用的是com.lowagie.itext这个工具pom,完整依赖如下所示:

<dependency><groupId>com.lowagie</groupId><artifactId>itext</artifactId><version>2.1.7</version>
</dependency>

工具类编写

实现上述的目的,有以下两种方式:

  • 先生成临时pdf文件,再进行文件合并,并生成新的pdf base64编码返回请求端,最后将临时文件删除。
  • 直接将base64编码的值,转换为byte字节码文件,直接进行字节码信息的合并。

先来看方式一:

import java.io.*;import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfCopy;
import com.lowagie.text.pdf.PdfImportedPage;
import com.lowagie.text.pdf.PdfReader;
import lombok.Cleanup;
import org.springframework.util.CollectionUtils;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;/*** @Title: 需要引入<code>com.lowagie.itext  2.1.7 <code/> 依赖* @description: 多个pdf 文件合并成一个pdf文件**/
public class PdfMergeUtils {/*** 多个pdf文件合并* @param files 待合并的文件数组* @param newfile 新的文件全路径信息(带文件名)* @return*/public static boolean mergePdfFiles(String[] files, String newfile) {boolean retValue = false;Document document = null;PdfCopy copy = null;PdfReader reader = null;try {document = new Document(new PdfReader(files[0]).getPageSize(1));copy = new PdfCopy(document, new FileOutputStream(newfile));document.open();for (int i = 0; i < files.length; i++) {reader = new PdfReader(files[i]);int n = reader.getNumberOfPages();for (int j = 1; j <= n; j++) {document.newPage();PdfImportedPage page = copy.getImportedPage(reader, j);copy.addPage(page);}reader.close();}retValue = true;} catch (Exception e) {e.printStackTrace();} finally {if (reader != null) {reader.close();}if (copy != null) {copy.close();}if (document != null) {document.close();}}return retValue;}/*** 将文件集合信息 ,合并到 <code>newfile<code/>文件名的新pdf文件中* @param files  待合并的pdf文件* @param newfile 合并后新生成的pdf文件(如果不是全路径,则会生成在项目同级目录下)* @return*/public static boolean mergePdfFiles(List<String> files, String newfile) {if(CollectionUtils.isEmpty(files)){return Boolean.FALSE;}boolean retValue = false;Document document = null;PdfCopy copy = null;PdfReader reader = null;try {// 以第一个pdf 作为基准PdfReader pdfReader = new PdfReader(files.get(0));Rectangle rectangle = pdfReader.getPageSize(1);document = new Document(rectangle);// 以第一个pdf 构建新的pdf文件输出流copy = new PdfCopy(document, new FileOutputStream(newfile));document.open();for (int i = 0; i < files.size(); i++) {// 读取pdf文件reader = new PdfReader(files.get(i));int n = reader.getNumberOfPages();for (int j = 1; j <= n; j++) {document.newPage(); // 创建新的pdf页数PdfImportedPage page = copy.getImportedPage(reader, j);copy.addPage(page);}reader.close();}retValue = true;} catch (Exception e) {e.printStackTrace();} finally {if (reader != null) {reader.close();}if (copy != null) {copy.close();}if (document != null) {document.close();}}return retValue;}/*** 将pdf的base64 编码,转换成对应的pdf文件暂存,并返回文件名称集合* @param base64Lists* @return* @throws Exception*/public static List<String> base64ToFile(List<String> base64Lists) throws Exception {if(CollectionUtils.isEmpty(base64Lists)){return null;}List<String> returnStrLists = new ArrayList<>();BASE64Decoder decoder = new BASE64Decoder();for (String base64Str : base64Lists) {byte[] fileBytes = decoder.decodeBuffer(base64Str);@Cleanup ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(fileBytes);// 此处代码会导致生成的文件很大// @Cleanup ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(fileBytes.length);// 生成临时文件  为了保证文件的唯一性,必须名称不同String fileName = "report_"+UUID.randomUUID().toString()+".pdf";returnStrLists.add(fileName); // 返回调用方文件名集合// 暂存文件@Cleanup OutputStream outputStream = new FileOutputStream(fileName);
//            int c = 0;
//            while (c < byteArrayInputStream.read()){//                byteArrayOutputStream.write(fileBytes);
//                byteArrayOutputStream.writeTo(outputStream);
//                byteArrayOutputStream.flush();
//            }byte[] bytes = new byte[1024];int len = 0;while ((len = byteArrayInputStream.read(bytes)) > 0){outputStream.write(bytes,0,len);}}return returnStrLists;}/*** 根据获取到的pdf base64 文件流集合,生成临时文件,并重新读取临时文件,进行pdf的合并。* @param base64Pdfs 各个合同类型数据pdf文件base64数据流* @return 新的已合并的pdf文件流的base64 数据值* @throws Exception*/public static String getNewMergePdfBase64(List<String> base64Pdfs) throws Exception {String newPdfName = null;List<String> fileNameLists = null;try {fileNameLists = base64ToFile(base64Pdfs);newPdfName = "report_"+UUID.randomUUID().toString()+".pdf";mergePdfFiles(fileNameLists, newPdfName);// 以新的文件名  读取成文件流  并转换base64 返回@Cleanup FileInputStream fileInputStream = new FileInputStream(newPdfName);return base64ForPdf(fileInputStream);}finally {// 如果临时文件存在,则删除临时文件if(StringUtils.isNotBlank(newPdfName)){File file = new File(newPdfName);if (file != null && file.isFile() && file.exists()) {file.delete();}}if(!CollectionUtils.isEmpty(fileNameLists)){for (String fileName : fileNameLists) {File file = new File(fileName);if (file != null && file.isFile() && file.exists()) {file.delete();}}}}}/***将文件输入流,转换为 base64 返回给请求端**/public static String base64ForPdf(InputStream fin) throws Exception {BASE64Encoder encoder = new BASE64Encoder();BufferedInputStream bin = new BufferedInputStream(fin);ByteArrayOutputStream baos = new ByteArrayOutputStream();BufferedOutputStream bout = new BufferedOutputStream(baos);byte[] buffer = new byte[1024];for (int len = bin.read(buffer); len != -1; len = bin.read(buffer)) {bout.write(buffer, 0, len);}bout.flush();byte[] bytes = baos.toByteArray();String var11 = encoder.encodeBuffer(bytes).trim();return var11;}
}

方式二就相对简单点,舍去了中间生成各个临时文件的逻辑,直接进行pdf数据流的合并。逻辑如下所示:

/*** pdf 合并操作2* 直接将各个pdf对应的字节码,进行合并成新的pdf文件数据* @param base64Pdfs  多个pdf的base64编码文件* @return*/
public static String getNewMergePdfBase64_2(List<String> base64Pdfs) throws Exception {String newPdfName = null;try{List<byte[]> byteLists = base64ToByte(base64Pdfs);// 将pdf的byte[] 数据生成新的pdf文件if(CollectionUtils.isEmpty(byteLists)){return null;}// 生成新的pdf文件newPdfName = "report_"+UUID.randomUUID().toString()+".pdf";mergePdfFiles2(byteLists,newPdfName);@Cleanup FileInputStream fileInputStream = new FileInputStream(newPdfName);return base64ForPdf(fileInputStream);}finally {// 如果临时文件存在,则删除临时文件if(StringUtils.isNotBlank(newPdfName)){File file = new File(newPdfName);if (file != null && file.isFile() && file.exists()) {file.delete();}}}
}public static void mergePdfFiles2(List<byte[]> bytes, String newFile) {try {// 以第一个pdf作为基础,后面的每页信息逐渐累加Document document = new Document(new PdfReader(bytes.get(0)).getPageSize(1));PdfCopy copy = new PdfCopy(document, new FileOutputStream(newFile));document.open();for (byte[] aByte : bytes) {PdfReader reader = new PdfReader(aByte);int n = reader.getNumberOfPages();for (int j = 1; j <= n; j++) {document.newPage();PdfImportedPage page = copy.getImportedPage(reader, j);copy.addPage(page);}}document.close();} catch (IOException | DocumentException e) {e.printStackTrace();}
}
/*** base62 文件,转byte[]* @param base64Lists  多个pdf的base64 编码* @return 多个pdf文件的字节码数组集合*/
private static List<byte[]> base64ToByte(List<String> base64Lists) throws Exception {if(CollectionUtils.isEmpty(base64Lists)){return null;}List<byte[]> returnStrLists = new ArrayList<>();BASE64Decoder decoder = new BASE64Decoder();for (String base64Str : base64Lists) {byte[] fileBytes = decoder.decodeBuffer(base64Str);returnStrLists.add(fileBytes);}return returnStrLists;
}

@Cleanup 注解的作用就是代码执行完成后,默认调用对应对象的close(),就好比第一个方法中的finally。

Springboot——多个pdf文件合并成一个工具类编写相关推荐

  1. PDF文件合并使用什么工具

    我们在网上下载文件的时候,一般一个文件往往不能满足我们的需求,所以我们这时候,就需要将几个文件合并到一起,然后这样就方便多了.小编自己也总结了PDF文件合并的方法,是借助一款工具来解决的,身边同事遇到 ...

  2. 如何将多个PDF文件合并成一个大的PDF文件

    什么是PDF合并 PDF是目前大家在工作学习中用的比较多的一种文档格式,大家有时候需要将多个PDF文件合成一个大的PDF,然而一般的PDF软件只能读不能写,这个时候您需要借助一些工具来实现PDF的合并 ...

  3. PDF怎么合并成一个文件?试试这个思路

    PDF是一种很常见的电子文档格式,通常用于共享和打印文档.但是有时候,我们可能需要将多个PDF文件合并成一个文件,以便于管理和浏览.下面是一些可以用来合并PDF文件的方法,这些方法都有其各自的优缺点. ...

  4. 多个pdf文件如何合并为一个文件?怎样将多个pdf文件合并到一个文件?

    怎样把多个pdf文件合并到一个文件? 现在PDF文件是我们日常办公中比较常见的一种文件格式, 我们在处理PDF文件的时候,难免会遇到各种各样的问题.有时候我们需要把多个pdf合并成一个pdf,但是还有 ...

  5. python实现PDF文件合并操作,附可直接使用的exe文件

    前几日在打数学建模比赛,发现有一个需求是把保证书和论文两个PDF文件合并成一个再去提交,但我在网上搜寻了很多的网站和软件,却发现它们大多数都是收费的,以WPS为例,使用合并PDF功能需要开通完整的稻草 ...

  6. 如何将两个或多个PDF文件合并成一个?这3个方法可以看看

    在工作中,有时候我们需要把两个或多个PDF文件合并成一个,这样一来,可以方便阅读.修改,还能快速打印文件. 下面分享3个工具,看看如何将两个或多个PDF文件合并成一个文件. 方法一:使用美图工具 如果 ...

  7. 怎么把多个pdf文件合并成一个?一分钟解决

    当我们有多个PDF文件时,将它们合并成一个文件可以帮助您更轻松地管理和浏览文件.不必打开多个文件,只需打开一个文件就能查看所有内容.将PDF文件合并成一个文件可以帮助您更好地组织文档,以便于共享和备份 ...

  8. pdf怎么合并成一个文件?高效工具分享

    PDF是一种非常常用的文档格式,许多人经常需要合并多个PDF文件为一个文件.这是因为有时候我们需要将多个PDF文件打包成一个文件,以便于共享或归档.在本文中,我们将介绍如何使用电脑或手机合并PDF文件 ...

  9. 如何将多个excel表格合并成一个_怎么将多个pdf文件合并成一个?

    现实生活中,不知道大家有没有遇上这样的时刻,自己不会做pdf文件,于是就去网上找了一些素材,但是网上的素材都是零零散散的,但是我们又不知道应该如何才能将她们拼凑到一起.如果你也在为这样的问题而烦恼的话 ...

最新文章

  1. mysql主节点数据恢复_Mysql 主从复制+数据恢复
  2. html页面光标坐标值,javascript-在包含HTML内容的contentEditable区域中获取插入符(光标)的位置...
  3. python中str用法_python中的str()不能直接用吗 -问答-阿里云开发者社区-阿里云
  4. 部署负载均衡 Keepalived DR群集优化版(减少部署完成后的BUG)
  5. IOS之通知NSNotificationCenter的使用
  6. Java的子类可以继承父类的私有变量和私有方法吗?
  7. 我写了一个开源项目AlphabetPy
  8. SWAT 学习相关基础知识(一)---Mr.Zhang
  9. 在Linux下安装LaTeX+CJK+中文字体的方法 [转]
  10. OpenCV图像的编解码读取
  11. Git hub加载慢?下载慢?浏览慢?几个小技巧让你一键起飞!
  12. Python清理微信僵尸粉
  13. c#中使用BackgroundWorker
  14. java环境安装教程_java环境搭建教程
  15. XML中输入特殊符号
  16. ZOJ1516HDU1507(二分图匹配)
  17. (连载)Android 8.0 : 系统启动流程之Linux内核
  18. jsp输出金字塔_倒金字塔加码操作技巧及案例解析
  19. idea如何查看并去掉所有断点
  20. 最新北风网人工智能(完整版)

热门文章

  1. acm竞赛技巧——c/c++ /java 快读快写(整数,字符串)
  2. 消息称腾讯微信试行“1065”工作制,晚 18 点强制下班
  3. 运行Android电脑卡,电脑运行安卓模拟器很卡如何提升其运行速度
  4. css中的opacity
  5. Android 为图片添加文字水印
  6. 常见的数据结构:栈 队列 数组 链表 红黑树——List集合 _ HashSet集合、可变参数 collections集合 Map集合
  7. 通俗易懂的讲解随机森林
  8. python爬虫爬取图片无法打开_半小时入门python爬虫爬下网站图片,不能再简单了...
  9. 计算机毕业设计ssm高校职称申报系统337gs系统+程序+源码+lw+远程部署
  10. 2017第八届蓝桥杯省赛-大学A组 包子凑数