Java自动化提取PDF表格的全场景实现

 更新时间:2026年01月16日 08:39:22   作者:E-iceblue  
随着企业数据自动化的需求日益激增,提取 PDF 中的表格的需求也越来越受到重视,本文将基于最新的 Spire.PDF for Java,展示如何精准地将 PDF 表格转换为文本、CSV 以及 Excel 格式,实现全场景的数据自动化提取,有需要的可以了解下

随着企业数据自动化的需求日益激增,提取 PDF 中的表格的需求也越来越受到重视。尽管此前我们就发布过使用 Java 提取 PDF 中的表格,并保存为 Text 文件的教程,但显然,简单的文本提取难以满足复杂的数据分析场景。

在处理财务报表、供应链清单等结构化文档时,开发者不仅需要获取数据,更需要保留其逻辑结构。本文将基于最新的 Spire.PDF for Java,展示如何精准地将 PDF 表格转换为文本、CSV 以及 Excel 格式,实现全场景的数据自动化提取。

环境准备

在进入今天的正文前,请确保你的开发环境已就绪:

  • JDK 支持:推荐使用 JDK 8 及以上版本。
  • Maven 依赖:在 pom.xml 文件中配置以下仓库和依赖,以获取最新的组件支持。
<repositories>
    <repository>
        <id>com.e-iceblue</id>
        <name>e-iceblue</name>
        <url>https://repo.e-iceblue.cn/repository/maven-public/</url>
    </repository>
</repositories>
<dependencies>
    <dependency>
        <groupId>e-iceblue</groupId>
        <artifactId>spire.pdf</artifactId>
        <version>11.12.16</version>
    </dependency>
</dependencies>

或导航到 Spire.PDF for Java 的官方网站下载安装包,解压后将 jar 文件手动导入到项目中。

基础提取:将 PDF 表格转为文本

作为入门级方案,将 PDF 中的表格提取为文本适用于对格式要求不高、仅需获取原始信息的场景。

技术逻辑:利用 PdfTableExtractor 识别表格,通过遍历单元格获取字符串。

import com.spire.pdf.*;
import com.spire.pdf.utilities.PdfTable;
import com.spire.pdf.utilities.PdfTableExtractor;

import java.io.FileWriter;
import java.io.IOException;

public class ExtractTable {
    public static void main(String[] args)throws IOException {
        // 实例化PdfDocument类的对象
        PdfDocument pdf = new PdfDocument();

        // 加载PDF文档
        pdf.loadFromFile("E:/Administrator/Python1/input/项目进度.pdf");

        // 创建StringBuilder类的实例
        StringBuilder builder = new StringBuilder();

        // 创建PdfTableExtractor类的对象
        PdfTableExtractor extractor = new PdfTableExtractor(pdf);

        // 遍历每一页
        for (int page = 0; page < pdf.getPages().getCount(); page++)
        {
            // 提取页面中的表格存入PdfTable[]数组
            PdfTable[] tableLists = extractor.extractTable(page);
            if (tableLists != null && tableLists.length > 0)
            {
                //遍历表格
                for (PdfTable table : tableLists)
                {
                    int row = table.getRowCount();//获取表格行
                    int column = table.getColumnCount();//获取表格列
                    for (int i = 0; i < row; i++)
                    {
                        for (int j = 0; j < column; j++)
                        {
                            // 获取表格中的文本内容
                            String text = table.getText(i, j);

                            // 将获取的text写入StringBuilder容器
                            builder.append(text+" ");
                        }
                        builder.append("\r\n");
                    }
                }
            }
        }

        // 保存为txt文档
        FileWriter fileWriter = new FileWriter("E:/Administrator/Python1/output/提取表格为文本.txt");
        fileWriter.write(builder.toString());
        fileWriter.flush();
        fileWriter.close();
    }
}

源文件与输出文件对比图:

方案一:最简化提取——将 PDF 表格导出为 CSV

虽然保存为文本格式能够快速获取内容,但在面对需要二次计算或数据入库的场景时,将 PDF 表格导出为 CSV 是一种更合适的选择。CSV 格式通用性很高,几乎可以被所有的主流数据库系统、数据分析工具以及编程语言无差识别,是构建自动化数据流转链路的理想中间格式。它不仅写入速度极快,且内存开销低,尤其适合后端批量处理任务。

技术逻辑:CSV(逗号分隔值)是结构化数据的标准格式。我们通过 PdfTableExtractor 获取表格数据后,通过代码控制逗号分隔符输出。

import com.spire.pdf.*;  
import com.spire.pdf.utilities.*;  
  
import java.io.*;  
  
