最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java輕松提取PDF表格數(shù)據(jù)并轉(zhuǎn)換為CSV

 更新時(shí)間:2025年09月18日 08:20:17   作者:缺點(diǎn)內(nèi)向  
在日常工作中,你是否曾為從 PDF 中手動(dòng)復(fù)制粘貼表格數(shù)據(jù)而抓狂,下面小編就和大家詳細(xì)介紹一下如何使用Java輕松高效地將提取的PDF 表格數(shù)據(jù)轉(zhuǎn)換為CSV吧

在日常工作中,你是否曾為從 PDF 中手動(dòng)復(fù)制粘貼表格數(shù)據(jù)而抓狂?面對(duì)那些包含財(cái)務(wù)報(bào)表、物流清單、統(tǒng)計(jì)報(bào)告或各種數(shù)據(jù)清單的 PDF 文件,你是否也曾想過(guò),如果能自動(dòng)化地將這些表格數(shù)據(jù)提取出來(lái),并轉(zhuǎn)換為易于處理的 CSV 格式,那該多好?

今天,我就來(lái)為大家揭秘如何在 Java 中實(shí)現(xiàn)這一目標(biāo),告別繁瑣的手動(dòng)操作,輕松高效地將 PDF 表格數(shù)據(jù)轉(zhuǎn)換為 CSV。

為什么我們需要從 PDF 中提取表格數(shù)據(jù)

PDF 格式因其出色的跨平臺(tái)兼容性和視覺(jué)保真度,被廣泛應(yīng)用于文檔共享和歸檔。然而,它的優(yōu)勢(shì)也恰恰是其在數(shù)據(jù)處理方面的局限:

  • 難以直接編輯和分析: PDF 旨在作為“電子紙”,其內(nèi)容通常是固定的,難以直接修改或進(jìn)行數(shù)據(jù)分析。
  • 數(shù)據(jù)孤島: 重要的表格數(shù)據(jù)被“鎖定”在 PDF 中,無(wú)法直接導(dǎo)入數(shù)據(jù)庫(kù)、電子表格或其他業(yè)務(wù)系統(tǒng)進(jìn)行進(jìn)一步處理。

將 PDF 表格數(shù)據(jù)轉(zhuǎn)換為 CSV (Comma Separated Values) 格式,則能帶來(lái)諸多便利:

  • 數(shù)據(jù)分析友好: CSV 是一種純文本格式,易于導(dǎo)入 Excel、Google Sheets 或各種數(shù)據(jù)分析工具進(jìn)行統(tǒng)計(jì)、篩選和可視化。
  • 系統(tǒng)集成: 方便將數(shù)據(jù)導(dǎo)入數(shù)據(jù)庫(kù)、CRM、ERP 等系統(tǒng),實(shí)現(xiàn)數(shù)據(jù)共享和業(yè)務(wù)流程自動(dòng)化。
  • 減少錯(cuò)誤: 自動(dòng)化提取避免了手動(dòng)復(fù)制粘貼可能引入的錯(cuò)誤,確保數(shù)據(jù)準(zhǔn)確性。

因此,掌握 PDF 表格的自動(dòng)化提取技術(shù),對(duì)于提升數(shù)據(jù)處理效率和業(yè)務(wù)自動(dòng)化水平至關(guān)重要。

借助 Spire.PDF for Java 實(shí)現(xiàn) PDF 到 CSV 的高效轉(zhuǎn)換

Spire.PDF for Java 是一款功能全面、性能卓越的 Java PDF 處理庫(kù)。它提供了豐富的 API,用于創(chuàng)建、編輯、轉(zhuǎn)換、打印和渲染 PDF 文檔。尤其在 PDF 表格提取方面,Spire.PDF for Java 能夠智能識(shí)別 PDF 中的表格結(jié)構(gòu),并以結(jié)構(gòu)化的方式返回?cái)?shù)據(jù),極大地簡(jiǎn)化了開發(fā)難度。

下面,我們來(lái)詳細(xì)分解如何使用它來(lái)完成 PDF 到 CSV 的轉(zhuǎn)換:

環(huán)境準(zhǔn)備:引入 Spire.PDF for Java 依賴

首先,你需要在你的 Maven 或 Gradle 項(xiàng)目中引入 Spire.PDF for Java 依賴。

Maven:

<repositories>
    <repository>
        <id>e-iceblue</id>
        <url>https://repo.e-iceblue.cn/repository/maven-public/</url>
    </repository>
