spire.pdf + pdf + 表格
背景: 近需要处理一批PDF文本,里面内容都是文本形式的表格数据,需要按指定规则将一些数据提取出来入库。网上看了一些开源的工具,大部分无法处理复杂的表格数据,尤其是涉及到单个表格内部出现换行时,数据抽取基本错乱。后续通过demo发现spire.pdf提供的jar包实现效果较好,虽然有一些BUG,但相较于其他组件,更符合实际项目需求。下面应用概述该组件实现表格抽取的过程及注意事项。
博客内容精选:
1、Servlet请求体重复读&修改新姿势
2、根据请求获取后端接口详情
3、封装Springboot项目的starter-sdk新方式
4、Springboot全局处理完整版
5、itextpdf读取文本时上下行位置错乱
6、JAVA读取PDF表格内容
1、POM依赖引入
<repositories>
<repository>
<id>com.e-iceblue</id>
<url>http://repo.e-iceblue.cn/repository/maven-public/</url>
</repository>
</repositories>
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.pdf.free</artifactId>
<version>5.1.0</version>
</dependency>
注:相较于使用spire做文档转换有3页的限制,表格抽取目前没有明确限制篇数,自身需求也只需处理一两页内容。
2、样例代码
public static String getFormatTableData(String localFile) throws ExtractException {
PdfDocument pdf = new PdfDocument(localFile);
StringBuilder builder = new StringBuilder();
PdfTableExtractor extractor = new PdfTableExtractor(pdf);
try {
for (int pageIndex = 0; pageIndex < pdf.getPages().getCount(); pageIndex++) {
PdfTable[] tableLists = extractor.extractTable(pageIndex);
if (tableLists != null && tableLists.length > 0) {
for (PdfTable table : tableLists) {
for (int i = 0; i < table.getRowCount(); i++) {
for (int j = 0; j < table.getColumnCount(); j++) {
String text = table.getText(i, j);
if (StringUtils.isNotBlank(text)) {
//每一行,各字段间用|分开
builder.append(text).append("|");
}
}
if (builder.charAt(builder.length() - 1) == '|') {
builder.deleteCharAt(builder.length() - 1);
//使用$作为换行标识
builder.append("$");
}
}
}
}
}
} catch (Exception e) {
//可使用图片OCR等方式补救
} finally {
pdf.close();
}
return StringUtils.deleteWhitespace(builder.toString());
说明:
1、数据抽取的基础要求就是各字段内容互不影响,尤其是单元格内换行导致上线行内容错乱
2、抽取字段间需要有明确的起始标记,此处以|分割字段值,以$分割行
3、抽取时另需考虑值为空或非法格式等特殊场景
注意事项:
1、spire.pdf不能读取所有pdf文本中的表格,部分场景直接报错(个人不涉及)
2、spire.pdf依赖包模块化基础较差,单个包就达到50M,远超其他组件包
3、spire.pdf只能识读PDF中的表格数据,表格外内容无法处理(图片OCR一般会兼容)
4、spire.pdf免费版本维护周期较大,已知BUG有行尾有标点符号,则该标点符号会丢失,数据内容就会错乱,有些场景造成的问题很大。
追加:表格外内容无法读取及行尾标点符号丢失问题,解决方法将在其他博客说明