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 然后我给重新合并设置了序号 别的没加什么东西 大佬文章地址

相关推荐
Chef_Chen3 分钟前
从0开始机器学习--Day17--神经网络反向传播作业
python·神经网络·机器学习
千澜空22 分钟前
celery在django项目中实现并发任务和定时任务
python·django·celery·定时任务·异步任务
斯凯利.瑞恩30 分钟前
Python决策树、随机森林、朴素贝叶斯、KNN(K-最近邻居)分类分析银行拉新活动挖掘潜在贷款客户附数据代码
python·决策树·随机森林
yannan201903131 小时前
【算法】(Python)动态规划
python·算法·动态规划
蒙娜丽宁1 小时前
《Python OpenCV从菜鸟到高手》——零基础进阶,开启图像处理与计算机视觉的大门!
python·opencv·计算机视觉
光芒再现dev1 小时前
已解决,部署GPTSoVITS报错‘AsyncRequest‘ object has no attribute ‘_json_response_data‘
运维·python·gpt·语言模型·自然语言处理
好喜欢吃红柚子1 小时前
万字长文解读空间、通道注意力机制机制和超详细代码逐行分析(SE,CBAM,SGE,CA,ECA,TA)
人工智能·pytorch·python·计算机视觉·cnn
小馒头学python1 小时前
机器学习是什么?AIGC又是什么?机器学习与AIGC未来科技的双引擎
人工智能·python·机器学习
神奇夜光杯2 小时前
Python酷库之旅-第三方库Pandas(202)
开发语言·人工智能·python·excel·pandas·标准库及第三方库·学习与成长
千天夜2 小时前
使用UDP协议传输视频流!(分片、缓存)
python·网络协议·udp·视频流