从PDF文件获取表格中的数据,也是日常办公容易涉及到的一项工作。一个一个复制吧,效率确实太低了。用Python从PDF文档中提取表格数据,并写入Excel文件,灰常灰常高效

上市公司的年报往往包含几百张表格,用它作为例子再合适不过,搞定这个,其他含表格的PDF都是小儿科了。今天以"保利地产年报"为例,这个PDF文档中有321页含有表格,总表格数超过这个数了。 先导入PDF读取模块pdfplumber,随便挑一页看下表格数据的结构。如下,我们挑了第4页pages[3]来读取其中的表格,并显示。这里读取表格,用到了extract_tables(),即默认每页有多个表格。它会将单个表格的数据按行读取存入列表,再将每个表格的所有数据汇总存到一个上一级列表,最后将所有表格的数据汇总到一个大列表。而extract_table()方法则只能读一张表,当一个页面有多张表,就默认选第一个,因此会漏掉后面的。而且它们的数据结构也不同,差异如下。

“保利地产年报”第四页如图所示,读取的结果存到列表table,显示如下。

#观察读取出来的表格的数据结构import pdfplumberwith pdfplumber.open("保利地产年报.pdf") as p:    page = p.pages[3] #选取第4页(起始页为0)    table = page.extract_tables() #多表格读取,存为嵌套列表    print(table)[[['', '常用词语释义', None, None, None, None, None, ''], ['中国证监会', None, '', '指', '', '', '中国证券监督管理委员会', ''], ['国资委', None, '', '指', '', '', '国务院国有资产监督管理委员会', ''], ['上交所', None, '', '指', '', '上海证券交易所', None, None], ['公司、本公司、保利地产', None, '指', None, None, '保利发展控股集团股份有限公司,原名称保利房\n地产(集团)股份有限公司', None, None], ['报告期、本报告期', None, '', '指', '', '2018年度', None, None], ['元、万元、亿元', None, '', '指', '', '人民币元、人民币万元、人民币亿元', None, None]], [['公司的中文名称', '保利发展控股集团股份有限公司'], ['公司的中文简称', '保利地产'], ['公司的外文名称', 'Poly Developments and Holdings Group Co., Ltd.'], ['公司的外文名称缩写', 'PDH'], ['公司的法定代表人', '宋广菊']], [['', '董事会秘书', '证券事务代表'], ['姓名', '黄海', '尹超'], ['联系地址', '广东省广州市海珠区阅江中路688号保利国际广场北塔33层董事会办公室', None], ['电话', '020-89898833', None], ['传真', '020-89898666-8831', None], ['电子信箱', 'stock@polycn.com', None]], [['公司注册地址', '广州市海珠区阅江中路688号保利国际广场30-33层'], ['公司注册地址的邮政编码', '510308'], ['公司办公地址', '广州市海珠区阅江中路688号保利国际广场北塔30-33层'], ['公司办公地址的邮政编码', '510308'], ['公司网址', 'www.polycn.com;www.gzpoly.com'], ['电子信箱', 'stock@polycn.com']], [['公司选定的信息披露媒体名称', '《中国证券报》、《上海证券报》、《证券时报》'], ['登载年度报告的中国证监会指定网站的网址', 'www.sse.com.cn'], ['公司年度报告备置地点', '公司董事会办公室']]]

确保可正常读取表格,以及了解读取出来的表格的数据结构,下面就可以一次性读取出所有表格,并存入Excel文件中了。导入相应模块,然后使用pdfplumber打开PDF文件。使用Workbook()新建Excel工作簿,然后使用remove()将其自带的工作表删除。因为我们想用PDF文件中表格所在的页码给相应的Excel工作表命名,以便二者的编号一致,方便后续查询。所以需要使用enumerate()给PDF的页从1开始编号。然后使用extract_tables()获取表格数据。 当然,如果当页没有表格,则extract_tables()获得的是空值None。在后续的操作中,空值会报错,所以加入if语句来做个判断。只有当列表tables不为空,即里面有货的时候,才建新的Excel表格,并执行后续的写入操作。列表tables若为空(即当页没有表格),则直接跳到下一页。 当发现当页有表格后,新建一个Excel表,以“Sheet”加上此时PDF的页码(比如“Sheet3”)命名。在写入数据时,先用一个for循环获得单个表格的数据,再用第二个for循环获得表格中一行的数据,然后写入Excel表。最后保存数据。由于表格太多,程序运行时间较长,大约需要3分钟。

