python读取pdf表格并合并为excel

python 复制代码
import pdfplumber
import pandas as pd
import os
from openpyxl import load_workbook
from datetime import datetime
# page_chars最尾部的非空字符
def tail_not_space_char(page_chars):
    i = -1
    while page_chars[i].get('text').isspace():
        i = i - 1
        # print(page_chars[i].get('text'), i)
    return page_chars[i]
 
 
# 返回列表最头部的非空字符
def head_not_space_char(page_chars):
    i = 0
    while page_chars[i].get('text').isspace():
        i += 1
        # print(page_chars[i].get('text'), i)
    return page_chars[i]
 

# 将pdf表格数据抽取到文件中
def extract_tables(input_file_path, output_excel_path):
    pdfList=[] 
    print("========================================表格抽取开始========================================")
    # 读取pdf文件,保存为pdf实例
    pdf = pdfplumber.open(input_file_path)
 
    # 存储每个页面最底部字符的y0坐标
    y0_bottom_char = []
    # 存储每个页面最底部表格中最底部字符的y0坐标
    y0_bottom_table = []
    # 存储每个页面最顶部字符的y1坐标
    y1_top_char = []
    # 存储每个页面最顶部表格中最顶部字符的y1坐标
    y1_top_table = []
    # 存储所有页面内的表格文本
    text_all_table = []
    # 获取当前日期为转换后的文件名
    current_datetime = datetime.now()

    # 格式化为"YYYY-MM-DD HH:MM:SS"的字符串
    formatted_datetime = current_datetime.strftime("%Y-%m-%d %H-%M-%S")
    fileName=formatted_datetime+".xlsx"
    # print("格式化后的日期时间:", formatted_datetime)

    # 访问每一页
    print("1===========开始抽取每页顶部和底部字符坐标及表格文本===========1")
    for page in pdf.pages:
        # table对象,可以访问其row属性的bbox对象获取坐标
        table_objects = page.find_tables()
        text_table_current_page = page.extract_tables()
        if text_table_current_page:
            text_all_table.append(text_table_current_page)
            # 获取页面最底部非空字符的y0
            y0_bottom_char.append(tail_not_space_char(page.chars).get('y0'))
            # 获取页面最底部表格中最底部字符的y0,table对象的bbox以左上角为原点,而page的char的坐标以左下角为原点,可以用page的高度减去table对象的y来统一
            y0_bottom_table.append(page.bbox[3] - table_objects[-1].bbox[3])
            # 获取页面最顶部字符的y1
            y1_top_char.append(head_not_space_char(page.chars).get('y1'))
            # 获取页面最顶部表格中最底部字符的y1
            y1_top_table.append(page.bbox[3] - table_objects[0].bbox[1])
    print("1===========抽取每页顶部和底部字符坐标及表格文本结束===========1")
 
    # 处理跨页面表格,将跨页面表格合并,i是当前页码,对于连跨数页的表,应跳过中间页面,防止重复处理
    print("2===========开始处理跨页面表格===========2")
    i = 0
    while i < len(text_all_table):
        print("处理页面{0}/{1}".format(i+1, len(text_all_table)))
        # 判断当前页面是否以表格结尾且下一页面是否以表格开头,若都是则说明表格跨行,进行表格合并
        # j是要处理的页码,一般情况是当前页的下一页,对于连跨数页情况,也可以是下下一页,跨页数为k
        # 若当前页是最后一页就不用进行处理
        if i + 1 >= len(text_all_table):
            break
        j = i + 1
        k = 1
        # 要处理的页为空时退出
        while text_all_table[j]:
            if y0_bottom_table[i] <= y0_bottom_char[i] and y1_top_table[j] >= y1_top_table[j]:
                # 当前页面最后一个表与待处理页面第一个表合并
                text_all_table[i][-1] = text_all_table[i][-1] + text_all_table[j][0]
                text_all_table[j].pop(0)
                # 如果待处理页面只有一个表,就要考虑下下一页的表是否也与之相连
                if not text_all_table[j] and j + 1 < len(text_all_table) and text_all_table[j + 1]:
                    k += 1
                    j += 1
                else:
                    i += k
                    break
            else:
                i += k
                break
    print("2===========处理跨页面表格结束===========2")
 
 
    # 保存excel
    print("3===========开始保存表格到excel===========3")
    
    for page_num, page in enumerate(text_all_table):
        for table_num, table in enumerate(page):
            print("处理表格页面{0}/表格{1}".format(page_num, table_num))
            if table:
                table_df = pd.DataFrame(table[1:], columns=table[0])
                final_filename = output_excel_path + "page{0}_table{1}.xlsx".format(page_num, table_num)
                table_df.to_excel(final_filename)
                print("生成文件:", final_filename)
                pdfList.append(final_filename)
    print("3===========保存表格到excel结束===========3")
    print("4===========开始合并excel===========4")
    # print(pdfList)
    