</repositories>
<dependencies>
    <dependency>
        <groupId>e-iceblue</groupId>
        <artifactId>spire.pdf</artifactId>
        <version>10.X.X</version> <!-- 請(qǐng)?zhí)鎿Q為最新版本號(hào) -->
    </dependency>
</dependencies>

Gradle:

repositories {
    maven { url 'https://repo.e-iceblue.cn/repository/maven-public/' }
}
dependencies {
    implementation 'e-iceblue:spire.pdf:10.X.X' // 請(qǐng)?zhí)鎿Q為最新版本號(hào)
}

請(qǐng)?jiān)L問(wèn) Spire.PDF for Java 官網(wǎng)獲取最新的版本號(hào)。

核心步驟分解與代碼示例

現(xiàn)在,我們來(lái)看具體的代碼實(shí)現(xiàn)。假設(shè)我們有一個(gè)名為 tableSample.pdf 的 PDF 文件,其中包含我們需要提取的表格數(shù)據(jù)。

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

import java.io.FileWriter;
import java.io.IOException;
import java.util.List;

public class PdfTableToCsvConverter {

    public static void main(String[] args) {
        // 1. 加載 PDF 文檔
        String pdfFilePath = "data/tableSample.pdf"; // 替換為你的 PDF 文件路徑
        String csvOutputFilePath = "output/extracted_table.csv"; // CSV 輸出路徑

        PdfDocument pdfDocument = new PdfDocument();
        try {
            pdfDocument.loadFromFile(pdfFilePath);
            System.out.println("PDF 文檔加載成功:" + pdfFilePath);

            // 2. 創(chuàng)建 PdfTableExtractor 實(shí)例
            PdfTableExtractor extractor = new PdfTableExtractor(pdfDocument);

            // 使用 FileWriter 寫入 CSV 文件
            try (FileWriter csvWriter = new FileWriter(csvOutputFilePath)) {
                // 遍歷 PDF 的每一頁(yè)
                for (int pageIndex = 0; pageIndex < pdfDocument.getPages().getCount(); pageIndex++) {
                    System.out.println("正在處理第 " + (pageIndex + 1) + " 頁(yè)...");

                    // 3. 識(shí)別并提取表格
                    // extractTable(int pageIndex) 方法返回當(dāng)前頁(yè)的所有表格
                    PdfTable[] tableLists = extractor.extractTable(pageIndex);

                    if (tableLists != null && tableLists.length > 0) {
                        for (PdfTable table : tableLists) {
                            System.out.println("  發(fā)現(xiàn)表格,行數(shù):" + table.getRowCount() + ", 列數(shù):" + table.getColumnCount());

                            // 4. 將提取到的數(shù)據(jù)寫入 CSV
                            for (int row = 0; row < table.getRowCount(); row++) {
                                StringBuilder rowData = new StringBuilder();
                                for (int column = 0; column < table.getColumnCount(); column++) {
                                    // 獲取單元格文本
                                    String cellText = table.getText(row, column);
                                    // 對(duì)包含逗號(hào)或雙引號(hào)的文本進(jìn)行處理,避免 CSV 格式錯(cuò)誤
                                    if (cellText.contains(",") || cellText.contains(""")) {
                                        cellText = """ + cellText.replace(""", """") + """;
                                    }
                                    rowData.append(cellText);
                                    if (column < table.getColumnCount() - 1) {
                                        rowData.append(","); // 添加逗號(hào)分隔
                                    }
                                }
                                csvWriter.append(rowData.toString()).append("\n"); // 寫入一行數(shù)據(jù)并換行
                            }
                            // 每個(gè)表格之間可以添加一個(gè)空行,或者其他分隔符,以便區(qū)分
                            csvWriter.append("\n"); 
                        }
                    } else {
                        System.out.println("  第 " + (pageIndex + 1) + " 頁(yè)未檢測(cè)到表格。");
                    }
                }
                System.out.println("數(shù)據(jù)已成功提取并保存到:" + csvOutputFilePath);
            } catch (IOException e) {
                System.err.println("寫入 CSV 文件時(shí)發(fā)生錯(cuò)誤:" + e.getMessage());
            }

        } catch (Exception e) {
            System.err.println("處理 PDF 文件時(shí)發(fā)生錯(cuò)誤:" + e.getMessage());
            e.printStackTrace();
        } finally {
            if (pdfDocument != null) {
                pdfDocument.close(); // 關(guān)閉文檔,釋放資源
                pdfDocument.dispose();
            }
        }
    }
}

代碼說(shuō)明:

  • PdfDocument.loadFromFile(): 用于加載指定的 PDF 文件。
  • PdfTableExtractor: Spire.PDF for Java 提供的表格提取工具類。
  • extractor.extractTable(pageIndex): 這是核心方法,它會(huì)智能分析指定頁(yè)面的內(nèi)容,識(shí)別出其中的表格結(jié)構(gòu),并返回一個(gè) PdfTable 數(shù)組。
  • PdfTable.getRowCount()PdfTable.getColumnCount(): 獲取提取到表格的行數(shù)和列數(shù)。
  • PdfTable.getText(row, column): 獲取指定單元格的文本內(nèi)容。
  • CSV 格式化: 代碼中包含了簡(jiǎn)單的 CSV 格式化邏輯,特別是針對(duì)含有逗號(hào)或雙引號(hào)的單元格內(nèi)容,使用雙引號(hào)包裹并對(duì)內(nèi)部雙引號(hào)進(jìn)行轉(zhuǎn)義,以確保生成的 CSV 文件格式正確。

運(yùn)行上述代碼,你就可以將 tableSample.pdf 中的所有表格數(shù)據(jù)提取出來(lái),并保存到 extracted_table.csv 文件中。

深入優(yōu)化與注意事項(xiàng)

盡管 Spire.PDF for Java 已經(jīng)非常強(qiáng)大,但在實(shí)際應(yīng)用中,我們?nèi)孕杩紤]一些優(yōu)化和注意事項(xiàng):

