解析pdf图片格式的表格到excel表格

简介: 解析pdf图片格式的表格到excel表格,原理是把pdf转换成图片,根据直方图定位表格单元格线条位置,按照单元格切分原始pdf,按顺序ocr单元格内容,最终拼接成完整excel
# -*- coding: utf-8 -*-"""Created on Wed Aug  3 10:06:27 2022@author: 01394546"""importcv2importnumpyasnpimportmatplotlib.pyplotaspltimportpandasaspdfromPILimportImageimportcv2importnumpyasnpimportfitz##如果安装失败,可以直接安装pip install PyMuPDF后,fitz就可以正常使用了importpytesseractimportmatplotlib.pyplotaspltimportos# 处理文件frompdf2imageimportconvert_from_path# pdf转图片importpytesseract# 识别图片文字importcsv# 处理csv文件deftess_ocr(pdf_path):
# 创建一个和pdf同名的文件夹images=convert_from_path(pdf_path, fmt='png', output_folder='./out/',
userpw='site',poppler_path=r'E:\poppler-0.68.0_x86\poppler-0.68.0\bin')  # 转成图片# pdf_document = '2022年南山宝安避雷名单-截止2022年7月(OCR).pdf'doc=fitz.open(pdf_path)
result= {}
for (i,img) inenumerate(images):
# plt.xticks([]), plt.yticks([])  # 隐藏x和y轴# plt.imshow(np.asarray(img))# plt.savefig('./out/{0}_{1}页.png'.format(pdf_path, i+1))# plt.show()print('正在处理{0}的第{1}/{2}页。。。'.format(pdf_path,i,len(images)))
print(np.asarray(img).shape)
b, g, r=cv2.split(np.asarray(img))  # 分别提取B、G、R通道img_new1=cv2.merge([r, g, b])  # 重新组合为R、G、Bxs,ys=cut_pdf2_pic(img_new1)
page1=doc.load_page(i)  # pdf文件第一页rect=page1.rect# print(rect)# print('ys----',ys)iflen(ys)==7:
cols=['行政区','区域','地址','事件描述','黑房东联系方式','事件时间']
else:
cols= [ '区域', '地址', '事件描述', '黑房东联系方式', '事件时间']
forjinrange(len(xs) -1):
foriinrange(len(ys) -1):
# 在分割时,第一个参数为y坐标,第二个参数为x坐标# print('xs[j]--',xs[j])# print('xs[j + 1]--',xs[j + 1])# print('ys[i]--', ys[i])# print('ys[i + 1]--', ys[i + 1])# print('(ys[i]/ys[-1])',(ys[i]/ys[-1]))# print('(ys[i]/ys[-1]) * rect.width', (ys[i]/ys[-1]) * rect.width)# print('(ys[i+1]/ys[-1])', (ys[i+1]/ys[-1]))# print('(ys[i+1]/ys[-1])* rect.width', (ys[i+1]/ys[-1])* rect.width)clip=fitz.Rect(((ys[i]-30)/ys[-1]) *rect.width, ((xs[j]-50)/xs[-1]) *rect.height,
                                 ((ys[i+1]+30)/ys[-1])*rect.width, ((xs[j+1]+50)/xs[-1])*rect.height)
