• python读取pdf表格并合并为excel


    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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164

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

  • 相关阅读:
    基于Java+SpringBoot+Vue+echarts健身房管理系统设计和实现
    从零开始, 开发一个 Web Office 套件 (3): 鼠标事件
    MongoDB:数据备份的备份和恢复
    牛客刷题<22>根据状态转移图实现时序电路
    骑士精神 ← IDA*
    nginx调度器
    Zabbix自定义脚本监控MySQL数据库
    大型语言模型,真的能够理解人类吗?
    jQuery之效果、数据缓存、属性操作、内容文本值、元素操作
    PyCharm及第三方库安装教程
  • 原文地址:https://blog.csdn.net/weixin_43686599/article/details/137982346