public class ExtractTable {  
    public static void main(String[] args) throws Exception {  
        // 1. 加载 PDF 文档  
        PdfDocument pdf = new PdfDocument();  
        // 请确保路径正确  
        pdf.loadFromFile("E:/Administrator/Python1/input/项目进度.pdf");  
  
        // 用于存储提取文本的 StringBuilder        StringBuilder sb = new StringBuilder();  
  
        // 2. 遍历每一页并提取表格  
        for (int i = 0; i < pdf.getPages().getCount(); i++) {  
            PdfTableExtractor extractor = new PdfTableExtractor(pdf);  
            PdfTable[] tableLists = extractor.extractTable(i);  
  
            if (tableLists != null) {  
                for (PdfTable table : tableLists) {  
                    for (int row = 0; row < table.getRowCount(); row++) {  
                        for (int col = 0; col < table.getColumnCount(); col++) {  
                            // 使用工具方法处理 CSV 特殊字符和换行  
                            String cellText = escapeCsvField(table.getText(row, col));  
                            sb.append(cellText);  
  
                            // 列之间用逗号分隔  
                            if (col < table.getColumnCount() - 1) {  
                                sb.append(",");  
                            }  
                        }  
                        // 行之间用换行符分隔  
                        sb.append("\n");  
                    }  
                }  
            }  
        }  
  
        // 3. 写入带 BOM 的 CSV 文件  
        File outFile = new File("E:/Administrator/Python1/output/提取表格为csv.csv");  
  
        // 确保输出目录存在  
        if (!outFile.getParentFile().exists()) {  
            outFile.getParentFile().mkdirs();  
        }  
  
        try (FileOutputStream fos = new FileOutputStream(outFile)) {  
            // 【核心修复】写入 UTF-8 BOM 字节,防止 Excel 打开乱码  
            fos.write(0xEF);  
            fos.write(0xBB);  
            fos.write(0xBF);  
  
            // 使用 UTF-8 编码包装输出流  
            try (Writer writer = new OutputStreamWriter(fos, "UTF-8")) {  
                writer.write(sb.toString());  
            }  
        }  
  
        pdf.close();  
        System.out.println("PDF 表格已成功导出为 CSV 文件。");  
    }  
  
    /**  
     * 处理 CSV 字段的工具方法:  
     * 1. 去除单元格内的换行符  
     * 2. 转义双引号  
     * 3. 对包含特殊字符的字段添加双引号包裹  
     */  
    private static String escapeCsvField(String text) {  
        if (text == null) return "";  
  
        // 去掉单元格内的换行符(防止破坏 CSV 行结构)  
        text = text.replaceAll("[\\n\\r]", " ");  
  
        // 处理特殊字符  
        boolean containsSpecialChar = text.contains(",") || text.contains(";") ||  
                text.contains("\"") || text.contains("\n");  
  
        if (containsSpecialChar) {  
            // 转义双引号:将 " 替换为 ""            text = text.replace("\"", "\"\"");  
            // 整个字段用双引号包裹  
            text = "\"" + text + "\"";  
        }  
  
        return text.trim();  
    }  
}

结果文件示意图:

提示:在导出 CSV 时,建议对单元格内容使用双引号包裹,以处理数据本身含有逗号的情况。此外,确保文件使用 UTF-8 (with BOM) 编码,防止在 Excel 中直接打开时出现中文乱码。

方案二:结构化导出——将 PDF 表格直接转为 Excel

由于 CSV 只能存储纯文本,合并单元格、字体等格式在导出时会丢失。如果需要保留样式,应该选择将 PDF 中的表格提取为 Excel 文件。比如说处理财务报表、审计清单等文件,单元格样式与数据息息相关。通过导出为 Excel,你可以更好地保留原 PDF 文档中的布局,避免对数据进行二次加工。

核心步骤

  • 加载源 PDF 文档。
  • 遍历读取 PDF 中的表格单元格和数据。
  • 将数据填入 Excel 单元格中。
  • 设置 Excel 单元格(可选步骤)。
  • 调用 saveToFile 并指定 FileFormat.XLSX
import com.spire.pdf.PdfDocument;  
import com.spire.pdf.utilities.PdfTable;  
import com.spire.pdf.utilities.PdfTableExtractor;  
import com.spire.xls.ExcelVersion;  
import com.spire.xls.Workbook;  
import com.spire.xls.Worksheet;  
  
public class ExtractTable {  
  
