文章目录

  • 1. 功能介绍
  • 2.项目难点
    • 1. tkinter设置图标显示
  • 3. 源代码
  • 3. 代码打包
    • 1. 打包过后程序运行出错
    • 2. 打包命令
    • 3.打包技巧

1. 功能介绍

  1. 选择两个pdf指定的页码并合并成一个文
  2. 选择一个指定的pdf文件,并指定页码,将指定的页码提取出来,可以用’,‘和’-‘分割
  3. 选择一个pdf文件,将其内容转换为word文件。
  4. 选择一个pdf文件将其表格转换为excel文件

2.项目难点

1. tkinter设置图标显示

tkinter设置图标显示可以使用TK.iconbitmap(‘pdf.ico’)函数实现。
但是在打包成一个exe文件之后,就无法实现了。
可以将ico文件通过base64模块的base64decode()将ico文件转换成数据流,然后创建一个新的py文件来保存成一个参数。如此在使用过程中通过再将base64数据转换成一个ico文件,再引用即可。

import base64open_icon = open("image/pdf.ico", "rb")
b64str = base64.b64encode(open_icon.read())
open_icon.close()
write_data = "img = %s" % b64str
# write_data = b64str
with open("icon.icon", "w+") as f:f.write(write_data)

引用base64数据,生成一个ico文件并在系统中引用

import ctypes
import tkinter as tk
import base64
import os
from icon import imgif __name__ == "__main__":# 以下两句代码用于将windows的任务栏图标设置为跟程序icon一样。myappid = "company.product.version"  # 这里可以设置任意文本ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)window = tk.Tk()window.title = "testicon"window.geometry("800x400")window.resizable(0, 0)img_data = base64.b64decode(img)with open("pdf.ico", "wb+") as fw:fw.write(img_data)window.iconbitmap("pdf.ico")os.remove("pdf.ico")window.mainloop()

3. 源代码