import pdfplumberfrom openpyxl import Workbook    with pdfplumber.open("保利地产年报.pdf") as p:    wb = Workbook() #新建excel工作簿    wb.remove(wb.worksheets[0])#删除工作簿自带的工作表    for index,page in enumerate(p.pages,start = 1): #从1开始给所有页编号        tables = page.extract_tables() #读取表格        if tables: #判断是否存在表格,若不存在,则不执行下面的语句            ws = wb.create_sheet(f"Sheet{index}") #新建工作表,表名的编号与表在PDF中的页码一致            for table in tables: #遍历所有列表                for row in table: #遍历列表中的所有子列表,里面保存着行数据                    ws.append(row) #写入excel表    wb.save("保利地产年报表格.xlsx")

数百个表格就这样潇洒地复制到Excel表格中了

如果想要指定某个表格,在提取数据的时候指定页码即可。但如果想批量导出大量不同公司的年报的指定表格,则需要使用关键词定位了。还好,无论深圳市场还是上海市场,公司的年报中的标题基本都是唯一的,这给我们用标题做关键词提供了方便。假设我们需要提取公司“主要会计数据”下面的表格,则用关键词“主要会计数据”定位即可。如下以此为例进行操作。

import osimport pdfplumberfrom openpyxl import Workbook    

path='PDF'  #文件所在文件夹files = [path+"\\"+i for i in os.listdir(path)] #获取文件夹下的文件名,并拼接完整路径key_words = "主要会计数据"

for file in files:    with pdfplumber.open(file) as p:        wb = Workbook() #新建excel工作簿        wb.remove(wb.worksheets[0])#删除工作簿自带的工作表

        #获取关键词所在页及下一页的页码        pages_wanted = []        for index,page in enumerate(p.pages): #从0开始给所有页编号            if key_words in page.extract_text():                pages_wanted.append(index)                pages_wanted.append(index+1)                break

        #提取指定页码里的表格        for i in pages_wanted:                 page = p.pages[i]            tables = page.extract_tables() #读取表格            if tables: #判断是否存在表格,若不存在,则不执行下面的语句                ws = wb.create_sheet(f"Sheet{i+1}") #新建工作表,表名的编号与表在PDF中的页码一致                for table in tables: #遍历所有列表                    for row in table: #遍历列表中的所有子列表,里面保存着行数据                        ws.append(row) #写入excel表        wb.save("Excel\\{}.xlsx".format(file.split("\\")[1].split(".")[0]))

以上,增加了一段获取关键词所在页码及下一页的页码的程序。之所以要获取关键词下一页页码,是因为有些表格会跨页,为了不遗漏数据,宁愿多获取一点。一旦找到关键词所在页,马上用break停止for循环。后面再遍历pages_wanted里面储存的页码,提取表格并写入Excel文件,并保存即可。批量获取的指定内容保存在Excel文件夹下。

如果您有需要处理的问题,可发邮件到我邮箱:donyo@qq.com,一起探讨解决方案。微信公众号输入“源文件”提取所有源文件及资料。

最好的赞赏就是点亮下方“在看”,多给PythonOffice积攒一点人气哈!