復(fù)雜表格處理

合并單元格與跨頁(yè)表格: Spire.PDF for Java 通常能較好地處理合并單元格和跨頁(yè)表格。對(duì)于跨頁(yè)表格,它會(huì)嘗試在不同頁(yè)面上識(shí)別出表格的各個(gè)部分。如果遇到識(shí)別不準(zhǔn)確的情況,可能需要結(jié)合其他文本提取功能,或者進(jìn)行二次數(shù)據(jù)清洗。

非標(biāo)準(zhǔn)表格: 對(duì)于那些并非嚴(yán)格意義上的表格(例如,僅通過(guò)線條或文本排版模擬的表格),Spire.PDF for Java 的智能識(shí)別可能無(wú)法完全捕捉。在這種情況下,你可能需要結(jié)合 PdfTextFinder 等工具,通過(guò)文本定位和正則表達(dá)式來(lái)提取數(shù)據(jù),然后手動(dòng)構(gòu)建表格結(jié)構(gòu)。

性能考量

大型 PDF 文件: 處理包含數(shù)百上千頁(yè)的大型 PDF 文件時(shí),內(nèi)存消耗和處理時(shí)間可能會(huì)增加。建議:

  • 分批處理: 如果可能,將大型 PDF 文件拆分為多個(gè)小文件進(jìn)行處理。
  • 優(yōu)化循環(huán): 確保在循環(huán)中沒(méi)有進(jìn)行不必要的對(duì)象創(chuàng)建或復(fù)雜計(jì)算。
  • 及時(shí)釋放資源: 始終在 finally 塊中調(diào)用 pdfDocument.close()pdfDocument.dispose() 來(lái)釋放資源。

數(shù)據(jù)清洗與驗(yàn)證

  • 數(shù)據(jù)質(zhì)量: 即使是智能提取,也可能因?yàn)?PDF 文件的質(zhì)量(如掃描件、低分辨率)導(dǎo)致提取到的數(shù)據(jù)不完全干凈。在將數(shù)據(jù)導(dǎo)入最終系統(tǒng)之前,務(wù)必進(jìn)行數(shù)據(jù)清洗(去除多余空格、統(tǒng)一格式等)和驗(yàn)證。
  • 頭部信息: 提取到的表格可能不包含明確的列頭。你可能需要根據(jù)業(yè)務(wù)邏輯,在生成 CSV 文件時(shí)手動(dòng)添加列頭,或者通過(guò)分析第一行數(shù)據(jù)來(lái)識(shí)別列頭。

其他功能延伸

Spire.PDF for Java 不僅僅局限于表格提取。它還提供了強(qiáng)大的文本提取、圖片提取、內(nèi)容替換、文檔合并/拆分、PDF 到其他格式(如 Word、Excel、圖片)的轉(zhuǎn)換等功能。你可以根據(jù)項(xiàng)目需求,進(jìn)一步探索和利用這些功能,實(shí)現(xiàn)更復(fù)雜的 PDF 處理任務(wù)。

