2025年5月17日 星期六 乙巳(蛇)年 二月十九 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Python

python pdf跨页表格转换为excel

时间:05-16来源:作者:点击数:33

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)

还有点问题 最后那个分数 小数点后面四舍五入了

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门