在实际的开发过程中,可能会遇到以下的一些场景:

  • 一个全部为竖版的PDF文件,现在需要将其全部转换为横版PDF文件;
  • 一个全部为竖版的PDF文件,现在需要将指定页转换为横版PDF文件;
  • 一个PDF文件中既有横板也有竖版,现在需要将所有横版转换为竖版;
  • 一个PDF文件中既有横板也有竖版,现在需要将所有竖版转换为横版;

这些需求都可以通过使用 itextpdf 开源库来实现,下面来通过代码进行演示。

需要说明的是,这里的转换只是PDF版式的旋转,并非是页面内容的旋转,如果需要在旋转版式的时候,同时旋转页面上的文字,那么下面的方法可能不太适用了。

1、引入依赖

目前 itextpdf 最新版本为 5.5.13.3,可以在 https://search.maven.org/ 网站进行搜索。

<dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13.3</version>
</dependency>

2、代码实现

不论是横版PDF转竖版PDF,还是竖版PDF转横板PDF,其实都是旋转问题,比如将一个横版PDF顺时针或者逆时针旋转90,得到的就是一个竖版的PDF,而将一个竖版PDF顺时针或者逆时针旋转90,得到的就是一个横板的PDF。

package com.magic.itextpdf;import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfNumber;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfSmartCopy;/*** PDF工具类*/
public class PdfUtils {/*** 旋转PDF文件* @param sourceFile 源PDF文件路径* @param targetFile 目标PDF文件路径* @param angle 旋转角度*/public static void rotate(String sourceFile, String targetFile, int angle) {PdfReader reader = null;Document document = null;FileOutputStream outputStream = null;try {// 读取源文件reader = new PdfReader(sourceFile);// 创建新的文档document = new Document();// 创建目标PDF文件outputStream = new FileOutputStream(targetFile);PdfCopy pdfCopy = new PdfSmartCopy(document, outputStream);// 获取源文件的页数int pages = reader.getNumberOfPages();document.open();PdfDictionary pdfDictionary;// 注意此处的页码是从1开始for (int page = 1; page <= pages; page++) {pdfDictionary = reader.getPageN(page);pdfDictionary.put(PdfName.ROTATE, new PdfNumber(angle));pdfCopy.addPage(pdfCopy.getImportedPage(reader, page));}} catch (IOException | DocumentException e) {e.printStackTrace();} finally {if (reader != null) {reader.close();}if (document != null) {document.close();}if (outputStream != null) {try {outputStream.flush();outputStream.close();} catch (IOException e) {e.printStackTrace();}}}}
}

这里的旋转角度 angle 必须是90的倍数,如果是其他的角度,则是无效的。有了旋转的方法后,我们可以再定义一些基础方法,比如顺时针旋转(右旋转)、逆时针旋转(左旋转)和垂直翻转,这样使用起来会更加方便。

(1)顺时针旋转(右旋转90)

    /*** 右旋转PDF文件90度* @param sourceFile 源PDF文件路径* @param targetFile 目标PDF文件路径*/public static void rightRotate(String sourceFile, String targetFile) {rotate(sourceFile, targetFile, -90);}

(2)逆时针旋转(左旋转90)

    /*** 左旋转PDF文件90度* @param sourceFile 源PDF文件路径* @param targetFile 目标PDF文件路径*/public static void leftRotate(String sourceFile, String targetFile) {rotate(sourceFile, targetFile, 90);}

(3)垂直(旋转180)

    /*** 翻转PDF文件* @param sourceFile 源PDF文件路径* @param targetFile 目标PDF文件路径*/public static void filp(String sourceFile, String targetFile) {rotate(sourceFile, targetFile, 180);}

在某些固定的场景下,可能旋转就是特指逆时针旋转,那么这个时候,我们还可以重载 rotate() 方法,默认使用 leftRotate() 方法,如下:

    /*** 旋转PDF文件* @param sourceFile 源PDF文件路径* @param targetFile 目标PDF文件路径*/public static void rotate(String sourceFile, String targetFile) {leftRotate(sourceFile, targetFile);}

3、指定页面旋转

上面的实现是将所有的PDF文件都旋转,但是有的时候,可能只想旋转指定的页码,而其余的保持不变,可以采用重载 rotate() 方法来实现指定页码旋转。

