项目是做不完的,生活处处是项目
规划项目化,项目清单化
成都市政府官网城市机会清单发布厅
下载成都市官网城市机会清单发布大厅的清单,将之转换成excel,后续有时间实现多份清单的关键词搜索功能。待开发ing……
那么今天的任务就是实现pdf转excel
以成都市2022新经济赋能智慧蓉城建设城市机会清单为例子,我自己命名为first.pdf,并且存到了桌面。
#调包侠第一步
import pandas as pd
import numpy as np
import pdfplumber
#路径和命名
path = r'C:\Users\ty\Desktop\first.pdf'
pdf = pdfplumber.open(path)
df_gov_demand =pd.DataFrame()
df_gov_suply =df_gov_demand.copy()
df_com_demand=df_gov_demand.copy()
df_com_suply = df_gov_demand.copy()
# 每个清单的column不一样,但是一致的是都是每页表格的第一行table[0]
#为什么不写成函数?有时间再写,因为我天生不是天才码农,哭哭
writer = pd.ExcelWriter(r"C:\Users\ty\Desktop\target.xlsx")
for page in pdf.pages[1:47]:
print (page)
# 获取当前页面的全部文本信息,包括表格中的文字
# print(page.extract_text())
for table in page.extract_tables():
# print(table)
df_gov_demand=df_gov_demand.append(pd.DataFrame(table[1:],columns=table[0]),ignore_index=True)
df_gov_demand.to_excel(writer,sheet_name='df_gov_demand' ,encoding ='utf-8')
for page in pdf.pages[48:64]:
print (page)
for table in page.extract_tables():
# print(table)
df_gov_suply=df_gov_suply.append(pd.DataFrame(table[1:],columns=table[0]),ignore_index=True)
df_gov_suply.to_excel(writer,sheet_name='df_gov_suply' ,encoding ='utf-8')
for page in pdf.pages[65:88]:
print (page)
for table in page.extract_tables():
# print(table)
df_com_demand=df_com_demand.append(pd.DataFrame(table[1:],columns=table[0]),ignore_index=True)
df_com_demand.to_excel(writer,sheet_name='df_com_demand' ,encoding ='utf-8')
for page in pdf.pages[89:129]:
print (page)
for table in page.extract_tables():
df_com_suply=df_com_suply.append(pd.DataFrame(table[1:],columns=table[0]),ignore_index=True)
df_com_suply.to_excel(writer,sheet_name='df_com_suply' ,encoding ='utf-8')
writer.save()
结果弄好之后,这个表怎么不规则,我勒个擦,对不起是我的锅,同一个类型的表格竟然指标不一致。
Q:而且还有那么多合并表怎么搞???
A:还算简单,定位空白格,然后集体等于上一行的那个单元格,后续就不合并了,合并纯属为了好看!!!俺累了……
(后续大家搜索的话,大家有啥建议,是我都整理好表格再挂云服务器,还是做个数据库,实时更新?貌似有点难……)俺不知道
代码更新:尽可能写成了定义函数【2022.06.29】
pdf_name = r"first.pdf"#pdf文件名
pdf_path = r"C:/Users/ty/Desktop/"#pdf位置
pdf_file =pdf_path + pdf_name
pdf_example = pdfplumber.open(pdf_file)
df_gov_demand =pd.DataFrame()
df_gov_suply =df_gov_demand.copy()
df_com_demand=df_gov_demand.copy()
df_com_suply = df_gov_demand.copy()
sheet_name_list = ['df_gov_demand','df_gov_suply','df_com_demand','df_com_suply']#表格工作簿的名称
# 每个清单的column不一样,但是大部分清单都是每页表格的第一行table[0],除了公园城市示范区“十四五”数字经济规划机会清单这个,
# 第一行不是columns,而且中间有合并行是分类,能不能直接做一个标题放在外面,标题在表格里面真的叫人难受
# 定义得到目标data_frame的函数
# start_num 是pdf的实际页码,并不是标注的页码
def get_df(df,pdf,sheet_name,start_num,end_num,writer):
for page in pdf.pages[start_num:end_num]:
# print (page)
for table in page.extract_tables():
# print(table)
df=df.append(pd.DataFrame(table[1:],columns=table[0]),ignore_index=False)
df.to_excel(writer,sheet_name=sheet_name ,encoding ='utf-8')
target_excel_name = r"target.xlsx"#存为文件名target_excel_name
target_excel_path = r"C:/Users/ty/Desktop/"#文件存储位置
target_writer = pd.ExcelWriter(target_excel_path+target_excel_name)
#由于机会清单四张表 页码没有规律,只能暂时这样,或许可以根据识别文字,定位页码,有些许复杂。
get_df(df_gov_demand,pdf_example,sheet_name_list[0],1,47,target_writer)
get_df(df_gov_suply,pdf_example,sheet_name_list[1],48,64,target_writer)
get_df(df_com_demand,pdf_example,sheet_name_list[2],65,88,target_writer)
get_df(df_com_suply,pdf_example,sheet_name_list[3],89,129,target_writer)
target_writer.save()
更新 首行非标题页处理
针对特定pdf,部分页的标题行不是首行,例如公园城市示范区“十四五”数字经济规划机会清单
其实直接处理也可以,只不过会有有一点点问题,可以直接把标题写成列表,手动写出columns,感觉有点笨笨。
但是大多数页的首行是标题页,可以利用这一点。所以改写一下函数如下。其他的部分大差不差。改改页码之类的就欧克啦,后续可以改成识别一共有几页,今天想下班了,回家背单词了,不能再食盐了。
# 定义得到目标data_frame的函数
# start_num 是pdf的实际页码,并不是标注的页码
def get_df(df,pdf,sheet_name,start_num,end_num,writer):
df1=df.copy()#用来记录标题行的
#df2=df.copy()
for page in pdf.pages[start_num:end_num]:
# print (page)
for table in page.extract_tables():
# print(table)
df1=df1.append(pd.DataFrame(table[:1]),ignore_index=False)
for index in range(len(df1.index)-1):
if df1.iloc[index,:].tolist()== df1.iloc[index+1,:].tolist():
columns_name = df1.iloc[index,:].tolist()
break
#记录每一页的表格数据
for page in pdf.pages[start_num:end_num]:
# print (page)
for table in page.extract_tables():
# print(table)
df=df.append(pd.DataFrame(table[:],columns=columns_name),ignore_index=True)
df = df.drop_duplicates()#去重
df.to_excel(writer,sheet_name=sheet_name ,encoding ='utf-8',index=False,header=False) #最后不要显示column和index