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

使用Python有效識(shí)別和合并PDF的跨頁(yè)表格

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

前言

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

1.所需庫(kù)與安裝

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

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

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

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'
# 閾值,判斷表格是否位于頁(yè)面頂部或底部
topthreshold = 0.2
dthreshold = 0.8
# 將word文件轉(zhuǎn)化為PDF
wdFormatPDF = 17

步驟詳解

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

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

將文檔從 Word 轉(zhuǎn)換為 PDF 的方法非常適合批量轉(zhuǎn)換,即當(dāng)你有多個(gè)需要自動(dòng)轉(zhuǎn)換的 Word 文檔時(shí)。但是請(qǐng)注意,根據(jù)文檔的數(shù)量和大小,這個(gè)操作可能會(huì)比較慢,因?yàn)槊看无D(zhuǎn)換都涉及到打開(kāi) 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 庫(kù)是針對(duì) Windows 環(huán)境的,依賴(lài)于機(jī)器上安裝的 Microsoft Word。

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

  1. get_table_bounds(page):
    這個(gè)函數(shù)接收一個(gè)PDF頁(yè)面對(duì)象,使用pdfplumber庫(kù)的find_tables()方法找到頁(yè)面上的所有表格,并返回一個(gè)包含每個(gè)表格邊界坐標(biāo)的列表。每個(gè)表格的邊界由一個(gè)四元組表示,包含左、頂、右、底的坐標(biāo)。
  2. is_first_table_at_top_of_page(page):
    這個(gè)函數(shù)接收一個(gè)PDF頁(yè)面對(duì)象,計(jì)算頁(yè)面高度,然后獲取第一個(gè)表格的邊界,判斷這個(gè)表格的頂部位置是否低于頁(yè)面頂部的某個(gè)閾值(topthreshold)。如果低于這個(gè)閾值,意味著表格可能從頁(yè)面的頂部開(kāi)始,返回一個(gè)字典,指示這個(gè)條件是否滿(mǎn)足。
  3. is_last_table_at_bottom_of_page(page):
    類(lèi)似于is_first_table_at_top_of_page,但檢查的是最后一個(gè)表格的底部位置是否高于頁(yè)面底部的某個(gè)閾值(dthreshold),以判斷表格是否接近頁(yè)面底部。
  4. is_table_ending_on_page(pdf_path, page, npage):
    這個(gè)函數(shù)接收PDF文件路徑、pdfplumber的頁(yè)面對(duì)象和頁(yè)碼,使用camelot庫(kù)讀取下一頁(yè)的表格。如果存在表格,它檢查最后一個(gè)表格是否接近當(dāng)前頁(yè)面的底部,并返回一個(gè)布爾值和最后一行的列數(shù)。
  5. is_table_starting_on_page(pdf_path, page, npage):
    與is_table_ending_on_page類(lèi)似,但檢查的是下一個(gè)頁(yè)面的第一個(gè)表格是否從頁(yè)面頂部開(kāi)始,并返回一個(gè)布爾值和第一行的列數(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.識(shí)別PDF文件中跨頁(yè)的表格并將其合并

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

# 遍歷每個(gè)PDF文件并使用Camelot讀取
for pdf_file in pdf_files:
    cross_page_tables = []
    print(f'開(kāi)始對(duì){pdf_file}進(jìn)行表格識(shí)別')
    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} 頁(yè)和第 {i + 2} 頁(yè)之間跨頁(yè),并且最后一行和下一頁(yè)的第一行列數(shù)相同")

        # 處理所有跨頁(yè)表格
        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)前跨頁(yè)表格
                    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é)

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

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

相關(guān)文章

  • Python?的矩陣傳播機(jī)制Broadcasting和矩陣運(yùn)算

    Python?的矩陣傳播機(jī)制Broadcasting和矩陣運(yùn)算

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

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

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

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

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

    淺談Python訪問(wèn)MySQL的正確姿勢(shì)

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

    python if not in 多條件判斷代碼

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

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

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

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

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

    在Python中使用gRPC的方法示例

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

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

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

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

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

最新評(píng)論

宝清县| 阿合奇县| 中山市| 柳江县| 阿拉善左旗| 醴陵市| 东海县| 哈密市| 洪雅县| 朝阳区| 长垣县| 贵定县| 绥宁县| 拜城县| 石屏县| 长寿区| 巴青县| 乌兰浩特市| 溆浦县| 荥经县| 富川| 金华市| 德格县| 涟源市| 徐州市| 项城市| 永城市| 茌平县| 杭锦旗| 泊头市| 巴林左旗| 湖口县| 云霄县| 定西市| 苗栗市| 桓台县| 偃师市| 察哈| 石首市| 嘉峪关市| 武宁县|