    public static void main(String[] args) {  
  
        //加载示例PDF文档  
        PdfDocument pdf = new PdfDocument("E:/Administrator/Python1/input/项目进度.pdf");  
        //创建一个PdfTableExtractor实例  
        PdfTableExtractor extractor = new PdfTableExtractor(pdf);  
        //从第一页提取表格  
        PdfTable[] pdfTables  = extractor.extractTable(0);  
        //创建一个工作簿对象  
        Workbook wb = new Workbook();  
        //删除默认工作表  
        wb.getWorksheets().clear();  
        //如果找到任何表格  
        if (pdfTables != null && pdfTables.length > 0) {  
            //循环遍历表格  
            for (int tableNum = 0; tableNum < pdfTables.length; tableNum++) {  
                //将工作表添加到工作簿  
                String sheetName = String.format("Table - %d", tableNum + 1);  
                Worksheet sheet = wb.getWorksheets().add(sheetName);  
                //循环遍历当前表格中的行  
                for (int rowNum = 0; rowNum < pdfTables[tableNum].getRowCount(); rowNum++) {  
                    //循环遍历当前表格中的列  
                    for (int colNum = 0; colNum < pdfTables[tableNum].getColumnCount(); colNum++) {  
                        //从当前表格单元格中提取数据  
                        String text = pdfTables[tableNum].getText(rowNum, colNum);  
                        //将数据插入特定单元格  
                        sheet.get(rowNum + 1, colNum + 1).setText(text);  
                    }  
                }  
                //自动调整列宽  
                for (int sheetColNum = 0; sheetColNum < sheet.getColumns().length; sheetColNum++) {  
                    sheet.autoFitColumn(sheetColNum + 1);  
                }  
            }  
        }  
        //将工作簿保存为 Excel 文件  
        wb.saveToFile("E:/Administrator/Python1/output/提取表格为excel.xlsx", ExcelVersion.Version2016);  
    }  
}

效果展示

进阶挑战:处理复杂的跨页提取

在实际业务中,我们常遇到长篇合同或大型清单,同一个表格被拆分到两个或多个物理页面。这种情况单纯依靠循环提取会导致数据断层。那么如何识别第二页顶部的表格是第一页末尾表格的延续?如何自动合并表头?

针对此类涉及坐标逻辑判断的高阶需求,我们准备了详细的进阶教程。感兴趣的话可以查看官网教程如何在 Java 中将 PDF 转换为 CSV(轻松提取 PDF 表格)

总结与技术支持

从提取 PDF 表格为文本,到涵盖 CSV 和 Excel 的全场景导出,技术工具的演进让 PDF 数据处理变得不再繁琐。通过 Spire.PDF for Java,你可以根据业务需求灵活选择轻量级的 CSV 方案或高保真的 Excel 方案。

到此这篇关于Java自动化提取PDF表格的全场景实现的文章就介绍到这了,更多相关Java提取PDF表格内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot整合MongoDB实现事务管理

    SpringBoot整合MongoDB实现事务管理

    Spring Boot是一种快速开发Spring应用的方式,它提供了大量的自动配置和默认设置,以简化开发流程,MongoDB是一个基于文档的NoSQL数据库,本文将介绍如何在Spring Boot应用中整合MongoDB,并实现事务管理,需要的朋友可以参考下
    2024-07-07
  • 新版SpringSecurity5.x使用与配置详解

    新版SpringSecurity5.x使用与配置详解

    Spring Security是一个强大且高度可定制的身份验证和访问控制框架,本文主要介绍了新版SpringSecurity5.x使用与配置详解,具有一定的参考价值,感兴趣的可以了解一下
    2024-08-08
  • Spring Boot处理全局统一异常的两种方法与区别

    Spring Boot处理全局统一异常的两种方法与区别

    这篇文章主要给大家介绍了关于Spring Boot处理全局统一异常的两种方法与区别,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring Boot具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-06-06
  • java解析多层嵌套json字符串问题

    java解析多层嵌套json字符串问题

    这篇文章主要介绍了java解析多层嵌套json字符串问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • 配置idea将Java与数据库连接起来实现一个简单的图书管理系统

    配置idea将Java与数据库连接起来实现一个简单的图书管理系统

    这篇文章主要给大家介绍了关于配置idea将Java与数据库连接起来实现一个简单的图书管理系统的相关资料,本文从基于Java的图书管理系统的背景、系统设计、数据库设计和系统实现等方面进行了详细的研究,需要的朋友可以参考下
    2023-12-12
  • Java C++分别实现滑动窗口的最大值

    Java C++分别实现滑动窗口的最大值

    这篇文章主要介绍了分别通过Java和C++实现滑动窗口最大值,即给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。感兴趣的可以了解一下
    2021-12-12
  • java中Properties文件加载和使用方法

    java中Properties文件加载和使用方法

    这篇文章主要为大家详细介绍了java中Properties文件加载和使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • Spring配置多个数据源并实现数据源的动态切换功能

    Spring配置多个数据源并实现数据源的动态切换功能

    这篇文章主要介绍了Spring配置多个数据源并实现数据源的动态切换功能,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2024-01-01
  • Spring 应用中集成 Apache Shiro的方法

    Spring 应用中集成 Apache Shiro的方法

    这篇文章主要介绍了Spring 应用中集成 Apache Shiro的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • 浅析Java中Future接口的使用方法

    浅析Java中Future接口的使用方法

    在Java开发中,异步编程是提高系统性能和响应能力的重要手段之一。本文将深入探讨Future接口的原理和源码解读,帮助读者更好地理解Future接口的工作机制和使用方法
    2023-05-05

最新评论