Java文件操作系列[1]——PDFBox实现分页提取PDF文本
需求:用java分页提取PDF文本。
PDFBox是一个很好的可以满足上述需求的开源工具。
1.PDF文档结构
要解析PDF文本,我们首先要了解PDF文件的结构。
关于PDF文档,最重要的几点:
一,PDF文档内容比较复杂,比如有纯文本(可以提取出其中的文字,可以用PDF软件中的“复制”功能)、图片(无法使用PDF软件中的“复制”功能)、表单、视频、音频等,总之形式比较复杂;
二,PDF文件采用二进制流与纯文字混合的编码模式,并且没有采用 Unicode 等标准字符编码方式,其字符编码采用 Adobe 公司内建的编码表( CMap),这使得对 PDF 的处理更加困难;
三,PDF有自己的文件结构:文件头,对象集合,交叉引用表,结尾(准确地说,这是PDF文档的物理结构,还有逻辑结构,详情可以点击查看这篇博文)。
2.PDFBox是个什么玩意
- 授权协议: Apache
- 开发语言: Java
- 操作系统: 跨平台
- 官网:http://pdfbox.apache.org/
3.PDFBox能干啥
- 从PDF提取文本
- 合并PDF文档
- PDF 文档加密与解密
- 与Lucene搜索引擎的集成
- 填充PDF/XFDF表单数据
- 从文本文件创建PDF文档
- 从PDF页面创建图片
- 打印PDF文档
4.准备工作
再次声明,本demo功能是提取PDF文本(中文文本验证也通过)。
1) 下载好jar包(3个):
a.fontbox-2.0.0-RC2.jar
b.pdfbox-2.0.0-RC2.jar
c.pdfbox-app-2.0.0-RC2.jar
下载地址1:我的下载
下载地址2:官网下载
2) myeclipse或eclipse。
5.开始编程
新建一个项目,写入下面的源码:
package com.primeton.pdfbox; import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer; import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper; /**
* PDFBox解析PDF文本实现
* @author MrChen
*
*/ public class PDFReader {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
PDFReader pdfReader = new PDFReader();
System.out.println("E:\\AndroidStudio.pdf");
try {
// 取得E盘下的SpringGuide.pdf的内容
System.out.println("开始提取");
File file = new File("E:\\AndroidStudio.pdf");
System.out.println("文件绝对路径为:"+file.getAbsolutePath());
pdfReader.readFdf(file);
System.out.println("提取结束");
} catch (Exception e) {
e.printStackTrace();
}
} public void readFdf(File pdfFile) throws Exception {
// 是否排序
boolean sort = false;
// 输入文本文件名称
String textFileName = null;
// 编码方式
String encoding = "UTF-8";
// 开始提取页数
int startPage = 1;
// 结束提取页数
int endPage = 3;
// 文件输入流,生成文本文件
Writer output = null;
// 内存中存储的PDF Document
PDDocument document = null; File outputFile = null;
try { // 从本地装载文件
//注意参数已不是以前版本中的URL.而是File。
System.out.println("开始装载文件"+pdfFile.getName());
document = PDDocument.load(pdfFile);
if (pdfFile.getName().length() > 4) {
textFileName = pdfFile.getName().substring(0, pdfFile.getName().length() - 4) + ".txt";
outputFile = new File(pdfFile.getParent(),textFileName);
System.out.println("新文件绝对路径为:"+outputFile.getAbsolutePath()); }
System.out.println("装载文件结束"); System.out.println("开始写到txt文件中");
// 文件输入流,写入文件倒textFile
output = new OutputStreamWriter(new FileOutputStream(outputFile),encoding);
System.out.println("写入txt文件结束");
// PDFTextStripper来提取文本
PDFTextStripper stripper = null;
stripper = new PDFTextStripper();
// 设置是否排序
stripper.setSortByPosition(sort);
// 设置起始页
stripper.setStartPage(startPage);
// 设置结束页
stripper.setEndPage(endPage);
// 调用PDFTextStripper的writeText提取并输出文本
System.out.println("开始调用writeText方法");
stripper.writeText(document, output);
System.out.println("调用writeText方法结束");
}catch (Exception e) {
e.printStackTrace();
}finally {
if (output != null) {
// 关闭输出流
output.close();
}
if (document != null) {
// 关闭PDF Document
document.close();
}
}
}
}
解析PDF文本
有很多打桩的语句,可以自行去除。
同时,本程序也可以提取中文信息。
6.遇到的问题及解决方案
1)一开始使用的并不是PDFBox2.0版本,而是1.8版(2.0版本还是实验版本,故选用了早期的1.8版本)。但选择1.8版本,使用PDDocument.load(String)方法时,老是出现这个异常——“java.io.IOException: Push back buffer is full”。
解决方案:上述问题困扰了笔者很久。笔者为此重新复习了IO和NIO的一些知识,并查阅了PDFBox英文API文档(1.8版本),均无解决思路。后大量查阅资料得知,这可能是1.8版本出现的bug,2.0版本修复了此bug。笔者将jar包改为2.0版本,果然就好了。需要提醒的是,2.0版本PDDocument.load()方法参数为File类型,不再是String类型。可以参阅官方API文档。
Java文件操作系列[1]——PDFBox实现分页提取PDF文本的更多相关文章
- Java文件操作系列[3]——使用jacob操作word文档
Java对word文档的操作需要通过第三方组件实现,例如jacob.iText.POI和java2word等.jacob组件的功能最强大,可以操作word,Excel等格式的文件.该组件调用的的是操作 ...
- Java文件操作系列[2]——使用JXL操作Excel文件
由于java流无法实现对Excel文件的读写操作,因此在项目中经常利用第三方开源的组件来实现.支持Excel文件操作的第三方开源组件主要有Apache的POI和开源社区的JXL. 总体来说,二者的区别 ...
- Java文件操作源码大全
Java文件操作源码大全 1.创建文件夹 52.创建文件 53.删除文件 54.删除文件夹 65.删除一个文件下夹所有的文件夹 76.清空文件夹 87.读取文件 88.写入文件 99.写入随机文件 9 ...
- Java 文件操作大全
Java 文件操作大全 //1.创建文件夹 //import java.io.*; File myFolderPath = new File(str1); try { if (!myFolderPat ...
- JAVA文件操作类和文件夹的操作代码示例
JAVA文件操作类和文件夹的操作代码实例,包括读取文本文件内容, 新建目录,多级目录创建,新建文件,有编码方式的文件创建, 删除文件,删除文件夹,删除指定文件夹下所有文件, 复制单个文件,复制整个文件 ...
- java文件操作(普通文件以及配置文件的读写操作)
转自:java文件操作(普通文件以及配置文件的读写操作) 读取普通文件 : /** * xiangqiao123欢迎你 如果对代码有疑问可以加qq群咨询:151648295 * * 读取MyFile文 ...
- 14、Java文件操作stream、File、IO
1.文件操作涉及到的基本概念 File File类 是文件操作的主要对象中文意义就是 文件 顾名思意 万物皆文件,在计算上看到的所有东西都是文件保存,不管是你的图片.视频.数据库数据等等都是按照基本的 ...
- Java文件操作API功能与Windows DOS命令和Linux Shell 命令类比
Java文件操作API功能与Windows DOS命令和Linux Shell 命令类比: Unix/Linux (Bash) Windows(MS-DOS) Java 进入目录 cd cd - 创建 ...
- Java文件操作与输入输出流
文件操作 package ch15; import java.io.*; /** * Created by Jiqing on 2016/12/28. */ public class FileTest ...
随机推荐
- 子组件索引$refs
$refs只在组件渲染完成之后才填充,并且它是非响应式的,它仅仅作为一个直接访问访问子组件的应急方案-----应当避免的模板中或者计算属性中使用$refs
- 树莓派也跑Docker和.NET Core
树莓派是什么 树莓派就是一个卡片大小的迷你电脑. 安装系统 有了电脑,我们当然得先安装系统. 系统下载 https://www.raspberrypi.org/downloads/raspbian/ ...
- export default 和 export 的使用方式(六)
一:ES6 的导入模块方式和暴露对象方式: ES6 中导入模块使用:import 模块名称 from '模块标识符':import '表示路径': 在 ES6 中使用 export default 和 ...
- nginx+vue实现项目动静分离
一般的企业都会采用前后端分离的方式来开发.部署项目,这样做的好处是更好的让前后台各司其职.另外也由于nginx是一个轻量级的静态资源服务器,其高并发也是其优点之一.这样可以减轻双方服务器的压力,同时又 ...
- Tomcat - 怎么控制某个类或者包下的日志打印级别
问题与分析 Tomcat是使用自己的日志实现tomcat-juli.jar来打印日志信息的,日志会被打印到catalina.out里,除去你在项目里自己使用的日志框架外,由System.out,Sys ...
- vi/vim打开文件提示Found a swap file by the name
问题分析 有一次在远程连接主机时,用vi打开文件my.ini却提示:Found a swap file by the name ".my.ini.swp".百度了下才知道,原来在使 ...
- 关于 prototype与__proto__ (用到的时候再看一次 加深理解)
链接顺序: 1. https://blog.csdn.net/ligang2585116/article/details/53522741 2.https://www.jianshu.com/p/80 ...
- [題解](最小生成樹)luogu_P1265
首先考虑最小生成树的模型,唯一不同的是第二种情形. 即“三个或三个以上的城市申请修建的公路成环” 考虑该情形,因为修路的申请是申请离它最近的城市,所以上述条件实质上为 “存在三个或三个以上的城市,他们 ...
- C# 面向对象之继承后初始化顺序
使用继承之后当我们初始化一个子类时子类的初始化顺序为: (1)初始化类的实例字段 (2)调用基类的构造函数,如果没有指明基类则调用System.Object的构造函数; (3)调用子类的构造函数
- BZOJ1053(数学结论进行剪枝搜索)
Description 对于任何正整数x,其约数的个数记作g(x).例如g(1)=1.g(6)=4.如果某个正整数x满足:g(x)>g(i) 0<i<x,则称x为反质数.例如,整数1 ...