一、PDF数据抽取的基础认识
从PDF中抽取数据是PDF处理中的重要部分,因为PDF格式的可读性强和颜值高,默认情况下无法直接修改和复制。PDF库通常以文本块或文本流的形式提供抽取功能,这些数据需要进一步解析和格式化才能导出。PDF数据抽取的目的是转换和重用PDF中的数据,如将PDF转换成Excel等格式。
Java语言是适用于各种类型的应用程序开发的功能强大的编程语言。同时由于Java本身拥有大量的类库和丰富的第三方类库支持,因此在PDF数据抽取上Java有着广泛的应用和深入的研究。
二、PDF数据抽取的实现
PDF 抽取需要解决两个基本问题:如何定位和提取任意的 PDF 网格,以及如何将提取的数据格式化为可读的文本。 PDF 数据抽取分为文本抽取和表格抽取两个部分。
1. 文本抽取
文本抽取通常用于提取 PDF 的摘要部分,如页面标题和作者名称,或对页面的全文内容进行提取。可以通过基于流和基于位置的策略进行,但如果PDF中存在多个嵌入式字体,这种方法的效果就不尽如人意。
PDFBox是一种基于Java的开源库,可以实现文本抽取功能,依赖于PdfTextStripper。以下是一个使用PDFBox进行文本抽取的示例代码:
PDDocument document = PDDocument.load(new File("pdf.pdf"));
PDFTextStripper textStripper = new PDFTextStripper();
String content = textStripper.getText(document);
2. 表格抽取
表格抽取通常是将PDF中的表格转换为Excel中的格式。PDF中的表格往往是以文字和线框的形式呈现。表格抽取需要将PDF中某个区域内的单元格识别和分离出来,然后建立表格模型,进一步将表格模型转换为目标格式。
一种常见的表格抽取方法是基于区域的方法,即将页面划分为不同的区域,每个区域包含表格单元以及与表格单元相关的字符和线条。之后需要将每个区域提取为一个表格模型,再将多个模型合并为一个表格。TET(Text Extraction Toolkit)正是一个基于区域的表格抽取工具,在Java中通过iText库实现。以下是使用TET进行表格抽取的示例代码:
import java.io.IOException;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import org.fit.pdfdom.PDFDomTree;
import org.pdfbox.pdmodel.PDDocument;
import org.pdfbox.pdmodel.PDPage;
import org.pdfbox.util.PDFTextStripperByArea;
import org.xml.sax.SAXException;
public class PDFTableExtract {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
PDFDomTree domTree = new PDFDomTree();
PDDocument document = PDDocument.load(new File("pdf.pdf"));
List allPages = document.getDocumentCatalog().getAllPages();
for (int pageNum = 0; pageNum < allPages.size(); pageNum++) {
PDPage page = (PDPage)allPages.get(pageNum);
PDFTextStripperByArea stripper = new PDFTextStripperByArea();
stripper.setSortByPosition(true);
// PDF中都是默认左下角为坐标原点,计算顶部和底部会比较麻烦
// 工具类PDFLayoutTextStripperByArea可以方便地通过百分比计算
float height = page.getMediaBox().getHeight();
float width = page.getMediaBox().getWidth();
stripper.addRegion("cell1", new RectangleF(0.5f, height - 56f, left2, height - 14f, 3)));
stripper.addRegion("cell2", new RectangleF(1.5f, height - 56f, left3, height - 14f, 3)));
stripper.addRegion("cell3", new RectangleF(2.5f, height - 56f, left4, height - 14f, 3)));
stripper.extractRegions(page);
ResultSet rs = createRecord();
rs.moveToInsertRow();
rs.updateString("ID", "1");
rs.updateString("CELL1", stripper.getTextForRegion("cell1"));
rs.updateString("CELL2", stripper.getTextForRegion("cell2"));
rs.updateString("CELL3", stripper.getTextForRegion("cell3"));
rs.insertRow();
}
document.close();
}
}
三、PDF转Excel实现
PDF 提取工具可以将 抽取 文本或表格到 XML 或 JSON 文件中,然后使用 Apache POI 等 API 依据 XML 或 Json 文件将数据转成 Excel。 Apache POI(Poor Obfuscation Implementation)是一个开源的 Java API,可以处理 Microsoft Office 格式的文档。下面是将PDF转换成Excel的示例代码:
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.json.JSONException;
import com.itextpdf.text.DocumentException;
import org.json.JSONArray;
import org.json.JSONObject;
public class PDF2Excel {
@SuppressWarnings("resource")
public static void main(String[] args) throws IOException, JSONException, DocumentException {
//读取json数据
String filepath = "data.json";
String jsonData = new String(Files.readAllBytes(Paths.get(filepath)));
JSONObject json = new JSONObject(jsonData);
JSONArray jsonArray = json.getJSONArray("rows");
//创建Excel文档对象并设置基本属性
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet("sheet1");
Iterator rowIter = jsonArray.iterator();
int rowNum = 0;
while (rowIter.hasNext()) {
HSSFRow row = sheet.createRow(rowNum);
JSONObject rowJson = (JSONObject) rowIter.next();
Iterator cellIter = rowJson.keys();
int cellNum = 0;
while (cellIter.hasNext()) {
String cellData = rowJson.getString((String) cellIter.next());
HSSFCell cell = row.createCell(cellNum++);
cell.setCellValue(cellData);
}
rowNum++;
}
FileOutputStream fileOutputStream = new FileOutputStream("output.xls");
workbook.write(fileOutputStream);
}
}
四、结论
PDF在很多场合用起来都很方便,但是需要将PDF转换成Excel等格式进行数据分析,各种PDF转换工具就显得尤为重要。本文借助Java语言以及PDFBox,iText和POI等Java类库,分别实现了文本和表格的PDF数据抽取并最终将PDF转换成Excel的过程。希望对使用Java进行PDF数据抽取的开发者有所帮助。