In the actual development process, the following scenarios may be encountered:
- A PDF file that is all vertical, and now it needs to be converted to a horizontal PDF file;
- A PDF file that is all vertical, now you need to convert the specified page to a horizontal PDF file;
- There are both horizontal and vertical versions in a PDF file, and now all horizontal versions need to be converted to vertical versions;
- There are both horizontal and vertical versions in a PDF file, and now all vertical versions need to be converted to horizontal versions;
These requirements can be achieved by using the itextpdf
open source library, which will be demonstrated by code below.
It should be noted that the conversion here is only the rotation of the PDF layout, not the rotation of the page content. If you need to rotate the text on the page when the layout is rotated, the following method may not be applicable.
1. Introduce dependencies
Currently itextpdf
the latest version is 5.5.13.3
, which can be searched at https://search.maven.org/ .
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.3</version>
</dependency>
2. Code implementation
Whether it is a horizontal PDF to a vertical PDF, or a vertical PDF to a horizontal PDF, it is actually a rotation problem. A vertical PDF is rotated 90 degrees clockwise or counterclockwise, and the result is a horizontal 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();
}
}
}
}
}
The rotation angle here angle
must be a multiple of 90. If it is any other angle, it is invalid. With the rotation method, we can define some basic methods, such as clockwise rotation (right rotation), counterclockwise rotation (left rotation) and vertical flip , which will be more convenient to use.
(1) Rotate clockwise (rotate 90 to the right)
/**
* 右旋转PDF文件90度
* @param sourceFile 源PDF文件路径
* @param targetFile 目标PDF文件路径
*/
public static void rightRotate(String sourceFile, String targetFile) {
rotate(sourceFile, targetFile, -90);
}
(2) Rotate counterclockwise (rotate 90 to the left)
/**
* 左旋转PDF文件90度
* @param sourceFile 源PDF文件路径
* @param targetFile 目标PDF文件路径
*/
public static void leftRotate(String sourceFile, String targetFile) {
rotate(sourceFile, targetFile, 90);
}
(3) Vertical (rotate 180)
/**
* 翻转PDF文件
* @param sourceFile 源PDF文件路径
* @param targetFile 目标PDF文件路径
*/
public static void filp(String sourceFile, String targetFile) {
rotate(sourceFile, targetFile, 180);
}
In some fixed scenarios, the rotation may refer specifically to counterclockwise rotation. At this time, we can also overload the rotate()
method, and use the leftRotate()
method by default, as follows:
/**
* 旋转PDF文件
* @param sourceFile 源PDF文件路径
* @param targetFile 目标PDF文件路径
*/
public static void rotate(String sourceFile, String targetFile) {
leftRotate(sourceFile, targetFile);
}
3. Specify page rotation
The above implementation is to rotate all PDF files, but sometimes, you may only want to rotate the specified page number, while the rest remain unchanged, you can use the overload rotate()
method to achieve the specified page number rotation.
/**
* 旋转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();
}
}
}
}
This method has one more parameter List<Integer> rotatedPageNums
, which passes the page number that needs to be rotated. For example, if you need to rotate pages 1, 3, and 5, you can call it like this:
PdfUtils.rotate("D:\\Test\\test.pdf", "D:\\Test\\test_out.pdf", 90, Arrays.asList(1, 3, 5));
If you continuously rotate some pages, such as from 10-60, if you use the above method to call, then there are more parameters. At this time, you can overload a method to realize the rotation according to the starting page number and the ending page number. Specifically code show as below:
/**
* 旋转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();
}
}
}
}
At this point, you can rotate according to the starting and ending page numbers, as follows:
PdfUtils.rotate("D:\\Test\\test.pdf", "D:\\Test\\test_out.pdf", 90, 10, 60);
4. Rotate all horizontal versions
If a PDF file has both horizontal and vertical versions, at this time, you want to convert all horizontal versions to vertical versions. The existing methods above are not enough. You can define new methods, as follows:
/**
* 旋转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();
}
}
}
}
Rotating all the horizontal versions is done according to the width of the page. The width of the horizontal version is wider than that of the vertical version, and for the horizontal version A4 layout PDF file, the width and height are 841.9 and 595.3 respectively.
5. Rotate all vertical versions
The above realizes the rotation of all the horizontal versions. Similarly, it may also encounter the need to rotate all the vertical versions. The code is as follows:
/**
* 旋转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();
}
}
}
}
If a PDF file has both A4 horizontal and A4 vertical versions, the height of the vertical version is higher than that of the horizontal version, and the height of the vertical version is the width of the horizontal version. At this time, the width and height of the horizontal and vertical versions are as follows:
- Horizontal: 841.9 x 595.3
- Vertical: 595.3 x 841.9
6. Test verification
Now use the above rotation method to convert page 2 in a PDF to vertical. The test code is as follows:
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);
}
}
The original PDF and the converted PDF are compared as follows:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。