共计 3628 个字符,预计需要花费 10 分钟才能阅读完成。
当初有这样的一个需要:
有一个几十页的 PDF 文件,当初须要从中拆分出指定的页码,而后生成一个新的 PDF 文件。
这个时候,能够应用开源的 itextpdf 库来实现,itextpdf
的官网 github 地址为:https://github.com/itext/itextpdf.
上面通过具体的代码来演示。
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、代码实现
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<Integer> 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 打印拆分
正文完