您的位置:

从javapdf转excel的角度看PDF数据抽取

一、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数据抽取的开发者有所帮助。