PDFBox的使用——分页提取PDF文本

需求:用java分页提取PDF文本。

PDFBox是一个很好的可以满足上述需求的开源工具。

1.PDF文档结构

要解析PDF文本,我们首先要了解PDF文件的结构。

关于PDF文档,最重要的几点:

一,PDF文档内容比较复杂,比如有纯文本(可以提取出其中的文字,可以用PDF软件中的“复制”功能)、图片(无法使用PDF软件中的“复制”功能)、表单、视频、音频等,总之形式比较复杂;

二,PDF文件采用二进制流与纯文字混合的编码模式,并且没有采用 Unicode 等标准字符编码方式,其字符编码采用 Adobe 公司内建的编码表( CMap),这使得对 PDF 的处理更加困难;

三,PDF有自己的文件结构:文件头,对象集合,交叉引用表,结尾(准确地说,这是PDF文档的物理结构,还有逻辑结构,详情可以点击查看这篇博文)。

2.PDFBox是个什么玩意

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

下载地址:进官网一看便知(注意版本)。

2) myeclipse或eclipse。

5.开始编程

新建一个项目,写入下面的源码:

  1 package com.primeton.pdfbox;
  2
  3 import java.io.File;
  4 import java.io.FileOutputStream;
  5 import java.io.OutputStreamWriter;
  6 import java.io.Writer;
  7
  8 import org.apache.pdfbox.pdmodel.PDDocument;
  9 import org.apache.pdfbox.text.PDFTextStripper;
 10
 11
 12 /**
 13  * PDFBox解析PDF文本实现
 14  * @author MrChen
 15  *
 16  */
 17
 18 public class PDFReader {
 19     /**
 20       * @param args
 21       */
 22      public static void main(String[] args) {
 23       // TODO Auto-generated method stub
 24       PDFReader pdfReader = new PDFReader();
 25       System.out.println("E:\\AndroidStudio.pdf");
 26       try {
 27            // 取得E盘下的SpringGuide.pdf的内容
 28            System.out.println("开始提取");
 29            File file = new File("E:\\AndroidStudio.pdf");
 30            System.out.println("文件绝对路径为:"+file.getAbsolutePath());
 31            pdfReader.readFdf(file);
 32            System.out.println("提取结束");
 33       } catch (Exception e) {
 34            e.printStackTrace();
 35       }
 36      }
 37
 38      public void readFdf(File pdfFile) throws Exception {
 39           // 是否排序
 40           boolean sort = false;
 41           // 输入文本文件名称
 42           String textFileName = null;
 43           // 编码方式
 44           String encoding = "UTF-8";
 45           // 开始提取页数
 46           int startPage = 1;
 47           // 结束提取页数
 48           int endPage = 3;
 49           // 文件输入流,生成文本文件
 50           Writer output = null;
 51           // 内存中存储的PDF Document
 52           PDDocument document = null;
 53
 54           File outputFile = null;
 55           try {
 56
 57                // 从本地装载文件
 58                //注意参数已不是以前版本中的URL.而是File。
 59                 System.out.println("开始装载文件"+pdfFile.getName());
 60                 document = PDDocument.load(pdfFile);
 61                 if (pdfFile.getName().length() > 4) {
 62                     textFileName = pdfFile.getName().substring(0, pdfFile.getName().length() - 4) + ".txt";
 63                     outputFile = new File(pdfFile.getParent(),textFileName);
 64                     System.out.println("新文件绝对路径为:"+outputFile.getAbsolutePath());
 65
 66
 67                 }
 68                 System.out.println("装载文件结束");
 69
 70
 71                System.out.println("开始写到txt文件中");
 72                // 文件输入流,写入文件倒textFile
 73                output = new OutputStreamWriter(new FileOutputStream(outputFile),encoding);
 74                System.out.println("写入txt文件结束");
 75                // PDFTextStripper来提取文本
 76                PDFTextStripper stripper = null;
 77                stripper = new PDFTextStripper();
 78                // 设置是否排序
 79                stripper.setSortByPosition(sort);
 80                // 设置起始页
 81                stripper.setStartPage(startPage);
 82                // 设置结束页
 83                stripper.setEndPage(endPage);
 84                // 调用PDFTextStripper的writeText提取并输出文本
 85                System.out.println("开始调用writeText方法");
 86                stripper.writeText(document, output);
 87                System.out.println("调用writeText方法结束");
 88           }catch (Exception e) {
 89                e.printStackTrace();
 90           }finally {
 91               if (output != null) {
 92                     // 关闭输出流
 93                     output.close();
 94                }
 95                if (document != null) {
 96                 // 关闭PDF Document
 97                 document.close();
 98                }
 99           }
100      }
101 }

有很多打桩的语句,可以自行去除。