處理復(fù)雜的 PDF 轉(zhuǎn) CSV 場(chǎng)景

實(shí)際應(yīng)用中,PDF 文件常常包含多個(gè)表格、跨多頁(yè),或表格結(jié)構(gòu)不規(guī)則。下面介紹如何應(yīng)對(duì)這些情況。

單頁(yè)包含多個(gè)表格

extractTable(i) 返回的 PdfTable[] 包含該頁(yè)中檢測(cè)到的所有表格,可以將每個(gè)表單獨(dú)保存為不同的 CSV 文件:

for (int i = 0; i < pdf.getPages().getCount(); i++) {
    PdfTableExtractor extractor = new PdfTableExtractor(pdf);
    PdfTable[] tableLists = extractor.extractTable(i);

    if (tableLists != null) {
        for (int t = 0; t < tableLists.length; t++) {
            PdfTable table = tableLists[t];
            StringBuilder tableContent = new StringBuilder();

            for (int row = 0; row < table.getRowCount(); row++) {
                for (int col = 0; col < table.getColumnCount(); col++) {
                    tableContent.append(escapeCsvField(table.getText(row, col)));
                    if (col < table.getColumnCount() - 1) {
                        tableContent.append(",");
                    }
                }
                tableContent.append("\n");
            }

            try (Writer writer = new OutputStreamWriter(
                    new FileOutputStream("output/Tables/Table_Page" + i + "_Index" + t + ".csv"), "UTF-8")) {
                writer.write(sb.toString());
            }
        }
    }
}

跨頁(yè)或大表格

如果表格跨越多頁(yè),可以逐頁(yè)提取并 追加寫入,以避免覆蓋:

StringBuilder sb = new StringBuilder();

for (int i = 0; i < pdf.getPages().getCount(); i++) {
    PdfTableExtractor extractor = new PdfTableExtractor(pdf);
    PdfTable[] tables = extractor.extractTable(i);

    if (tables != null) {
        for (PdfTable table : tables) {
            for (int row = 0; row < table.getRowCount(); row++) {
                for (int col = 0; col < table.getColumnCount(); col++) {
                    sb.append(escapeCsvField(table.getText(row, col)));
                    if (col < table.getColumnCount() - 1) sb.append(",");
                }
                sb.append("\n");
            }
        }
    }
}

FileWriter writer = new FileWriter("MergedTables.csv");
writer.write(sb.toString());
writer.close();

格式限制

CSV 只能存儲(chǔ)純文本,像合并單元格、字體、圖片等格式會(huì)丟失。如果需要保留樣式,可以導(dǎo)出為 Excel(.xlsx)。

CSV 特殊字符處理

在寫入 CSV 時(shí),逗號(hào)、分號(hào)、雙引號(hào)、換行等特殊字符可能會(huì)破壞文件結(jié)構(gòu)。 上述 Java 示例中的 escapeCsvField 方法可以去除換行并安全轉(zhuǎn)義。

更復(fù)雜的場(chǎng)景下,可以使用 Spire.XLS for Java,通過(guò)簡(jiǎn)單的 Java 代碼將表格數(shù)據(jù)寫入 Excel,再將 Excel 工作表保存為 CSV,無(wú)需手動(dòng)處理特殊字符。

總結(jié)

通過(guò)本文的介紹,相信你已經(jīng)掌握了如何在 Java 中使用 Spire.PDF for Java 庫(kù)來(lái)高效地將 PDF 表格數(shù)據(jù)轉(zhuǎn)換為 CSV 格式。這款工具憑借其智能的表格識(shí)別能力和簡(jiǎn)潔的 API,極大地簡(jiǎn)化了數(shù)據(jù)提取的復(fù)雜性,幫助開發(fā)者從 PDF 的“數(shù)據(jù)孤島”中解放數(shù)據(jù)價(jià)值。

