java 读取pdf表格_在Java中使用tabula提取PDF中的表格数据

问题:如何将pdf文件中指定的表格数据提取出来?

尝试过的工具包有:pdfbox、tabula。最终选用tabula

两种工具的比较

pdfbox

其中,pdfbox能将pdf中的内容直接提取成String,代码片段:

public static voidreadPdf(String path) {try{

PDDocument document= PDDocument.load(newFile(path));

PDFTextStripper textStripper= newPDFTextStripper();

textStripper.setSortByPosition(true);

String text=textStripper.getText(document);

System.out.println(text);

document.close();

}catch(IOException e) {

e.printStackTrace();

}

}

但是如果遇到类似以下表格数据时,会有格式损失。无论中间有几个空的单元格,最终只会转为1个制表位字符(/t)。

fac2b2c6b6760bd38e809e42254fe2c2.png

input1.pdf

转换为String后是这样的:

06bc81919db5fbdb332938e4f1215386.png

pdfbox优点:方便快捷,使用简单,maven添加依赖后,使用PDFTextStripper.getText()即可提取文本。

pdfbox缺点:提取带有连续的空单元格的表格数据时,有格式丢失。

tabula

重点介绍tabula,虽然底层也是用pdfbox实现的,但是经过封装后的tabula更适合提取复杂格式的表格。

同样的pdf表格,转换为csv后,是这样的:

dbc643b7b3cecb4112a05192a1f6dafc.png

output1.csv

可以说是完美还原了。

继续尝试转换其他格式的表格。

d882e5a163e27a281a26478dedab3a74.png

input2.pdf

efccfaa2ee449ec29767bd88ca6b9085.png

output2.csv

16a8a261bd96043386114fcb51228af7.png

input3.pdf

cb8bed1f9b451e95e9f18680bfe25b55.png

output3.csv

测试结果:input1、input2基本可以还原,input3有部分差异,但通过BufferedReader读出来的值和pdf基本一致。

tabula的使用

1. 获取

1.1 获取源码

从https://github.com/tabulapdf/tabula-java下载tabula-java-master.zip,使用Eclipse将tabula打成jar包,然后将jar引用到自己的工程中。也可以直接下载tabula-1.0.2-jar-with-dependencies.jar到本地。

1.2 获取Windows客户端工具

从https://tabula.technology下载tabula-win-1.2.0.zip到本地,解压后运行tabula.exe即可使用。

2. 使用

2.1 解读README.md

## Usage Examples

`tabula-java` provides a command line application:

$ java -jar target/tabula-1.0.2-jar-with-dependencies.jar --help

usage: tabula [-a ] [-b ] [-c ] [-d] [-f

] [-g] [-h] [-i] [-l] [-n] [-o ] [-p ] [-r]

[-s ] [-t] [-u] [-v]

Tabula helps you extract tables from PDFs

-a,--areaPortion of the page to analyze. Accepts top,

left,bottom,right.

Example: --area 269.875,12.75,790.5,561.

If all values are between 0-100 (inclusive)

and preceded by '%', input will be taken as

% of actual height or width of the page.

Example: --area %0,0,100,50.

To specify multiple areas, -a option should

be repeated. Default is entire page

-b,--batchConvert all .pdfs in the provided directory.

-c,--columnsX coordinates of column boundaries. Example

--columns 10.1,20.2,30.3

-d,--debug Print detected table areas instead of

processing.

-f,--formatOutput format: (CSV,TSV,JSON). Default: CSV

-g,--guess Guess the portion of the page to analyze per

page.

-h,--help Print this help text.

-i,--silent Suppress all stderr output.

-l,--lattice Force PDF to be extracted using lattice-mode

extraction (if there are ruling lines

separating each cell, as in a PDF of an Excel

spreadsheet)

-n,--no-spreadsheet [Deprecated in favor of -t/--stream] Force PDF

not to be extracted using spreadsheet-style

extraction (if there are no ruling lines

separating each cell)

-o,--outfile Write output to instead of STDOUT.

Default: -

-p,--pagesComma separated list of ranges, or all.

Examples: --pages 1-3,5-7, --pages 3 or

--pages all. Default is --pages 1

-r,--spreadsheet [Deprecated in favor of -l/--lattice] Force

PDF to be extracted using spreadsheet-style

extraction (if there are ruling lines

separating each cell, as in a PDF of an Excel

spreadsheet)

-s,--passwordPassword to decrypt document. Default is empty

-t,--stream Force PDF to be extracted using stream-mode

extraction (if there are no ruling lines

separating each cell)

-u,--use-line-returns Use embedded line returns in cells. (Only in

spreadsheet mode.)

-v,--version Print version and exit.

其中一些附加参数可视情况选用。

-a:表示指定某个矩形区域,程序只会对此区域进行解析,类似pdfbox的PDFTextStripperByArea.addRegion()。-a后跟4个值,以逗号分隔。分别表示:

区域上边界到页面上边界的距离(或百分比)

区域左边界到页面左边界的距离(或百分比)

区域下边界到页面上边界的距离(或百分比)

区域右边界到页面左边界的距离(或百分比)

以%开头时表示百分比,比如-a %10,0,90,100。

-o:表示将结果输出到文件,后面跟文件路径

-p:表示提取指定页,后面跟数字,如果不指定则默认为1

-t:表示按流的方式提取,遇到合并单元格时使用

2.2 命令行运行

使用cmd命令行工具直接运行jar包

java -jar tabula-1.0.2.jar E:\tmp\input\input1.pdf -o E:\tmp\output\output1.csv

c5a301f2ce5d2833b73affd045746bbf.png

2.3 程序内调用

String cmd = "java -jar tabula-1.0.2.jar E:\tmp\input\input1.pdf -o E:\tmp\output\output1.csv";

Runtime.getRuntime().exec();


版权声明:本文为weixin_36440198原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。