python中提取几列_Python一键提取PDF中的表格到Excel(实例50)相关推荐

  1. android 抓取webview中的所有图片_如何一键提取PDF文档中的所有图片?

    原标题:如何一键提取PDF文档中的所有图片? 目前PDF文档被大家广泛应用,主要是因为PDF文档在传输和转换的过程中比较稳定,所以PDF格式几乎是办公文件格式的首选.大家都知道PDF文档转换格式以及编 ...

  2. python dataframe取一列_python - 从pandas DataFrame列标题中获取列表

    python - 从pandas DataFrame列标题中获取列表 我想从pandas DataFrame中获取列标题列表. DataFrame将来自用户输入,因此我不知道将会有多少列或将调用它们. ...

  3. python中读取指定的行和列_Python怎么获取excle中指定行和列的值?

    ''' https://www.cnblogs.com/xiazhenyu/ *** 学而思之.思而记之.记而习之 *** ''' f="dict_file.txt" #定义文件名 ...

  4. python xpath提取td标签_Python Xpath 提取html整个元素(标签与内容)

    提取html某标签中文字时,文字中含有:"2O5",导致提取的文字不符合预期. 解决方法: #coding=utf-8 from lxml import etree from HT ...

  5. python每行乘列表_python – 在pandas数据帧中查找每行的两列列表中哪一列的最快方法...

    我正在寻找最快的方法来做到以下几点: 我们有一个pd.DataFrame: df = pd.DataFrame({ 'High': [1.3,1.2,1.1], 'Low': [1.3,1.2,1.1 ...

  6. python dataframe取一列_python DataFrame列运算

    展开全部 用2113pandas中的DataFrame时选取行或列: 1.import numpy as npimport pandas as pdfrom pandas import Sereis, ...

  7. python三引号 内部变量_python在三引号中使用变量

    1.定义和运算: 变量名 = 值 定义变量举例: # 定义一个变量 myCar = "比亚迪F0" # 输出一个变量 print(myCar) 变量之间的简单运算举例: price ...

  8. python数组赋值给变量_Python:将数组中的元素导出到变量中 (unpacking)

    问题 你需要将数组(list)或元组(tuple)中的元素导出到N个变量中. 解决方案 任何序列都可以通过简单的变量赋值方式将其元素分配到对应的变量中,唯一的要求就是变量的数量和结构需要和序列中的结构 ...

  9. python列表中怎么去掉空值_Python 如何删除列表中的空值

    今天在获取android性能CPU测试数据时,发现这么一个问题: # -*- coding:utf-8 -*- import os import time cpuInfo = os.popen(r'a ...

最新文章

  1. 深入学习Heritrix---解析CrawlController
  2. python list去掉引号_python的一些易忘知识点
  3. java日志模块_Java源码初探_logging日志模块实现
  4. python中小数_比较python中的小数
  5. JavaScript 如何打败众语言,成为 Node 的实现语言?
  6. 20世纪50年代电子计算机的功能元件,第1章 计算机基础知识习题答案
  7. 6. ubuntu 下 mysql 数据库迁移
  8. oracle 已知表名查询所属的schema_sql注入联合查询总结
  9. Lua FFI 实战
  10. 用accelstepper库控制28BYJ-48步进电机(快慢运动切换)
  11. Java如何找出数组中前k个高频元素
  12. 海大计算机考研经验,关于考研中国海洋大学的一些小经验
  13. PostgreSQL COALESCE 和 NULLIF 函数
  14. 汇编总结:mov指令
  15. c语言中用什么表示真假,C语言中如何表示“真”和“假”?系统如何判断一个量的“真”和“假”?...
  16. 图解 Panda3D引擎开发入门
  17. 跟着大宇学RabbimtMQ目录贴
  18. c++项目-----演讲比赛--附详细过程
  19. 概率预测的评估方法简介
  20. 模拟根据后端返回列表数据,先包装成树结构,包装路由数据格式。

热门文章

  1. docker kibana:7.14.2
  2. Springboot2.x +JPA 集成 Apache ShardingSphere 分表+读写分离
  3. linux根文件系统 /etc/resolv.conf 文件详解
  4. linux环境安装Kafka最新版本 jdk1.8
  5. 使用IntelliJ IDEA 2020 高效开发 springboot项目
  6. form表单提交,后台实体类接收转义问题 解决方案
  7. 1450. 在既定时间做作业的学生人数
  8. C语言 文件读写 fputc 函数 - C语言零基础入门教程
  9. Python zip函数 - Python零基础入门教程
  10. BugkuCTF-WEB题源码