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

使用Python有效識別和合并PDF的跨頁表格

 更新時間:2025年12月18日 08:58:30   作者:Quest?for?Knowledge  
在處理大量包含表格數(shù)據(jù)的PDF文檔時,一個常見的挑戰(zhàn)是這些表格可能跨越多頁,動合并這些表格不僅耗時,而且容易出錯,所以本文給大家介紹了如何使用Python有效識別和合并PDF的跨頁表格,需要的朋友可以參考下

前言

在處理大量包含表格數(shù)據(jù)的PDF文檔時,一個常見的挑戰(zhàn)是這些表格可能跨越多頁。手動合并這些表格不僅耗時,而且容易出錯。幸運的是,通過使用Python和一些強大的庫,我們可以自動化這一過程,有效地識別和合并跨頁表格。

1.所需庫與安裝

為了實現(xiàn)這個功能,我們將使用以下Python庫:

  • pandas:用于數(shù)據(jù)處理和分析。
  • camelot:用于從PDF文檔中提取表格。
  • pdfplumber:用于讀取PDF文檔中的文本和布局信息。
  • win32com.client:用于將Word文檔轉(zhuǎn)換為PDF(僅限Windows環(huán)境)。

確保你的環(huán)境中安裝了這些庫。可以通過運行以下命令來安裝它們:

pip install pandas camelot-py pdfplumber pywin32
import pandas as pd
import camelot  # 基于文本的 PDF,而不適用于掃描文檔
import os
from win32com.client import Dispatch
from os import walk
import pdfplumber
# 文件夾路徑
path = 'E:\\data\\table_json-master'
# 閾值,判斷表格是否位于頁面頂部或底部
topthreshold = 0.2
dthreshold = 0.8
# 將word文件轉(zhuǎn)化為PDF
wdFormatPDF = 17

步驟詳解

  1. 識別表格邊界
    利用pdfplumber,我們可以檢測每一頁上的表格邊界,這有助于判斷表格是否位于頁面頂部或底部,以及是否跨頁。
  2. 表格識別與跨頁檢查
    camelot庫被用來識別PDF文檔中的表格。我們檢查每一表格是否在頁面的頂部或底部結(jié)束,以此判斷它是否可能是一個跨頁表格。
  3. 跨頁表格合并
    如果確定表格跨頁并且列數(shù)匹配,我們使用camelot再次讀取這些頁面并將表格數(shù)據(jù)合并到一個DataFrame中,然后將結(jié)果保存為CSV或JSON文件。

2.提供 doc2pdf 函數(shù)用于將 Microsoft Word 文檔轉(zhuǎn)換為 PDF 格式

將文檔從 Word 轉(zhuǎn)換為 PDF 的方法非常適合批量轉(zhuǎn)換,即當(dāng)你有多個需要自動轉(zhuǎn)換的 Word 文檔時。但是請注意,根據(jù)文檔的數(shù)量和大小,這個操作可能會比較慢,因為每次轉(zhuǎn)換都涉及到打開 Word,加載文檔,將其保存為 PDF,然后再關(guān)閉文檔和 Word 應(yīng)用程序。

def doc2pdf(input_file):
    word = Dispatch('Word.Application')
    doc = word.Documents.Open(input_file)
    doc.SaveAs(input_file.replace(".docx", ".pdf"), FileFormat=wdFormatPDF)
    doc.Close()
    word.Quit()


# 遍歷文件夾,將其中的word文件轉(zhuǎn)化為PDF
for root, dirs, filenames in walk(path):
    for file in filenames:
        if file.endswith(".doc") or file.endswith(".docx"):
            doc2pdf(os.path.join(root, file))

win32com.client 庫是針對 Windows 環(huán)境的,依賴于機器上安裝的 Microsoft Word。

3.定義函數(shù),用于識別PDF文檔中表格的位置,特別是跨頁表格

  1. get_table_bounds(page):
    這個函數(shù)接收一個PDF頁面對象,使用pdfplumber庫的find_tables()方法找到頁面上的所有表格,并返回一個包含每個表格邊界坐標(biāo)的列表。每個表格的邊界由一個四元組表示,包含左、頂、右、底的坐標(biāo)。
  2. is_first_table_at_top_of_page(page):
    這個函數(shù)接收一個PDF頁面對象,計算頁面高度,然后獲取第一個表格的邊界,判斷這個表格的頂部位置是否低于頁面頂部的某個閾值(topthreshold)。如果低于這個閾值,意味著表格可能從頁面的頂部開始,返回一個字典,指示這個條件是否滿足。
  3. is_last_table_at_bottom_of_page(page):
    類似于is_first_table_at_top_of_page,但檢查的是最后一個表格的底部位置是否高于頁面底部的某個閾值(dthreshold),以判斷表格是否接近頁面底部。
  4. is_table_ending_on_page(pdf_path, page, npage):
    這個函數(shù)接收PDF文件路徑、pdfplumber的頁面對象和頁碼,使用camelot庫讀取下一頁的表格。如果存在表格,它檢查最后一個表格是否接近當(dāng)前頁面的底部,并返回一個布爾值和最后一行的列數(shù)。
  5. is_table_starting_on_page(pdf_path, page, npage):
    與is_table_ending_on_page類似,但檢查的是下一個頁面的第一個表格是否從頁面頂部開始,并返回一個布爾值和第一行的列數(shù)。