到此這篇關(guān)于Java輕松提取PDF表格數(shù)據(jù)并轉(zhuǎn)換為CSV的文章就介紹到這了,更多相關(guān)Java PDF轉(zhuǎn)CSV內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Maven快速入門和常用配置方式

    Maven快速入門和常用配置方式

    Apache?Maven?是一個(gè)強(qiáng)大的?Java?項(xiàng)目管理工具,通過(guò)項(xiàng)目對(duì)象模型(POM)和生命周期管理構(gòu)建、依賴和文檔,?它支持依賴管理、構(gòu)建繼承和站點(diǎn)生成,簡(jiǎn)化構(gòu)建過(guò)程并確保環(huán)境一致性,?關(guān)鍵指令如mvn?clean、mvn?compile和mvn?package等幫助完成構(gòu)建任務(wù)
    2026-05-05
  • application.yml文件中如何開啟mybatis自動(dòng)駝峰映射

    application.yml文件中如何開啟mybatis自動(dòng)駝峰映射

    這篇文章主要介紹了application.yml文件中開啟mybatis自動(dòng)駝峰映射的方法,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • SpringBoot實(shí)現(xiàn)HTTP服務(wù)監(jiān)聽的代碼示例

    SpringBoot實(shí)現(xiàn)HTTP服務(wù)監(jiān)聽的代碼示例

    前后端分離項(xiàng)目中,在調(diào)用接口調(diào)試時(shí)候,我們可以通過(guò)cpolar內(nèi)網(wǎng)穿透將本地服務(wù)端接口模擬公共網(wǎng)絡(luò)環(huán)境遠(yuǎn)程調(diào)用調(diào)試,本次教程我們以Java服務(wù)端接口為例,需要的朋友可以參考下
    2023-05-05
  • Java單測(cè)void類型的方法詳解

    Java單測(cè)void類型的方法詳解

    這篇文章主要給大家介紹了Java中單測(cè)void類型的方法,文中給出了詳細(xì)的示例代碼,相信對(duì)大家的理解和學(xué)習(xí)具有一定的參考借鑒價(jià)值,需要的朋友可以跟著小編下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-01-01
  • java四種訪問(wèn)權(quán)限實(shí)例分析

    java四種訪問(wèn)權(quán)限實(shí)例分析

    這篇文章主要介紹了java四種訪問(wèn)權(quán)限實(shí)例分析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • SpringMVC注解的入門實(shí)例詳解

    SpringMVC注解的入門實(shí)例詳解

    這篇文章主要為大家介紹了SpringMVC注解的入門實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-01-01
  • MyBatis自定義映射關(guān)系和關(guān)聯(lián)查詢實(shí)現(xiàn)方法詳解

    MyBatis自定義映射關(guān)系和關(guān)聯(lián)查詢實(shí)現(xiàn)方法詳解

    這篇文章主要介紹了MyBatis自定義映射關(guān)系和關(guān)聯(lián)查詢實(shí)現(xiàn)方法,當(dāng)POJO屬性名與數(shù)據(jù)庫(kù)列名不一致時(shí),需要自定義實(shí)體類和結(jié)果集的映射關(guān)系,在MyBatis注解開發(fā)中,使用@Results定義并使用自定義映射,使用 @ResultMap使用自定義映射
    2023-04-04
  • springboot多環(huán)境進(jìn)行動(dòng)態(tài)配置的方法

    springboot多環(huán)境進(jìn)行動(dòng)態(tài)配置的方法

    這篇文章主要介紹了springboot多環(huán)境下如何進(jìn)行動(dòng)態(tài)配置,本文主要分享了如何在springboot的項(xiàng)目中使用多環(huán)境配置,重點(diǎn)是”spring.profiles.active“屬性,需要的朋友可以參考下
    2022-06-06
  • 如何通過(guò)Kaptcha在Web頁(yè)面生成驗(yàn)證碼

    如何通過(guò)Kaptcha在Web頁(yè)面生成驗(yàn)證碼

    這篇文章主要介紹了如何通過(guò)Kaptcha在Web頁(yè)面生成驗(yàn)證碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • 關(guān)于.java編譯成.class?與?.class反編譯成.java問(wèn)題

    關(guān)于.java編譯成.class?與?.class反編譯成.java問(wèn)題

    這篇文章主要介紹了關(guān)于.java編譯成.class?與?.class反編譯成.java問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09

最新評(píng)論

鹰潭市| 化州市| 辽阳市| 沙河市| 忻州市| 井冈山市| 大同市| 朝阳区| 怀集县| 那坡县| 威远县| 合作市| 乐至县| 墨玉县| 平昌县| 扬中市| 大邑县| 郧西县| 南宫市| 美姑县| 潼南县| 衡东县| 辽宁省| 陈巴尔虎旗| 揭阳市| 永登县| 开鲁县| 阿尔山市| 玉龙| 汕尾市| 临洮县| 怀仁县| 临西县| 廉江市| 科尔| 孟连| 正宁县| 荔波县| 平顶山市| 错那县| 绥江县|