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 = -1while 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 = 0while 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)# 获取页面最底部非空字符的y0y0_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])# 获取页面最顶部字符的y1y1_top_char.append(head_not_space_char(page.chars).get('y1'))# 获取页面最顶部表格中最底部字符的y1y1_top_table.append(page.bbox[3] - table_objects[0].bbox[1])print("1===========抽取每页顶部和底部字符坐标及表格文本结束===========1")# 处理跨页面表格,将跨页面表格合并,i是当前页码,对于连跨数页的表,应跳过中间页面,防止重复处理print("2===========开始处理跨页面表格===========2")i = 0while i < len(text_all_table):print("处理页面{0}/{1}".format(i+1, len(text_all_table)))# 判断当前页面是否以表格结尾且下一页面是否以表格开头,若都是则说明表格跨行,进行表格合并# j是要处理的页码,一般情况是当前页的下一页,对于连跨数页情况,也可以是下下一页,跨页数为k# 若当前页是最后一页就不用进行处理if i + 1 >= len(text_all_table):breakj = i + 1k = 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 += 1j += 1else:i += kbreakelse:i += kbreakprint("2===========处理跨页面表格结束===========2")# 保存excelprint("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 然后我给重新合并设置了序号 别的没加什么东西 大佬文章地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/1108.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

asp.net core rabbitmq的基本使用

要在 .NET Core 应用程序中实现使用 RabbitMQ 发送和接收消息的简单示例&#xff0c;首先需要在开发机器上安装 RabbitMQ 服务器并运行它。接下来&#xff0c;我们将创建两个控制台应用程序&#xff1a;一个用于发送消息&#xff08;生产者&#xff09;&#xff0c;另一个用于接…

灵途科技荣获省级“专精特新”企业认定!

4月8日&#xff0c;湖北省经济和信息化厅发布了湖北省第六批专精特新中小企业公示名单&#xff0c;泛自动驾驶领域光电感知专家灵途科技荣获省级“专精特新”企业认定。 “专精特新”自2021年在全国各省市范围内贯彻执行&#xff0c;旨在推动形成一批具备专业化、精细化优势&a…

设计模式学习笔记 - 开源实战三(中):剖析Google Guava中用到的设计模式

概述 上篇文章&#xff0c;我通过 Google Guava 这样一个优秀的开源类库&#xff0c;讲解了如何在业务开发中&#xff0c;发现跟业务无关、可以复用的通用功能模块&#xff0c;并将它们抽离出来&#xff0c;设计成独立的类库、框架或功能组件。 本章再来学习下&#xff0c;Go…

【Hadoop3.3.6全分布式环境搭建】

说明: 完成Hadoop全分布式环境搭建,需准备至少3台虚拟机(master slave01 slave02)环境: VMWare + Centos7 + JDK1.8+ Hadoop3.3.6主机规划: 主节点:master从节点:slave01 , slave02 一、准备工作 1、所有主机安装jdk 上传jdk-8u171-linux-x64.tar.gz到/root目录下,然后…

AWS SAP(Certified Solutions Architect- Professional)认证题库详解(一)

很多朋友在做AWS认证的时候拿到题库之后,却不理解正确答案的原理,这里针对每一条答案都给了一个非常详细的解释,同时也会积累丰富的云计算架构的实践经验,保证看得懂,记得住,看完一遍之后就可以去考试了。  问题1 一家公司使用Amazon在单个m4.2xlarge AmazonEC2实例上…

改变图片的DPI和 清晰度

投稿时&#xff0c;我们的图片不满足要求&#xff0c;经常需要修改&#xff0c;这个博主讲解了几种方法&#xff0c;非常好。 【科研制图】如何快速修改图片符合投稿要求(分辨率300DPI等)及AI智能绘制高质量图片&#xff08;Upscayl软件&#xff09;_哔哩哔哩_bilibili

【java】26:JUnit

为什么需要 JUnit&#xff1a; 1.一个类有很多功能代码需要测试&#xff0c;为了测试&#xff0c;就需要写入到main方法中 2.如果有多个功能代码测试&#xff0c;就需要来回注销&#xff0c;切换很麻烦……… 3.如果可以直接运行一个方法&#xff0c;就方便很多&#xff0c;并且…

openssl3.2 - exp - 用base64后的字符串作为配置项的值

文章目录 openssl3.2 - exp - 用base64后的字符串作为配置项的值概述笔记配置项的值长度有限制 配置项的值不能是base64之后的直接值&#xff0c;需要处理之后才行。openssl配置项的值并不是所有可见字符都可以例子现在用的base64的类cipher_base64.hcipher_base64.cpp 现在用的…

ChatGPT研究论文提示词集合1-【主题选择与问题研究、文献综述】

