现在有这样的一个需求:
有一个几十页的PDF文件,现在需要从中拆分出指定的页码,然后生成一个新的PDF文件。这个时候,可以使用开源的 itextpdf 库来实现,
itextpdf
的官方 github 地址为:https://github.com/itext/itextpdf.下面通过具体的代码来演示。
1、引入依赖
目前
itextpdf
最新版本为 5.5.13.3
,可以在 https://search.maven.org/ 网站进行搜索。
com.itextpdf
itextpdf
5.5.13.3
2、代码实现
2.1 指定页码抽取
package com.magic.itextpdf;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfSmartCopy;
/**
* PDF工具类
*/
public class PdfUtils {/**
* 抽取PDF文件
* @param sourceFile 源PDF文件路径
* @param targetFile 目标PDF文件路径
* @param extractedPageNums 需要抽取的页码
*/
public static void extract(String sourceFile, String targetFile, List extractedPageNums) {
Objects.requireNonNull(sourceFile);
Objects.requireNonNull(targetFile);
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();
// 注意此处的页码是从1开始
for (int page = 1;
page <= pages;
page++) {
// 如果是指定的页码,则进行复制
if (extractedPageNums.contains(page)) {
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();
}
}
}
}
}
extract()
方法有三个参数,分包是源PDF文件路径、目标PDF文件路径和指定页码,其中指定页码采用List集合进行传递,比如需要抽取第1页,可以像下面这样调用PdfUtils.extract("D:\\Test\\test.pdf", "D:\\Test\\test_out.pdf", Collections.singletonList(1));
如果同时需要抽取多页,比如1、3、5页,那么可以这样调用
PdfUtils.extract("D:\\Test\\test.pdf", "D:\\Test\\test_out.pdf", Arrays.asList(1, 3, 5));
当然,如果一个PDF有一百多页,现在需要抽取10-60页,如果还是像上面一样传递参数,则会非常麻烦,此时就可以重载一个方法,实现传递起始页码和结束页码来抽取了。
2.2 起始结束页码抽取
重载
extract
方法,具体的代码如下:/**
* 抽取PDF文件
* @param sourceFile 源PDF文件路径
* @param targetFile 目标PDF文件路径
* @param fromPageNum 起始页码
* @param toPageNum 结束页码
*/
public static void extract(String sourceFile, String targetFile, int fromPageNum, int toPageNum) {
Objects.requireNonNull(sourceFile);
Objects.requireNonNull(targetFile);
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();
// 注意此处的页码是从1开始
for (int page = 1;
page <= pages;
page++) {
if (page >= fromPageNum && page <= toPageNum) {
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();
}
}
}
}
对于连续页码而言,这个方式更加简单,比如要抽取 10-60页,那么可以这样调用
PdfUtils.extract("D:\\Test\\test.pdf", "D:\\Test\\test_out.pdf", 10, 60);
3、测试验证
现在有一个总共2页的PDF文件,分别使用上面的方法进行抽取拆分第1页,代码如下:
package com.magic.itextpdf;
import java.util.Collections;
public class Test {public static void main(String[] args) {
PdfUtils.extract("D:\\Test\\test.pdf", "D:\\Test\\test_out_1.pdf", Collections.singletonList(1));
PdfUtils.extract("D:\\Test\\test.pdf", "D:\\Test\\test_out_2.pdf", 1, 1);
}
}
运行后,分别生成了
test_out_1.pdf
和 test_out_2.pdf
两个新文件,新文件都是源文件的第一页。4、其他方法
如果只是处理单个PDF文件的话,那么可以使用WPS的打印功能,或者Chrome浏览器的打印功能都可以实现,非常方便。
4.1 WPS打印拆分
文章图片
4.2 Chrome打印拆分 【使用itextpdf提取PDF文件中的任意页码】
文章图片
推荐阅读
- 使用itextpdf实现横板PDF文件与竖版PDF文件的相互转换
- Java后端|Springboot集成Elasticsearch,爬虫爬取数据,实现简单搜索功能
- 【Java面试手册-基础篇】能否声明main()方法为private或protected,或者不用访问修饰符()
- Java后端常见面试题总结
- iText throws ArrayIndexOutOfBoundsException
- IDEA配置Maven教程
- IDEA写jsp代码报错,但是正常运行解决
- 踩坑-Tomcat(servlet)在启动(加载)是执行两次
- IDEA配置Tomcat以及环境