#!python
# author:kunta
# date: 2022-09
# version 1.1.0
# description: this software have 4 function
# 1. 选择两个pdf指定的页码并合并成一个文件,未指定页码则完全合并两个文件
# 2. 选择一个指定的pdf文件,并指定页码,将指定的页码提取出来,可以用’,‘和’-‘分割
# 3. 选择一个pdf文件,将其内容转换为word文件。
# 4. 选择一个pdf文件将其表格转换为excel文件。# date 2022-10
# version 2.0
# 本版本增加PDFOCR识别功能。import tkinter as tk
from tkinter import ttk, HORIZONTAL
from tkinter import filedialog
from tkinter import messagebox
from tkinter import Button, Label, StringVar, IntVar
from tkinter.ttk import Separator
from tkinter import RAISED
from PyPDF2 import PdfReader, PdfMerger, PdfWriter
from functools import partial
from pdf2docx import Converter
import pdfplumber as ppm
import pandas as pd
import ctypes
from icon import img   # 将pdf.ico图片转换成base64文件并作为img变量保存到icon.py中。
import openpyxl
import cv2
import os
import base64# 读取合并文件的第一个选择框内容
def askfile1():# 打开文件选择器,并筛选出pdf文件filename = tk.filedialog.askopenfilename(filetypes=[('PDF', '*.pdf'), ('All Files', '*')])if filename is None:entry1.insert(0, '您没有选择任何文件!')else:entry1.delete(0, "end")     # 选择文件之后,将entry1输入框的内容清空。entry1.insert(0, filename)  # 然后将选择的文件全路径插入到entry1输入框中# 读取合并文件的第二个选择框内容
def askfile2():filename = tk.filedialog.askopenfilename(filetypes=[('PDF', '*.pdf'), ('All Files', '*')])if filename is None:entry2.insert(0, '您没有选择任何文件!')else:entry2.delete(0, "end")entry2.insert(0, filename)# 读取分割文件选择框内容
def askfile3():filename = tk.filedialog.askopenfilename(filetypes=[('PDF', '*.pdf'), ('All Files', '*')])if filename is None:entry3.insert(0, '您没有选择任何文件!')else:entry3.delete(0, "end")entry3.insert(0, filename)# 读取pdf转word选择框内容
def askfile4():filename = tk.filedialog.askopenfilename(filetypes=[('PDF', '*.pdf'), ('All Files', '*')])if filename is None:entry4.insert(0, '您没有选择任何文件!')else:entry4.delete(0, "end")entry4.insert(0, filename)# 读取pdf转Excel选择框内容
def askfile5():filename = tk.filedialog.askopenfilename(filetypes=[('PDF', '*.pdf'), ('All Files', '*')])if filename is None:entry5.insert(0, '您没有选择任何文件!')else:entry5.delete(0, "end")entry5.insert(0, filename)# 将两个pdf文件进行合并
def pdfmerger():# print(filename)filename1 = entry1.get()filename2 = entry2.get()file1 = PdfReader(filename1)file2 = PdfReader(filename2)mergerfile = PdfMerger()# 如果用户输入的正确的页码范围,则合并用户输入的页码范围,如果用户输入的页码范围不正确,则将两个文件完全合并try:page11 = int(entry11.get()) - 1page12 = int(entry12.get())page21 = int(entry21.get()) - 1page22 = int(entry22.get())if page11 < 0 or page12 < 0 or page21 < 0 or page22 < 0 or page11 > page12 or page21 > page22 or page12 > len(file1.pages) or page22 > len(file2.pages):messagebox.showerror(title='错误消息', message="请输入正确的页码")returnmergerfile.append(file1, pages=(page11, page12))mergerfile.append(file2, pages=(page21, page22))except:mergerfile.append(file1)mergerfile.append(file2)with open('merger.pdf', 'wb') as outputstream:mergerfile.write(outputstream)messagebox.showinfo(title='文件合并完成', message="文件合并完成,合并后文件名称为msrger.pdf")# print(test1)# 将pdf文件的内容页面进行提取
def pdfspilit():filename = entry3.get()page31 = entry31.get()# page32 = int(entry32.get())file3 = PdfReader(filename)pagelist = []pages = page31.replace(" ", "").split(",")# pages.pop()print("pages:", pages)for i in pages:if i.isdigit():pagelist.append(int(i))else:if i == "":breakrep1 = i.replace('-', ",")rep2 = rep1.split(",")# i = list(i)print("i:", i)for j in range(int(rep2[0]), int(rep2[1])+1):pagelist.append(int(j))print("pagelist:", pagelist)# pages = list(pages)spilitfile = PdfWriter()# spilitfile.append(file3, pages=(page31, page32))pagelist = list(set(pagelist))for i in pagelist:i = i-1spilitfile.addPage(file3.getPage(i))with open('split.pdf', 'wb') as outputstream:spilitfile.write(outputstream)messagebox.showinfo(title="文件提取完成", message="提取后的文件名称为 split.pdf")# 定义一个函数用来将pdf文件转换为word
def pdftoword():filename = entry4.get()convert = Converter(filename)try:convert.convert('pdf2work.docx', start=0, end=None)convert.close()messagebox.showinfo(title="PDF文件转换完成", message='PDF文件转换完成,文件保存为pdf2word.docx')except:messagebox.showerror(title='PDF文件转换失败', message='PDF文件转换失败,请检查源文件')# 定义一个函数用以将pdf转换为excel
def pdftoexcel():filename = entry5.get()items = []startpage = int(entry51.get()) - 1endpage = int(entry52.get())with ppm.open(filename) as pdf:for page in range(startpage, endpage):try:table = pdf.pages[page].extract_table()for line in table:items.append(line)except:messagebox.showerror(title='文件转换失败', message="文件转换失败,请选择正确的文件或者要转换的页码")returnif len(items) == 0:messagebox.showerror(title="未读取到表格信息", message="未读取到表格信息,请选择正确的文件或页码")else:# head = items[0]# print(head)# items.pop(0)print(items)# df = pd.DataFrame(items, columns=head)df = pd.DataFrame(items)df.to_excel('excel.xlsx', index=False)messagebox.showinfo(title="PDF转Excel完成", message="PDF转Excel完成,文件保存为excel.xlsx")if __name__ == '__main__':# 以下两句代码用于将windows的任务栏图标设置为跟程序icon一样。myappid = "company.product.version"  # 这里可以设置任意文本ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)# create tkinter instancewindow = tk.Tk()# add a title towindow.title('英纳法重庆公司PDF文件合并/提取及转换工具')# set the windows size and cannot resize the windowwindow.geometry('830x430')window.resizable(0, 0)# 将img参数转换成图片,并设置为程序图标img_data = base64.b64decode(img)with open("pdf.ico", "wb+") as fw:fw.write(img_data)window.iconbitmap("pdf.ico")os.remove("pdf.ico")# 定义文件名参数,用于在选择文件之后,显示文件名到后面的输入框中。filename1 = StringVar()filename2 = StringVar()filename3 = StringVar()filename4 = StringVar()filename5 = StringVar()path = tk.StringVar()# 读取PDF合并的第一个文件btn = tk.Button(window, text='选择第一个文件', command=askfile1)   # 第一个btn按钮,调用askfile1程序,打开读取文件,并将值传递给entry1btn.grid(row=0, column=0)  # 通过grid进行布局,将btn布局到第一行第一列。entry1 = tk.Entry(window, textvariable=filename1)   # 定义一个Entry控件,其值为fliename1.entry1.grid(row=0, column=1, columnspan=3, ipadx=160)  # 将entry1布局到第一行第二列,跨行3,宽度设置为160.entry11 = tk.Entry(window)  # 定义一个输入框用来设置第一个文件的起始页entry11.grid(row=0, column=5)entry11.insert(0, '起始页')  # 给Enrtry11设置一个初始值‘起始页’,entry12 = tk.Entry(window)  # 定义一个输入框用来设置第一个文件的最后一页entry12.grid(row=0, column=6)entry12.insert(0, '结束页')# 读取PDF合并的第二个文件btn2 = tk.Button(window, text='选择第二个文件', command=askfile2)btn2.grid(row=1, column=0)entry2 = tk.Entry(window, textvariable=filename2)entry2.grid(row=1, column=1, columnspan=3, ipadx=160)entry21 = tk.Entry(window)entry21.grid(row=1, column=5)entry21.insert(0,'起始页')entry22 = tk.Entry(window)entry22.grid(row=1, column=6)entry22.insert(0, '结束页')# 定义一个BTN,点击执行pdf文件合并功能。mergerBtn = tk.Button(window, text='合并文件', command=partial(pdfmerger))mergerBtn.grid(row=2, column=0)# 定义一个分割线,用来分开两个功能,sticky指示线的方向sep = Separator(window, orient=HORIZONTAL)sep.grid(row=3, column=0, columnspan=8, padx=5, pady=10, sticky="EW")# 页面提取的功能区,包括一个文件选择按钮,一个Entry输入框显示文件名称,一个Entry控件用以输入要提取的页码btn3 = tk.Button(window, text='选择提取页面文件', command=askfile3)btn3.grid(row=4, column=0)entry3 = tk.Entry(window, textvariable=filename3)entry3.grid(row=4, column=1, columnspan=3, ipadx=160)entry31 = tk.Entry(window)entry31.grid(row=4, column=5)entry31.insert(0, '页码范围')spilitBtn = tk.Button(window, text='提取页面', command=pdfspilit)spilitBtn.grid(row=5)# 定义一个分割线,用来分开两个功能,sticky指示线的方向sep = Separator(window, orient=HORIZONTAL)sep.grid(row=6, column=0, columnspan=8, padx=5, pady=10, sticky="EW")# 下面是PDF文件转Word文件的功能区,包括一个文件选择按钮,一个显示文件路径的Entry控件btn4 = tk.Button(window, text='转word的PDF文件', command=askfile4)btn4.grid(row=7, column=0)entry4 = tk.Entry(window, textvariable=filename4)entry4.grid(row=7, column=1, columnspan=3, ipadx=160)WordBtn = tk.Button(window, text='PDF转Word', command=pdftoword)   # 执行文件转换的控件,调用pdftoword程序WordBtn.grid(row=8)# 定义一个分割线,用来分开两个功能,sticky指示线的方向sep = Separator(window, orient=HORIZONTAL)sep.grid(row=9, column=0, columnspan=8, padx=5, pady=10, sticky="EW")# 下面是PDF文件转Excel文件的功能区,包括一个文件选择按钮,一个显示文件路径的Entry控件btn5 = tk.Button(window, text='转Excel的PDF文件', command=askfile5)btn5.grid(row=10, column=0)entry5 = tk.Entry(window, textvariable=filename5)entry5.grid(row=10, column=1, columnspan=3, ipadx=160)entry51 = tk.Entry(window)entry51.grid(row=10, column=5)entry51.insert(0, '起始页')entry52 = tk.Entry(window)entry52.grid(row=10, column=6)entry52.insert(0, '结束页')ExcelBtn = tk.Button(window, text='PDF转Excel', command=pdftoexcel)   # 执行文件转换的控件,调用pdftoword程序ExcelBtn.grid(row=11)# 定义一个分割线,用来分开两个功能,sticky指示线的方向sep = Separator(window, orient=HORIZONTAL)sep.grid(row=12, column=0, columnspan=8, padx=5, pady=10, sticky="EW")# 软件功能提示信息text = tk.Label(window, text='注意1:合并文件:选择两个pdf文件,并分别指定文件要合并的页码范围,合并后的文件默认在当前路径下的merger.pdf文件')text.grid(row=14, column=0, columnspan=8, sticky=tk.W)text2 = tk.Label(window, text="注意2:提取文件:提取一个pdf文件的指定页码,中间用英文','隔开,页码范围示例  1,2,3,5-9,11,15-19,提取后默认保存在当前路径下的split.pdf文件")text2.grid(row=15, column=0, columnspan=8, sticky=tk.W)text3 = tk.Label(window, text='注意3:PDF转word:仅支持可识别的文档转换,不支持图片识别功能,转换后文件为word.docx')text3.grid(row=16, column=0, columnspan=8, sticky=tk.W)text4 = tk.Label(window, text='注意4:PDF转Excel:分别输入表格所在PDF文件的起始页及结束页,在页码范围内,每一页都需要有表格否则会报错,转换后文件为excel.xlsx')text4.grid(row=17, column=0, columnspan=8, sticky=tk.W)# 主程序运行加载window.mainloop()