点击下方▼▼▼▼链接直达AIPaperPass &#xff01; AIPaperPass - AI论文写作指导平台 目录 1.主题选择与问题定义 2.文献综述 3.书籍介绍 AIPaperPass智能论文写作平台 近期小编按照学术论文的流程&#xff0c;精心准备一套学术研究各个流程的提示词集合。总共14个步骤…

论文笔记:Large Language Model for Participatory Urban Planning

202402 arxiv 大模型城市规划 引入了一个基于LLM的多代理协作框架&#xff0c;模拟规划师和数千名具有不同特征和背景的居民&#xff0c;用于参与式城市规划——>生成考虑居民多样化需求的城市区域土地利用规划为了提高讨论的效率&#xff0c;论文采用了鱼缸讨论机制&#…

python——函数

概念 函数就是将一段具有独立功能的代码块整合到一个整体并命名&#xff0c;在需要的位置调用这个名称去完成对应的需求 定义函数 def 函数名&#xff08;参数&#xff09;&#xff1a;代码1......return 值函数名 函数名由编程人员自定义的&#xff0c;满足标识符命名规则…

建筑楼宇VR火灾扑灭救援虚拟仿真软件厂家

在传统消防安全教育方式中&#xff0c;往往存在内容枯燥、参与度低和风险大等问题&#xff0c;使得消防安全知识难以深入人心。然而&#xff0c;借助VR消防安全逃生教育系统&#xff0c;我们可以打破这一困境&#xff0c;为公众带来前所未有的学习体验。 VR消防安全逃生教育系统…

【Web】DASCTF X GFCTF 2024|四月开启第一局 题解

目录 EasySignin cool_index web1234 web4打破防了&#x1f92e;&#xff0c;应该很接近解出来了&#xff0c;感兴趣的师傅续上吧 EasySignin 先随便注册个账号登录&#xff0c;然后拿bp抓包改密码(username改成admin) 然后admin / 1234567登录 康好康的图片功能可以打SS…

OEEL图表——饼状图绘制(各国太阳能发电占比)

简介 本数据主要的目的就是进行饼状图的绘制,所使用的数据全球电力系统分布情况 数据属性 NameTypeDescriptioncountryString3-character country code corresponding to the ISO 3166-1 alpha-3 specscountry_lgStringLonger form of the country designationnameStringNam…

数据采集技术综合项目实战3(网络爬虫+数据预处理+数据可视化)附带详细步骤说明,干货满满

项目介绍及需求&#xff1a; 本项目主要是通过对b站电影弹幕进行采集并分析。1.获得弹幕高频词生成符合该电影特征、主题、角色等相关字段的词云图&#xff0c;通过词云图的方式对某部电影主题具体化。2.获取用户年内评论发布时间观生成时间的折线图&#xff0c;以便从侧面观察…

在Vue项目使用kindEditor富文本编译器以及上传图片

第一步 npm install kindeditor第二步&#xff0c;建立kindeditor.vue组件 <template><div class"kindeditor"><textarea :id"id" name"content" v-model"outContent"></textarea></div> </templa…

Android中logcat日志、ANR日志、trace日志的介绍与分析方法

Logcat日志 在Android开发中&#xff0c;日志是开发者在应用程序中添加的一种输出信息的记录方式&#xff0c;用于查看应用程序在运行时的状态、调试信息、错误信息等。Android日志可以帮助开发者追踪应用程序的行为、诊断问题并进行调试。Android提供了一系列的日志输出方法&…

使用 vllm 运行 Llama3-8b-Instruct

使用 vllm 运行 Llama3-8b-Instruct 0. 引言1. 安装 vllm2. 运行 Llama3-8b-Instruct 0. 引言 此文章主要介绍使用 vllm 运行 Llama3-8b。 1. 安装 vllm 创建虚拟环境&#xff0c; conda create -n myvllm python3.11 -y conda activate myvllm安装 Ray 和 Vllm&#xff0c…

富格林:致用查明暗箱黑幕技巧

富格林认为&#xff0c;投资现货黄金对于新手投资者来说是一个很好的选择&#xff0c;但是在进行投资之前需要了解一些基本的技巧和策略用以查明暗箱黑幕。事实上&#xff0c;现货黄金市场充满着丰富的交易机会&#xff0c;以及并存的交易风险&#xff0c;因此投资者要想在这其…

动态规划——状态压缩dp

acwing291.蒙德里安的梦想 #include<iostream> #include<cstring>using namespace std;const int N 12, M 1 << N;long long int f[N][M]; //f[i][j]表示第i列j状态有多少个可行解 int n, m; bool st[M]; //st[i]表示合并列的状态i是否合法int main() {wh…