def is_first_table_at_top_of_page(page):
    page_height = page.height
    table_bounds_list = get_table_bounds(page)
    if table_bounds_list:
        first_table_bounds = table_bounds_list[0]
        is_first_table_at_top = first_table_bounds[1] < topthreshold * page_height
        return {
            "is_first_table_at_top": is_first_table_at_top,
        }
    else:
        return {
            "is_first_table_at_top": False,
        }


def is_last_table_at_bottom_of_page(page):
    page_height = page.height
    table_bounds_list = get_table_bounds(page)
    if table_bounds_list:
        last_table_bounds = table_bounds_list[-1]
        is_last_table_at_bottom = last_table_bounds[3] > dthreshold * page_height
        return {
            "is_last_table_at_bottom": is_last_table_at_bottom,
        }
    else:
        return {
            "is_last_table_at_bottom": False,
        }


def get_table_bounds(page):
    table_bounds_list = []
    tables = page.find_tables()
    for table in tables:
        x0, top, x1, bottom = table.bbox
        table_bounds_list.append((x0, top, x1, bottom))
    return table_bounds_list


def is_table_ending_on_page(pdf_path, page, npage):
    tables = camelot.read_pdf(pdf_path, pages=str(npage + 1))
    if not tables:
        return False, 0
    table = tables[-1]
    last_row = table.df.iloc[-1]
    last_table_result = is_last_table_at_bottom_of_page(page)
    return last_table_result['is_last_table_at_bottom'], len(last_row)


def is_table_starting_on_page(pdf_path, page, npage):
    tables = camelot.read_pdf(pdf_path, pages=str(npage + 1))
    if not tables:
        return False, 0
    table = tables[0]
    first_row = table.df.iloc[0]
    first_table_result = is_first_table_at_top_of_page(page)
    return first_table_result['is_first_table_at_top'], len(first_row)

4.識別PDF文件中跨頁的表格并將其合并

  1. 獲取PDF文件列表:
    使用列表推導(dǎo)式和os.listdir(path)函數(shù),篩選出所有以.pdf結(jié)尾的文件,形成一個包含所有PDF文件名的列表。
  2. 遍歷PDF文件: 對于每一個PDF文件,首先打印一條信息表明正在處理哪個文件。
  3. 構(gòu)造完整的PDF文件路徑。
    使用camelot.read_pdf函數(shù)讀取整個PDF文檔中的所有表格。
  4. 檢查跨頁表格: 使用pdfplumber庫打開PDF文件,遍歷除了最后一頁的所有頁面。
    對于每一頁,使用之前定義的函數(shù)is_table_ending_on_page和is_table_starting_on_page來檢查表格是否在該頁結(jié)束并在下一頁開始。 如果發(fā)現(xiàn)表格跨頁,并且連續(xù)兩頁的表格具有相同的列數(shù)(意味著它們可能是同一表格的一部分),則記錄這對頁面號。
  5. 合并跨頁表格: 如果找到了跨頁的表格,代碼會嘗試合并這些表格。 使用一個列表current_merge來跟蹤需要合并的頁面范圍。
    當(dāng)遇到新的跨頁表格序列時,如果前一個序列尚未合并,先執(zhí)行合并操作。
# 獲取文件夾中所有PDF文件的列表
pdf_files = [f for f in os.listdir(path) if f.endswith('.pdf')]
print(pdf_files)

# 遍歷每個PDF文件并使用Camelot讀取
for pdf_file in pdf_files:
    cross_page_tables = []
    print(f'開始對{pdf_file}進行表格識別')
    pdf_path = os.path.join(path, pdf_file)
    tables = camelot.read_pdf(pdf_path, pages='all')
    # 導(dǎo)出pdf所有的表格為json文件
    tables.export(f'{pdf_file}.json', f='json')  # json, excel, html, sqlite, markdown
    with pdfplumber.open(pdf_path) as pdf:
        for i, page in enumerate(pdf.pages[:-1]):
            table_ending, ending_col_count = is_table_ending_on_page(pdf_path, page, i)
            if i+ 1 < len(pdf.pages):
                table_starting, starting_col_count = is_table_starting_on_page(pdf_path, page, i + 1)
                if table_ending and table_starting and ending_col_count == starting_col_count:
                    cross_page_tables.append((i, i + 1))
                    print(f" {pdf_file}的表格在第 {i + 1} 頁和第 {i + 2} 頁之間跨頁,并且最后一行和下一頁的第一行列數(shù)相同")

        # 處理所有跨頁表格
        if cross_page_tables:
            current_merge = []
            for (start_page, end_page) in cross_page_tables:
                if not current_merge or start_page == current_merge[-1]:
                    current_merge.append(end_page)
                else:
                    # 合并當(dāng)前跨頁表格
                    merged_table = camelot.read_pdf(pdf_path, pages=",".join(map(str, [p + 1 for p in current_merge])))
                    full_df = pd.concat([table.df for table in merged_table])
                    full_df.to_csv(f'{pdf_file}_merged_{"_".join(map(str, [p + 1 for p in current_merge]))}.csv',
                                   index=False)
                    full_df.to_json(f'{pdf_file}_merged_{"_".join(map(str, [p + 1 for p in current_merge]))}.json',
                                    orient='records')
                    print(f'合并表格已保存為 {pdf_file}_merged_{"_".join(map(str, [p + 1 for p in current_merge]))}.csv 和 {pdf_file}_merged_{"_".join(map(str, [p + 1 for p in current_merge]))}.json')
                    # 重置合并列表
                    current_merge = [start_page, end_page]