3. 代码打包

1. 打包过后程序运行出错

pyinstaller打包后,运行生成的exe报错“recursion is detected during loading of “cv2“ binary extensions.”
解决方法:

  1. 通过pip uninstall oepncv-python卸载,
  2. 通过pip install opencv-python --target 安装到程序路径。
  3. 通过pyinstaller -F -w --clean main.py --paths=“C:\Users\admin_zhouga\PycharmProjects\PDFinsert\venv\lib\site-packages\cv2” 进行打包

2. 打包命令

pyinstaller -F -w --clean --icon=“C:\Users\admin_zhouga\image\pdf.ico” C:\Users\admin_zhouga\PycharmProjects\PDFinsert\PDFcreate.py

–icon= 是给打包之后的文件exe文件添加一个图标

3.打包技巧

  1. 在创建工程的时候,需要在虚拟环境中创建。
  2. 在虚拟环境中安装pyinstaller
  3. 在虚拟环境的命令行中运行打包命令,如此可以缩小exe文件的大小。

Python PDF文件合并,提取相关推荐

  1. gnuradio上怎么使用python文件_使用Python从PDF文件中提取数据

    前言 数据是数据科学中任何分析的关键,大多数分析中最常用的数据集类型是存储在逗号分隔值(csv)表中的干净数据.然而,由于可移植文档格式(pdf)文件是最常用的文件格式之一,因此每个数据科学家都应该了 ...

  2. 使用Python从PDF文件中提取数据

    前言 数据是数据科学中任何分析的关键,大多数分析中最常用的数据集类型是存储在逗号分隔值(csv)表中的干净数据.然而,由于可移植文档格式(pdf)文件是最常用的文件格式之一,因此每个数据科学家都应该了 ...

  3. python自动翻译pdf_python实现从pdf文件中提取文本,并自动翻译的方法

    针对Python 3.5.2 测试 首先安装两个包: $ pip install googletrans $ pip install pdfminer3k googletrans会提供一个命令tran ...

  4. python用来自动修改pdf_python实现从pdf文件中提取文本,并自动翻译的方法

    针对Python 3.5.2 测试 首先安装两个包: $ pip install googletrans $ pip install pdfminer3k googletrans会提供一个命令tran ...

  5. PDF文件合并 –Python

    PDF 文件合并 – Python 安装 明确目标 Simple case 了解需求 Part I Part II 代码实现 安装 因版本差异,可能会产生报错. Python import platf ...

  6. 办公自动化:PDF文件合并器,用Python将多个PDF文件进行合并

    相关文件 想学Python的小伙伴可以关注小编的公众号[Python日志] 有很多的资源可以白嫖的哈,不定时会更新一下Python的小知识的哈!! Python源码.问题解答学习交流群:7731621 ...

  7. Python实现PDF文件合并

    PDF是我们目前办公处理的一种重要文件格式,目前商用PDF浏览器一般对合并PDF功能有权限限制,下面介绍利用Python实现多个PDF合并的方法,以实现更高效便捷的PDF文件合并需求. 实现步骤分成三 ...

  8. python实现PDF文件合并操作,附可直接使用的exe文件

    前几日在打数学建模比赛,发现有一个需求是把保证书和论文两个PDF文件合并成一个再去提交,但我在网上搜寻了很多的网站和软件,却发现它们大多数都是收费的,以WPS为例,使用合并PDF功能需要开通完整的稻草 ...

  9. python怎么读取pdf为文本_如何从pdf文件中提取特定文本python

    我试图摘录这段文字:DLA LAND AND MARITIME ACTIVE DEVICES DIVISION PO BOX 3990 COLUMBUS OH 43218-3990 USA Name: ...

