使用 Java 提取 PDF 表格中的数据
Contents
[
Hide
]
从 PDF 中提取表格
使用 TableAbsorber 在每页上查找表格并遍历行、单元格、文本片段和文本段。
- 使用 Document 实例打开源 PDF。
- 遍历文档 Page 对象,因为表格是逐页检测的。
- 创建一个 TableAbsorber 对每页进行调用
visit(page)填充检测到的表格列表。 - 遍历检测到的 AbsorbedTable, AbsorbedRow, AbsorbedCell, TextFragment,以及
TextSegment对象。 - 从片段内容构建提取的行文本并打印表格数据。
public static void extractTablesFromPdf(Path inputFile) {
try (Document document = new Document(inputFile.toString())) {
for (Page page : document.getPages()) {
TableAbsorber absorber = new TableAbsorber();
absorber.visit(page);
for (AbsorbedTable table : absorber.getTableList()) {
System.out.println("Table");
for (AbsorbedRow row : table.getRowList()) {
StringBuilder rowText = new StringBuilder();
for (AbsorbedCell cell : row.getCellList()) {
if (rowText.length() > 0) {
rowText.append("|");
}
StringBuilder cellText = new StringBuilder();
for (TextFragment fragment : cell.getTextFragments()) {
StringBuilder fragmentText = new StringBuilder();
for (TextSegment segment : fragment.getSegments()) {
fragmentText.append(segment.getText());
}
if (cellText.length() > 0) {
cellText.append("|");
}
cellText.append(fragmentText);
}
rowText.append(cellText);
}
System.out.println(rowText);
}
}
}
}
}
从特定标记区域提取表格
此示例查找方形注释,将其矩形与每个检测到的表格进行比较,并仅输出位于标记区域内的表格。
- 使用 Document 实例打开源 PDF。
- 获取目标 Page 并定位方框 Annotation 标记提取区域的。
- 创建一个 TableAbsorber 并调用
visit(page)检测该页上的表格。 - 比较每个检测到的 AbsorbedTable Rectangle 与注释矩形的边界。
- 遍历匹配的 AbsorbedRow 和 AbsorbedCell 对象并重建行文本。
- 仅打印标记区域的表格数据。
public static void extractTableFromSpecificArea(Path inputFile) {
try (Document document = new Document(inputFile.toString())) {
Page page = document.getPages().get_Item(1);
Annotation squareAnnotation = null;
for (Annotation annotation : page.getAnnotations()) {
if (annotation.getAnnotationType() == AnnotationType.Square) {
squareAnnotation = annotation;
break;
}
}
if (squareAnnotation == null) {
System.out.println("No square annotation found.");
return;
}
TableAbsorber absorber = new TableAbsorber();
absorber.visit(page);
for (AbsorbedTable table : absorber.getTableList()) {
Rectangle tableRect = table.getRectangle();
Rectangle annotationRect = squareAnnotation.getRect();
boolean isInRegion = annotationRect.getLLX() < tableRect.getLLX()
&& annotationRect.getLLY() < tableRect.getLLY()
&& annotationRect.getURX() > tableRect.getURX()
&& annotationRect.getURY() > tableRect.getURY();
if (isInRegion) {
for (AbsorbedRow row : table.getRowList()) {
StringBuilder rowText = new StringBuilder();
for (AbsorbedCell cell : row.getCellList()) {
if (rowText.length() > 0) {
rowText.append("|");
}
StringBuilder cellText = new StringBuilder();
for (TextFragment fragment : cell.getTextFragments()) {
StringBuilder fragmentText = new StringBuilder();
for (TextSegment segment : fragment.getSegments()) {
fragmentText.append(segment.getText());
}
if (cellText.length() > 0) {
cellText.append("|");
}
cellText.append(fragmentText);
}
rowText.append(cellText);
}
System.out.println(rowText);
}
}
}
}
}
将表导出到 Excel
- 使用 Document 实例打开源 PDF。
- 创建 ExcelSaveOptions 用于导出。
- 将 Excel 输出格式设置为
XLSX因此检测到的表布局被写入为 Excel 工作簿。 - 呼叫
document.save(outputFile.toString(), excelSave)将文档导出为 Excel 格式。
public static void exportTablesToExcel(Path inputFile, Path outputFile) {
try (Document document = new Document(inputFile.toString())) {
ExcelSaveOptions excelSave = new ExcelSaveOptions();
excelSave.setFormat(ExcelSaveOptions.ExcelFormat.XLSX);
document.save(outputFile.toString(), excelSave);
}
}