5.總結(jié)

通過上述步驟,可以自動化地處理大量的PDF文檔,識別和合并跨頁表格,大大提高了數(shù)據(jù)處理的效率和準(zhǔn)確性。這種方法特別適用于需要頻繁分析大量文檔的工作場景。

到此這篇關(guān)于使用Python有效識別和合并PDF的跨頁表格的文章就介紹到這了,更多相關(guān)Python識別和合并PDF跨頁表格內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python?的矩陣傳播機制Broadcasting和矩陣運算

    Python?的矩陣傳播機制Broadcasting和矩陣運算

    這篇文章主要介紹了Python?的矩陣傳播機制Broadcasting和矩陣運算,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-06-06
  • Python+turtle繪制七夕表白玫瑰花

    Python+turtle繪制七夕表白玫瑰花

    七夕節(jié),又稱“七巧節(jié)”“女兒節(jié)”“乞巧節(jié)”等,是中國民間的傳統(tǒng)節(jié)日。一年一度的七夕又快到了,用Python畫一朵玫瑰花送給你的那個TA吧
    2022-08-08
  • python中wordcloud安裝的方法小結(jié)

    python中wordcloud安裝的方法小結(jié)

    這篇文章主要介紹了安裝python中wordcloud的幾種方法,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • 淺談Python訪問MySQL的正確姿勢

    淺談Python訪問MySQL的正確姿勢

    這篇文章主要介紹了淺談Python訪問MySQL的正確姿勢,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • python if not in 多條件判斷代碼

    python if not in 多條件判斷代碼

    學(xué)了一段時間python,發(fā)現(xiàn)有時遇到多條件判斷的時候,覺得使用單純的in的話比較麻煩,需要多個條件,今天又遇到一個,網(wǎng)上搜索了一下,也有同學(xué)和我遇到相同的問題,記錄一下
    2016-09-09
  • Python結(jié)合多線程與協(xié)程實現(xiàn)高效異步請求處理

    Python結(jié)合多線程與協(xié)程實現(xiàn)高效異步請求處理

    在現(xiàn)代Web開發(fā)和數(shù)據(jù)處理中,高效處理HTTP請求是關(guān)鍵挑戰(zhàn)之一,本文將結(jié)合Python異步IO(asyncio)和多線程技術(shù),探討如何優(yōu)化請求處理邏輯,解決常見的線程事件循環(huán)問題,有需要的小伙伴可以根據(jù)需求進行選擇
    2025-04-04
  • python+mysql實現(xiàn)學(xué)生信息查詢系統(tǒng)

    python+mysql實現(xiàn)學(xué)生信息查詢系統(tǒng)

    這篇文章主要為大家詳細介紹了python+mysql實現(xiàn)學(xué)生信息查詢系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-02-02
  • 在Python中使用gRPC的方法示例

    在Python中使用gRPC的方法示例

    這篇文章主要介紹了在Python中使用gRPC的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08
  • python字符串拼接和列表拼接方式

    python字符串拼接和列表拼接方式

    這篇文章主要介紹了python字符串拼接和列表拼接方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • Python利用Diagrams繪制漂亮的系統(tǒng)架構(gòu)圖

    Python利用Diagrams繪制漂亮的系統(tǒng)架構(gòu)圖

    Diagrams  是一個基于Python繪制云系統(tǒng)架構(gòu)的模塊,它能夠通過非常簡單的描述就能可視化架構(gòu)。本文將利用它繪制漂亮的系統(tǒng)架構(gòu)圖,感興趣的可以了解一下
    2023-01-01

最新評論

宣威市| 新蔡县| 贵阳市| 友谊县| 广东省| 南城县| 五华县| 建瓯市| 福泉市| 安吉县| 会宁县| 涟水县| 胶南市| 临澧县| 宁晋县| 永兴县| 河西区| 文成县| 屏南县| 江北区| 禹州市| 金川县| 泰顺县| 白城市| 曲麻莱县| 漾濞| 松潘县| 岳西县| 梓潼县| 民县| 衢州市| 伊春市| 泰州市| 营山县| 会理县| 醴陵市| 嘉黎县| 林甸县| 子洲县| 云梦县| 时尚|