a_text=page1.get_text(clip=clip)
# print(a_text)result[cols[i]]=result.get(cols[i],[])
result[cols[i]].append(a_text.replace('\n',''))
# for i in result.keys():#     print(len(result[i]))print(result)
data=pd.DataFrame(result)
data.index.name='编号'data['标注名称'] =data['地址']
if'行政区'inlist(data.columns):
data['地名地址'] ='深圳市'+data['行政区']+data['区域'] +data['地址']
else:
data['地名地址'] ='深圳市'+data['区域'] +data['地址']
data['经度'] =Nonedata['纬度'] =Nonedata['被举报原因'] =data['事件描述']
data['举报日期[日期]'] =data['事件时间']
data[['标注名称', '地名地址', '经度', '纬度', '被举报原因','黑房东联系方式', '举报日期[日期]']].to_csv(os.path.join('./黑房东数据/OUT/', pdf_path.split('/')[-1]+'.csv'))
defcut_pdf2_pic(image):
# image = cv2.imread('./20220809193309.png', 1)# print(image)# 灰度图片gray=cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 二值化binary=cv2.adaptiveThreshold(~gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 35, -5)
# ret,binary = cv2.threshold(~gray, 127, 255, cv2.THRESH_BINARY)# cv2.imshow("二值化图片:", binary) #展示图片# cv2.waitKey(0)rows, cols=binary.shapescale=20# 识别横线kernel=cv2.getStructuringElement(cv2.MORPH_RECT, (cols//scale, 1))
eroded=cv2.erode(binary, kernel, iterations=1)
# cv2.imshow("Eroded Image",eroded)dilatedcol=cv2.dilate(eroded, kernel, iterations=1)
# cv2.imshow("表格横线展示:",dilatedcol)# cv2.waitKey(0)# 识别竖线scale=20kernel=cv2.getStructuringElement(cv2.MORPH_RECT, (1, rows//scale))
eroded=cv2.erode(binary, kernel, iterations=1)
dilatedrow=cv2.dilate(eroded, kernel, iterations=1)
# cv2.imshow("表格竖线展示:",dilatedrow)# cv2.waitKey(0)# 标识表格merge=cv2.add(dilatedcol, dilatedrow)
# cv2.imshow("表格整体展示:", merge)# cv2.waitKey(0)print('merge.shape:', merge.shape)#页面的长和宽,对应矩阵的行和列x=merge.sum(axis=0)  #像素向上叠加,长度等于列y=merge.sum(axis=1)  #像素向右边叠加,长度等于行# print(x,len(x))# print(y,len(y))ys=np.where(x>255*len(y) *0.6)#竖线xs=np.where(y>255*len(x) *0.80)#横线ys=list(ys[0])
xs=list(xs[0])
xs2=[]
ys2=[]
xs=[0]+xsforjinrange(len(xs) -1):
ifxs[j+1] -xs[j] <20: continuexs2.append(xs[j])
xs2.append(xs[-1])
ys=[0]+ysforiinrange(len(ys) -1):
ifys[i+1] -ys[i] <20: continueys2.append(ys[i])
ys2.append(ys[-1])
print(xs)
print(xs2)
print(ys)
print(ys2)
xs=xs2ys=ys2# for j in range(len(xs) - 1):#     for i in range(len(ys) - 1):#         # 在分割时,第一个参数为y坐标,第二个参数为x坐标#         ROI = image[xs[j]:xs[j + 1], ys[i]:ys[i + 1]]  # 减去3的原因是由于我缩小ROI范围#         # cv2.imshow("分割后子图片展示:",ROI)#         # cv2.waitKey(0)##         b, g, r = cv2.split(ROI)  # 分别提取B、G、R通道#         img_new1 = cv2.merge([r, g, b])  # 重新组合为R、G、B##         if np.var(img_new1) > 1000:#             print('第{0}行--第{1}列----------------'.format(j, i))#             print(np.var(img_new1))#             plt.xticks([]), plt.yticks([])  # 隐藏x和y轴#             plt.imshow(img_new1)#             plt.savefig('./out/第{0}行,第{1}列.png'.format(j, i))#             # plt.show()# text = pytesseract.image_to_string(img_new1, lang='chi_sim+eng')  # 识别图片文字returnxs,ysimportosTemp_Dir1='./OCR/'forroot, dirs, filesinos.walk(Temp_Dir1, topdown=False):
for (i_,file_path) inenumerate(files):
print(i_,file_path)
tess_ocr(os.path.join(root, file_path))
目录
相关文章
|
2天前
|
SQL 数据库连接 数据库
【SQL Server】2. 将数据导入导出到Excel表格当中
【SQL Server】2. 将数据导入导出到Excel表格当中
50 0
|
2天前
|
Java 数据库
SpringBoot定时将数据库表生成Excel表格
SpringBoot定时将数据库表生成Excel表格
30 0
|
2天前
|
安全 Java 数据库连接
jdbc解析excel文件,批量插入数据至库中
jdbc解析excel文件,批量插入数据至库中
21 0
|
2天前
|
前端开发 UED
前端解析Excel文件
前端解析Excel文件
39 0
|
1天前
|
开发框架 资源调度 JavaScript
uniapp本地导出表格excel
uniapp本地导出表格excel
|
2天前
|
前端开发 关系型数据库 MySQL
【MySQL × SpringBoot 突发奇想】全面实现流程 · 数据库导出Excel表格文件的接口
【MySQL × SpringBoot 突发奇想】全面实现流程 · 数据库导出Excel表格文件的接口
24 0
|
2天前
|
Java 关系型数据库 MySQL
【MySQL × SpringBoot 突发奇想】全面实现流程 · xlsx文件,Excel表格导入数据库的接口(下)
【MySQL × SpringBoot 突发奇想】全面实现流程 · xlsx文件,Excel表格导入数据库的接口
10 0
|
2天前
|
Java 关系型数据库 MySQL
【MySQL × SpringBoot 突发奇想】全面实现流程 · xlsx文件,Excel表格导入数据库的接口(上)
【MySQL × SpringBoot 突发奇想】全面实现流程 · xlsx文件,Excel表格导入数据库的接口
15 0
|
2天前
|
存储 数据采集 数据可视化
Python列表到Excel表格第一列的转换技术详解
Python列表到Excel表格第一列的转换技术详解
8 0
|
2天前
|
JavaScript 前端开发 BI
原生html—摆脱ps、excel 在线绘制财务表格加水印(html绘制表格js加水印)
原生html—摆脱ps、excel 在线绘制财务表格加水印(html绘制表格js加水印)
22 1

推荐镜像

更多