6.遇到的问题及解决方案

1)一开始使用的并不是PDF2.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。改为2.0版本,果然就好了。需要提醒的是,2.0版本PDDocument.load()方法参数为File类型,不再是String类型。可以参阅官方API文档

时间: 2024-10-19 23:09:05

PDFBox的使用——分页提取PDF文本的相关文章

Delphi提取PDF文本

生成PDF的控件很多,但解析的不是太多,pdf Toolkit可以,但测试的第一个复杂的pdf就报告错误,并且汉字乱码,可能使用的版本或使用方法不对. 想起之前使用java调用的Apache名下的pdfBox库很好用,于是就用下载了pdfBox,使用Delphi来调用pdfBox解析pdf文本. 环境要求:java运行环境 pdfBox应用包:pdfbox-app-2.0.6.jar 这里使用了DOS命令行来解析,然后调用解析结果. 首先是执行DOS命令: procedure CheckResu

C# 提取PDF文本和图片

任务要求: 提取PDF文档中的文本 提取PDF文档中的图片 所需工具: Free Spire.PDF for .NET 4.3 (免费版) 实现代码: [示例 1 ]提取文本 using Spire.Pdf; using System; using System.IO; using System.Text; namespace ExtractText { class Program { static void Main(string[] args) { //加载文档 PdfDocument do

利用lucene和pdfBox对PDF文本进行内容的解析

/*  * 这段代码的功能是利用PDFBox.zip的包  * 利用lucene对PDF文本进行内容的解析  * 读取pdf文件的内容.然后重新的写入到同名的.txt文件中  * */ 结果截图: package pdfbox; import java.io.File; import java.io.FileOut... songtaste.com/user/10335914/infosongtaste.com/user/10335923/infosongtaste.com/user/10335

使用pdfbox分页保存pdf为图片

一.背景 pdfbox作为Apache开源的PDF操作工具,允许创建新的PDF文档,操作现有文档,以及从文档中提取内容的能力.Apache PDFBox还包括一些命令行实用工具.本文楼主主要介绍其中的PDF转图片的功能,有其他功能需求的同学,可以去官网读读文档,https://pdfbox.apache.org/ 二.准备工作 只需两个jar,pdfbox-2.0.7.jar,font-box-2.0.7.jar,当然用maven或gradle的同学,只需引入pdfbox就行了,依赖添加,楼主给

利用lucene对PDF文本进行内容的解析

/* * 这段代码的功能是利用PDFBox.zip的包 * 利用lucene对PDF文本进行内容的解析 * 读取pdf文件的内容.然后重新的写入到同名的.txt文件中  * */ 结果截图: package pdfbox; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.net.MalformedU

[转].NET下读取PDF文本

本文转自:http://blog.csdn.net/wangqiuyun/article/details/8548779 在.NET下读取PDF文本用到的类库主要有两个:PDFBox和iTextSharp. 先说PDFBox,这个类库据说功能很强大,本人在这只是简单介绍一下: 1.下载PDFBox 下载地址:http://sourceforge.net/projects/pdfbox/ 2.引用动态链接库 解压缩下载的PDFBox,找到其中的Bin目录,需要在项目中添加引用的dll文件有: IK

tika提取pdf信息异常

org.apache.tika.sax.WriteOutContentHandler$WriteLimitReachedException: Your document contained more than 100000 characters, and so your requested limit has been reached. To receive the full text of the document, increase your limit. (Text up to the l

迅捷pdf转换器——如何提取pdf中的图片

对于PDF文件的转换,我们最常遇到的情况是把PDF文件转换成Word格式的情况,不过在一些特殊的情况下,我们也会遇到一些特殊的转换工作,比如将pdf转换成jpg格式的文件就比较少见.PDF转换成图片,转换出来的就是一张张的图片,像是扫描过的PDF文件,文字和图片合并成的文件,单独将图片提取出来,只需要里面的图片要怎么办,最简单的方法:利用迅捷PDF转换器的“PDF图片获取”功能直接提取图片. 迅捷PDF转换器正式为上班一族打造的一款专业软件.软件采用OCR技术,它就像是一台袖珍型扫描仪,帮助用户

C# 提取PPT文本和图片的实现方案

在图文混排的文档中,我们可以根据需要将文档中的文字信息或者图片提取出来,通过C#代码可以提取Word和PDF文件中的文本和图片,那么同样的,我们也可以提取PPT幻灯片当中的文本和图片.本篇文档将讲述如何使用C#来实现提取PPT文本和图片的操作.首先也是需要安装组件Spire.Presentation,然后添加引用dll文件到项目中.下面是主要的代码步骤. 原文档: 1. 提取文本 步骤一:创建一个Presentation实例并加载文档 Presentation presentation = ne