最新文章

  1. 软件测试中性能瓶颈是什么,性能测试中如何定位性能瓶颈
  2. 利用cmake查看OpenCV的源码的方法
  3. r语言默认工作目录document_使用 Docker 和 Nginx 实现简单目录索引服务
  4. C++构造函数调用规则
  5. 监督学习 | 非线性回归 之多项式回归原理及Sklearn实现
  6. python3 面向对象编程 下载_Python3(7) Python 面向对象编程
  7. Stata和Matlab联合处理金融数据
  8. Linux 中常用的命令
  9. 【Flink】FLink 通讯组件 Akka与Actor 模型
  10. 空类型(void *)的简单理解
  11. 企业员工考勤管理子系统
  12. 设为首页,加入收藏兼容360/火狐/谷歌/IE等主流浏览器的代码
  13. 网络管理工具IP-Tools的使用
  14. cat环境搭建及springboot项目接入
  15. 【JAVA】从0开始写DHT/磁力爬虫 05 INFOHASH转种子
  16. 数据结构(2)时间复杂度——渐进时间复杂度、渐进上界、渐进下界
  17. 自动化工具之SelendroidRobotium
  18. xp系统设置ntp服务器,xp设置ntp服务器地址
  19. 数据通信初级工程师题库
  20. java 写一个HelloJavaWorld你好世界输出到操作系统文件Hello.txt文件中

热门文章

  1. 人民币大小写转换格式
  2. 【数据库】码,超码,候选码与主码,外码
  3. DPC(Defect Pixel Correction)——坏点检测
  4. 小学生3年级100以内加减法
  5. 在Java 17中偏向锁可算废了
  6. 经过离散点画平滑曲线(贝塞尔3次)
  7. C#实现贝塞尔曲线的算法
  8. 基于51单片机的火灾预警系统设计
  9. USACO-Section 1.2 Daul Palindromes[...]
  10. oracle执行语句出无效字符,pl/sql动态执行sql语句时报错:ORA-00911: 无效字符 ORA-06512: 在 line 14...