# 合并所有Excel文件
    all_data = []
    for file in pdfList:
        file_path = os.path.join(file)
        df = pd.read_excel(file_path)
        all_data.append(df)
    
    # 合并数据帧
    combined_df = pd.concat(all_data, ignore_index=True)
    # 保存到新的Excel文件
    combined_df.to_excel(fileName, index=False)
    wb = load_workbook(fileName)
    sheet = wb.active
    
    # 获取"A"列的范围
    column = sheet['A']
    
    # 生成序号并写入"A"列
    for i, cell in enumerate(column, start=0):
        cell.value = i
    
    # 保存修改后的Excel文件
    wb.save(fileName)
    print("5===========合并excel结束===========5")
    for file in pdfList:
        os.remove(file)
# # 保存txt
    # print("4===========开始保存表格到txt===========4")
    # for page_num, page in enumerate(text_all_table):
    #     for table_num, table in enumerate(page):
    #         print("处理表格页面{0}/表格{1}".format(page_num, table_num))
    #         if table:
    #             table_df = pd.DataFrame(table[1:], columns=table[0])
    #             final_filename = output_excel_path + "page{0}_table{1}.txt".format(page_num, table_num)
 
    #             with open(final_filename,"w") as f:
    #                 f.write(table_df.to_string())
    #                 f.close()
    #             # print("生成文件:", final_filename)
    # print("4===========保存表格到txt结束===========4")
 
 
    # print("========================================表格抽取结束========================================")
 
if __name__ == '__main__':
 
    # 抽取表格
    input_file = "pdf.pdf"
    output_excel_path = ""
 
    extract_tables(input_file, output_excel_path)

方法也是修改csdn的一个大佬的 作者是吧跨页得都给弄成了一个个得excel 然后我给重新合并设置了序号 别的没加什么东西 大佬文章地址

相关推荐
笨鸟先飞,勤能补拙1 小时前
AI 赋能网络安全:技术全景、成熟度评估与实战案例
人工智能·python·安全·web安全·网络安全·sqlite·github
长和信泰光伏储能2 小时前
京津冀光伏发电:绿色能源的未来之路
python·能源
浦信仿真大讲堂2 小时前
从重复操作到自动化闭环:如何让 CST 与 Python 真正协同起来
python·自动化·cst·仿真软件·达索软件
hPw0eKIqD2 小时前
使用二次封装的Excel COM 组件操作Excel\WPS ET中的区域、行和列
excel·wps
Gu Gu Study3 小时前
ScoutLoop开放域深度研究引擎(agent的初步设计想法)
人工智能·python
卷无止境3 小时前
写代码这件事,到底该讲究点什么?
后端·python
卷无止境3 小时前
循环复杂度到底在算什么,Python 代码怎么才能写得让人一看就懂
后端·python
lpfasd1234 小时前
MediaCrawler 项目深度分析
chrome·python·chrome devtools
Dxy12393102164 小时前
Python项目打包成EXE完整教程(PyInstaller实战避坑)
开发语言·python
bamb005 小时前
一个项目带你入门AI应用开发01
python