    /*** 旋转PDF文件* @param sourceFile 源PDF文件路径* @param targetFile 目标PDF文件路径* @param angle 旋转角度* @param rotatedPageNums 需要旋转的页码*/public static void rotate(String sourceFile, String targetFile, int angle, List<Integer> rotatedPageNums) {PdfReader reader = null;Document document = null;FileOutputStream outputStream = null;try {// 读取源文件reader = new PdfReader(sourceFile);// 创建新的文档document = new Document();// 创建目标PDF文件outputStream = new FileOutputStream(targetFile);PdfCopy pdfCopy = new PdfSmartCopy(document, outputStream);// 获取源文件的页数int pages = reader.getNumberOfPages();document.open();PdfDictionary pdfDictionary;// 注意此处的页码是从1开始for (int page = 1; page <= pages; page++) {pdfDictionary = reader.getPageN(page);if (null == rotatedPageNums || rotatedPageNums.isEmpty()) {pdfDictionary.put(PdfName.ROTATE, new PdfNumber(angle));} else if (rotatedPageNums.contains(page)) {pdfDictionary.put(PdfName.ROTATE, new PdfNumber(angle));}pdfCopy.addPage(pdfCopy.getImportedPage(reader, page));}} catch (IOException | DocumentException e) {e.printStackTrace();} finally {if (reader != null) {reader.close();}if (document != null) {document.close();}if (outputStream != null) {try {outputStream.flush();outputStream.close();} catch (IOException e) {e.printStackTrace();}}}}

这个方法多了一个参数 List<Integer> rotatedPageNums,传递的是需要旋转的页码,比如说需要旋转1、3、5页,那么可以这样调用:

PdfUtils.rotate("D:\\Test\\test.pdf", "D:\\Test\\test_out.pdf", 90, Arrays.asList(1, 3, 5));

如果连续旋转某些页面,比如从10-60,如果使用上面的方法调用的话,那么参数就比较多了,这个时候,又可以重载一个方法,来根据起始页码和结束页码实现旋转,具体代码如下:

    /*** 旋转PDF文件* @param sourceFile 源PDF文件路径* @param targetFile 目标PDF文件路径* @param angle 旋转角度* @param fromPageNum 起始页码* @param toPageNum 结束页码*/public static void rotate(String sourceFile, String targetFile, int angle, int fromPageNum, int toPageNum) {PdfReader reader = null;Document document = null;FileOutputStream outputStream = null;try {// 读取源文件reader = new PdfReader(sourceFile);// 创建新的文档document = new Document();// 创建目标PDF文件outputStream = new FileOutputStream(targetFile);PdfCopy pdfCopy = new PdfSmartCopy(document, outputStream);// 获取源文件的页数int pages = reader.getNumberOfPages();document.open();PdfDictionary pdfDictionary;// 注意此处的页码是从1开始for (int page = 1; page <= pages; page++) {pdfDictionary = reader.getPageN(page);// 如果页面是在起始页码和结束页码之间的,则进行旋转if (page >= fromPageNum && page <= toPageNum) {pdfDictionary.put(PdfName.ROTATE, new PdfNumber(angle));}pdfCopy.addPage(pdfCopy.getImportedPage(reader, page));}} catch (IOException | DocumentException e) {e.printStackTrace();} finally {if (reader != null) {reader.close();}if (document != null) {document.close();}if (outputStream != null) {try {outputStream.flush();outputStream.close();} catch (IOException e) {e.printStackTrace();}}}}

此时就可以根据起始结束页码来旋转了,如下:

PdfUtils.rotate("D:\\Test\\test.pdf", "D:\\Test\\test_out.pdf", 90, 10, 60);

4、旋转所有横版

假如一个PDF文件中既有横版,又有竖版,这个时候希望把所有的横版都转换为竖版,上面已有的方法是满足不了的,可以定义新的方法,如下:

    /*** 旋转PDF文件中的所有横版* @param sourceFile 源PDF文件路径* @param targetFile 目标PDF文件路径* @param angle 旋转角度*/public static void rotateHorizontal(String sourceFile, String targetFile, int angle) {PdfReader reader = null;Document document = null;FileOutputStream outputStream = null;try {// 读取源文件reader = new PdfReader(sourceFile);// 创建新的文档document = new Document();// 创建目标PDF文件outputStream = new FileOutputStream(targetFile);PdfCopy pdfCopy = new PdfSmartCopy(document, outputStream);// 获取源文件的页数int pages = reader.getNumberOfPages();document.open();PdfDictionary pdfDictionary;// 注意此处的页码是从1开始for (int page = 1; page <= pages; page++) {pdfDictionary = reader.getPageN(page);// 根据页面的宽度float pageWidth = reader.getPageSize(page).getWidth();if (pageWidth > 600F) {pdfDictionary.put(PdfName.ROTATE, new PdfNumber(angle));}pdfCopy.addPage(pdfCopy.getImportedPage(reader, page));}} catch (IOException | DocumentException e) {e.printStackTrace();} finally {if (reader != null) {reader.close();}if (document != null) {document.close();}if (outputStream != null) {try {outputStream.flush();outputStream.close();} catch (IOException e) {e.printStackTrace();}}}}

旋转所有的横版,是根据页面的宽度进行,横版的宽度比竖版的宽,而对于横版A4版面PDF文件,其宽高分别为841.9和595.3。

5、旋转所有竖版

上面实现了旋转所有的横版,同理,可能也会遇到需要旋转所有的竖版的需求,代码如下:

    /*** 旋转PDF文件中的所有竖版* @param sourceFile 源PDF文件路径* @param targetFile 目标PDF文件路径* @param angle 旋转角度*/public static void rotateVertical(String sourceFile, String targetFile, int angle) {PdfReader reader = null;Document document = null;FileOutputStream outputStream = null;try {// 读取源文件reader = new PdfReader(sourceFile);// 创建新的文档document = new Document();// 创建目标PDF文件outputStream = new FileOutputStream(targetFile);PdfCopy pdfCopy = new PdfSmartCopy(document, outputStream);// 获取源文件的页数int pages = reader.getNumberOfPages();document.open();PdfDictionary pdfDictionary;// 注意此处的页码是从1开始for (int page = 1; page <= pages; page++) {pdfDictionary = reader.getPageN(page);// 根据页面的高度float pageHeight = reader.getPageSize(page).getHeight();if (pageHeight > 600F) {pdfDictionary.put(PdfName.ROTATE, new PdfNumber(angle));}pdfCopy.addPage(pdfCopy.getImportedPage(reader, page));}} catch (IOException | DocumentException e) {e.printStackTrace();} finally {if (reader != null) {reader.close();}if (document != null) {document.close();}if (outputStream != null) {try {outputStream.flush();outputStream.close();} catch (IOException e) {e.printStackTrace();}}}}

如果一个PDF文件同时存在A4横版和A4竖版,那么竖版的高度比横版的高,并且竖版的高度值为横版的宽度,这个时候横竖版的宽高分别如下:

  • 横版:841.9 x 595.3
  • 竖版:595.3 x 841.9

6、测试验证

现在使用上面的旋转方法把一个PDF中的第2页转换为竖版,测试代码如下:

package com.magic.itextpdf;import java.util.Collections;public class Test {public static void main(String[] args) {PdfUtils.rotate("D:\\Test\\test.pdf", "D:\\Test\\test_2.pdf", 90, 2, 2);}
}

原始PDF和转换后的PDF对比如下:

使用itextpdf实现横板PDF文件与竖版PDF文件的相互转换相关推荐

  1. 通过itextpdf操作PDF,动态向PDF文件最后一页添加图片

    通过itextpdf操作PDF,向PDF文件最后一页添加图片(缩放图片并判断最后一页是否能放下图片) 本人第一篇博客,哈哈!第一次接触itextpdf,想实现将图片向PDF尾部追加(判断原页面使用情况 ...

  2. PDF解决方案(2)--文件转PDF

    相关专题链接: PDF解决方案(1)--文件上传 PDF解决方案(2)--文件转PDF PDF解决方案(3)--PDF转SWF PDF解决方案(4)--在线浏览 前言:上一篇中讲到的文件上传,文件上传 ...

  3. POI根据模板导出word文件,以及word转PDF,PDF转图片再插入PDF中(防止PDF被修改)

    POI操作word和PDF POI根据模板导出word文件 word转PDF PDF转图片再插入PDF中(防止PDF被修改) POI根据模板导出word文件 一.制作word模版,${xxxx}是一会 ...

  4. 自动生成PDF文件(Java通过PDF模板自动生成PDF)

    思路: 1.创建PDF模板(先创建对应的excel文件,创建好后另存为PDF文件)即可. 2.使用Adobe Acrobat DC工具打开PDF文件,设置自己想要替换的内容. 3.maven项目引入依 ...

  5. java pdf工具类_Java PDF工具类(一)| 使用 itextpdf 根据PDF模板生成PDF(文字和图片)...

    Java PDF工具类(一)| 使用 itextpdf 根据设置好的PDF模板填充PDF(文字和图片) 相关文章: Java PDF工具类(二)| 使用 wkhtmltox 实现 HTML转PDF(文 ...

  6. Java中使用ItextPdf工具根据PDF合同模板填充pdf

    Java中使用itextPdf工具根据PDF合同模板填充内容 设置PDF合同模板的文本域 导入itextPdf的pom依赖 编写生成填充pdf代码 1:设置PDF合同模板的文本域 ​ 设置PDF文本域 ...

  7. java word 转pdf or 直接生成pdf文件

    1.需要引入的maven坐标 <!-- https://mvnrepository.com/artifact/com.itextpdf/kernel --><dependency&g ...

  8. 用java实现,office文件转成pdf文件

    实现环境:要求可以在linux环境下运行,开源插件 , 跨平台 以下有五种方法:  结论: office不支持跨平台, aspose收费, 基于pio+itext转换后会严重失真, 基于libreOf ...

  9. 在Springboot环境下,使用Docx4J + Freemarker 完成word docx文件生成与Pdf文件转换(附带兼容linux字体问题处理办法)

    在Springboot环境下,使用Docx4J + Freemarker 完成word docx文件生成与Pdf文件转换(附带兼容linux字体问题处理办法) 前言 效果展示 正文 docx文件模板创 ...

最新文章

  1. tushare 金融数据获取(R语言版)
  2. Keras实现mode.fit和model.fit_generator比较
  3. 自动化机器学习(三)神经网络架构搜索综述(NAS)简述
  4. 深入浅出,ARCore开发原理
  5. boost::pfr::tuple_size_v相关的测试程序
  6. 微信小程序--页面传参
  7. 批量替换文件夹下所有文件的内容
  8. 传统form表单提交方式的文件上传与文件存储
  9. 提高篇 第三部分 图论 第4章 差分约束系统
  10. 连接linux工具有哪些_推荐 10 个不错的网络监视工具,值得收藏
  11. js最新手机号码、身份证正则表达式
  12. Spring、SpringMVC和Springboot的区别
  13. AI加持,计算机要拥有嗅觉了;GPU终于可用于Google Compute Engine | AI开发者头条
  14. asp.net创建自定义排序用户界面
  15. mysql8多表连接_MySQL 多个表的 连接
  16. 我们不应该歧视任何的编程语言,因为他们都是萌娘
  17. python立体图形,python中如何画三维的图形?
  18. 牛客网、赛码网javascript在线编程的输入输出
  19. 如何在GitHub上建立一个自己的网站
  20. 数字图像处理第八章----图像压缩

热门文章

  1. 三闯港交所,主打性价比的乡村基如何夺魁“中式快餐第一股”?
  2. git报 “The stash entry is kept in case you need it again“ 错误解析
  3. 如何解决网络运营商对4G网络的限速?
  4. Spark中资源与任务的关系
  5. 如何解决在线医疗语音问诊的技术难题 | 以眩晕问诊为例
  6. c#的decode用法
  7. 我的ROS学习之路——动起来的小海龟
  8. 简单几步实现RTMP直播
  9. 项目经理必备工具之Project软件操作秘籍︱高远华信公司总经理张会斌
  10. 发送手机短信验证码-后端、前端(验证码倒计时)