【Python实战】完美实现 WPS 会员功能,自动化处理 PDF 文档(建议收藏)

news2025/2/23 3:18:17

数字化办公已成常态,文档管理和处理是很多小伙伴的日常工作。

PDF(Portable Document Format)文档因其跨平台兼容性和格式固定性而备受青睐。

然而,对于非WPS会员用户而言,一些高级功能如批量处理、格式转换、添加水印等常常受限。

即便是充了会员,有些文档的水印也无法完全去除。

本文旨在揭示如何通过 Python 和相关库,自动化处理 PDF 文档,从而完美实现类似WPS会员的高级功能,无需额外付费。

文章目录如下(按需取用):

  • 生成水印 —— 创建专属水印,保护你的文档版权。
  • 添加水印 —— 将水印无缝融合到PDF文档中,增强文档的专业性和安全性。
  • 提取文本内容 —— 从PDF中快速抽取文字,便于二次编辑和使用。
  • 多个PDF合并 —— 将分散的PDF文件整合成一份,简化文档管理和阅读体验。
  • 单个PDF分割 —— 按页或章节拆分大型PDF文档,便于分享和管理。
  • PDF转图片 —— 将PDF页面转换为图像格式,适用于各种展示场景。
  • 图片转PDF —— 反向操作,将多张图片合成为一份PDF文档,方便打印和分享。

0. 前置准备

首先需要在电脑上准备好 Python 环境,有不了解的小伙伴,送你一份保姆级教程:【7天Python入门系列】Day1:环境准备之Conda和VS code安装

PDF 文档处理,一般会用到下面三个库,打开终端,一键安装:

pip install PyPDF2
pip install PyMuPDF
pip install reportlab

1. 生成水印

采用 reportlab 的画布功能,先引入必要的模块:

from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from reportlab.pdfbase import pdfmetrics   # 注册字体
from reportlab.pdfbase.ttfonts import TTFont # 字体类
from reportlab.lib.pagesizes import letter  # 页面的标志尺寸(8.5*inch, 11*inch)

然后,我们引入本地电脑支持的字体,注册字体类:

pdfmetrics.registerFont(TTFont('simkai', 'C:\Windows\Fonts\simkai.ttf'))

Windows 电脑中,字体默认保存在 C:\Windows\Fonts\,文件后缀为 .ttf,在其中找到想要想要生成的字体路径,填入上述代码片段对应位置。

最后,给出函数实现:

def create_watermark(watermark_text='公众号:猴哥的AI知识库', font=15, pagesize=(30*cm, 30*cm)):
    watermark_canvas = canvas.Canvas("data/watermark.pdf", pagesize) # 指定存放位置和画布大小
    watermark_canvas.setFont("simkai", font) 
    watermark_canvas.setFillAlpha(0.1) # 设置透明度,1为不透明
    watermark_canvas.translate(10*cm, 5*cm)
    watermark_canvas.rotate(30) # 水印旋转角度
    for i in range(5):
        for j in range(10):
            a = 10*(i-1)
            b = 5*(j-2)
            watermark_canvas.drawString(a*cm, b*cm, watermark_text)
    watermark_canvas.save()

注意:画布大小可以作为一个参数传入,可根据 pdf 页面的大小进行设置。此外,你还可以任意修改水印的位置和字体。

如何获取 pdf 页面的大小,接着往下看。

我们先来看下生成的水印效果:

2. 添加水印

如何将上面生成的水印,添加到我们的 PDF 文档中?

首先,我们引入 PyPDF2 中的读写类,给定要插入水印的 PDF (input_pdf)和输出的 PDF (output_pdf)。

然后,根据输入的 PDF 首页大小创建水印文件。

page_size = (first_page.mediabox.width, first_page.mediabox.height)  # 获取页面大小

最后,调用 .merge_page 方法为每一页插入水印,当然也可以设置间隔几页插入,或者只插入特定页。

实现代码如下:

from tqdm import tqdm
from PyPDF2 import PdfReader, PdfWriter

def add_watermark(input_pdf, output_pdf, watermark_text='公众号:猴哥的AI知识库'):
    pdf_reader = PdfReader(input_pdf)  # 读取需要添加水印的文件
    first_page = pdf_reader.pages[0]
    page_size = (first_page.mediabox.width, first_page.mediabox.height)  # 获取页面大小
    create_watermark(watermark_text, pagesize=page_size)  # 创建水印PDF

    pdf_writer = PdfWriter()  # 创建PDF文件写入对象
    watermark_file = PdfReader("data/watermark.pdf")  # 读取水印PDF(假设水印页只有一页)

    for page_num in tqdm(range(len(pdf_reader.pages)), desc='add_watermark'):  # 遍历每一页PDF对象
        pdf_page = pdf_reader.pages[page_num]  # 获取PDF的当前页对象
        pdf_page.merge_page(watermark_file.pages[0])  # 将水印页合并到当前页中
        pdf_writer.add_page(pdf_page)  # 将合并后的PDF对象页添加到PDF写入对象中
    with open(output_pdf, 'wb') as output:  # 打开输出文件
        pdf_writer.write(output)  # 写入PDF内容到输出文件

最终效果,我们拿南瓜书来举个例子:

3. 提取文本内容

手动复制 PDF 中的文本实在太麻烦了,能否一键提取所有内容?

不但能,而且还可以转存成 MarkDown 格式。

这里提供两种方式~

方式一:采用 PyPDF2:调用.extract_text()方法

def pypdf_to_txt(input_pdf, output_path='output.md'):
    pdf_reader = PdfReader(input_pdf)
    markdown_lines = []
    # 遍历PDF的每一页
    for page_num in range(len(pdf_reader.pages)):
        page = pdf_reader.pages[page_num]
        text = page.extract_text()
        markdown_lines.append(text)
        markdown_lines.append("\n\n")  # 分页
    # 将文本写入Markdown文件
    with open(output_path, "w", encoding="utf-8") as f:
        f.writelines(markdown_lines)

方式二:采用 PyMuPDF

注:fitz 是 PyMuPDF 库的一个模块

import fitz
def pymupdf_to_txt(input_pdf, output_path='output.md'):
    pdf_document = fitz.open(input_pdf)
    markdown_lines = []
    # 遍历PDF的每一页
    for page_num in range(pdf_document.page_count):
        page = pdf_document.load_page(page_num)
        text = page.get_text("text")
        if not text:
            pm = page.get_pixmap()
            pm.save("temp.png")
            img = cv2.imread("temp.png")
            texts = img_ocr(img_data=img)
            # os.remove("temp.png")
            markdown_lines.append("\n".join(texts))
        else:
            markdown_lines.append(text+"\n\n")
    # 将文本写入Markdown文件
    with open(output_path, "w", encoding="utf-8") as f:
        f.writelines(markdown_lines)

上述函数中,还加了一层判断,也即如果识别到当前 PDF 页是一张图片,没有文字,怎么办?

此时,我们可以调用 OCR 方法,识别出所有文字再进行拼接,市面上开源的 OCR 方案有很多,大家都在用哪款 OCR,欢迎评论区告诉我。

关于如何优雅地使用 OCR,如果感兴趣的小伙伴多的话,猴哥再单独出一篇分享。

4. 多个 PDF 合并

了解了上述操作以后,实现 PDF 合并就很简单了。

首先,新建一个 writer 用于写入新文件;

然后,每一个输入文件都对应一个 reader。

直接上代码:

def merge_pdf(input_pdfs, output_pdf):
    pdf_writer = PdfWriter()
    for input_pdf in input_pdfs:
        pdf_reader = PdfReader(input_pdf)
        for page in pdf_reader.pages:
            pdf_writer.add_page(page)
    with open(output_pdf, 'wb') as f:
        pdf_writer.write(f)

5. 单个 PDF 分割

如果想把一个大型 PDF 按需切割成多个文件,比如按页切割 或者 按章节切割,怎么处理?

假设我们每 10 页切割成一个 PDF,这里给一个示例代码:

def split_pdf(input_pdf, per_num=10):
    pdf_reader = PdfReader(input_pdf)
    total_pages = len(pdf_reader.pages)
    file_dir, file_name = os.path.split(input_pdf)
    file_base, file_ext = os.path.splitext(file_name)
    new_folder_path = os.path.join(file_dir, file_base)
    os.makedirs(new_folder_path, exist_ok=True)
    for start in range(0, total_pages, per_num):
        end = min(start + per_num, total_pages) 
        pdf_writer = PdfWriter()
        for i in range(start, end):
            pdf_writer.add_page(pdf_reader.pages[i])
        output_file_path = os.path.join(new_folder_path, f'{file_base}_{start}_{end}{file_ext}')
        with open(output_file_path, 'wb') as f:
            pdf_writer.write(f)

6. PDF 转成图片

按照本文第 2 部分的方式添加水印,很容易被一键去水印,比如 WPS 的会员功能。

如果要使得自己的水印变得更为隐蔽,最好是将 PDF 转为图片,然后在图片中添加水印。

如何将 PDF 转成图片?

这里我们采用 fitz 进行处理:

def pdf2imgs(input_pdf, png_path, zoom=200):
    doc = fitz.open(input_pdf)
    total = doc.page_count
    for pg in tqdm(range(total), total=total, desc='pdf2imgs'):
        page = doc[pg]
        zoom = int(zoom)  # 值越大,分辨率越高,文件越清晰
        trans = fitz.Matrix(zoom / 100.0, zoom / 100.0)
        pm = page.get_pixmap(matrix=trans, alpha=False)
        os.makedirs(png_path, exist_ok=True)
        pm.save(os.path.join(png_path, '%s.png' %(pg)))
    doc.close()
    return total

7. 图片转 PDF

接上一步,将加了水印的图片再合成为 PDF 文件。

def imgs2pdf(image_paths, output_path='1.pdf'):
    doc = fitz.open()
    for img in tqdm(image_paths, desc='imgs2pdf'):
        imgdoc = fitz.open(img)
        pdfbytes = imgdoc.convert_to_pdf()
        imgpdf = fitz.open("pdf", pdfbytes)
        doc.insert_pdf(imgpdf)
    doc.save(output_path)
    doc.close()

写在最后

本文带大家采用 Python 和相关库,自动化批量处理 PDF 文档,完美实现了类似 WPS 会员的高级功能,旨在帮助大家提供办公效率。

这些功能已足够我们解放双手了,还有未尽功能,欢迎评论区留言告诉我。

如果本文对你有帮助,欢迎点赞收藏备用。

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

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

相关文章

【SpringMVC】详细介绍SpringMVC的执行流程

目录 1. 概念 2.SpringMVC工作原理 3. springMVC的简单使用 1.在pom.xml中导入相关依赖 2.在web.xml中配置dispatcherServlet 3.创建springMVC.xml核心配置文件 1. 概念 什么是MVC? MVC是下面三个组件的简写,模型(Model)、视图…

mathtype7永久激活密钥咋子哪里获取?2024最新破解版下载附安装教程

在数字化时代,我们每天都与文字和符号打交道。无论是撰写论文、准备报告还是编写程序,数学公式的输入都是不可或缺的一环。但你有没有遇到过这样的困扰:在Word文档中编辑复杂的数学公式时,操作繁琐且不直观? 别担心&a…

鸿蒙图形开发【3D引擎接口示例】

介绍 本实例主要介绍3D引擎提供的接口功能。提供了ohos.graphics.scene中接口的功能演示。 3D引擎渲染的画面会被显示在Component3D这一控件中。点击按钮触发不同的功能,用户可以观察渲染画面的改变。 效果预览 使用说明 在主界面,可以点击按钮进入不…

【书生大模型实战营第三期】基础岛 第1关 书生大模型全链路开源体系

欢迎大家参与第三期书生大模型实战营!!! 1. 书生浦语开源历程 从23年7月开始,直到今年7月,书生浦语先后开源了 InternLM、InternLM2 核性能更好的 InternLM2.5。 2. InternLM2.5 的优势 其中,最新的 Intern…

计算机语言-CSP初赛知识点整理

历年真题 [2020-CSP-J-第2题] 编译器的主要功能( ) A. 将源程序翻译成机器指令代码 B. 将源程序重新组合 C. 将低级语言翻译成高级语言 D. 将一种高级语言翻译成另一种高级语言 [2021-CSP-J-第1题] 以下不属于面向对象程序设计语言的是()。 A. C B. Pyt…

【读点论文】场景图像中文本检测和识别关键技术研究-博士学位论文

文本是人类获取信息及社会交流的重要手段,从图像准确读取文本对人类的生产生活至关重要。现有方法通常将文本读取细分为文本检测、文本识别、端到端文本识别三个子任务。其中文本检测的目的是定位出图像中文本的位置,文本识别旨在识别出文本区域的字符序…

高仲富:49岁搞AI,白天种菜卖菜,晚上学数学搞程序

这是《开发者说》的第13期,本期我们邀请的开发者是高仲富,曾是一位数学老师,自学成为一名程序员,在北京漂过,后逃回了成都,一边与病魔抗争,一边写代码,一写就是15年,制作…

Electron 集成SQlite FTS5 实现百万级数据的倒排索引

背景 在产品迭代时,个人版产品已经将联系人和消息实时备份到本地,而消息的备份的目的仍然是为了快速查询对自己有用的上下文,并能快速定位到这些用户以及这些有用的信息。另外包括未来喂给 chatgpt-4o 的数据也是需要调用搜索获取的&#xff…

39. 647. 回文子串,516.最长回文子序列, 动态规划总结

确定dp数组以及下标的含义。如果大家做了很多这种子序列相关的题目,在定义dp数组的时候 很自然就会想题目求什么,我们就如何定义dp数组。绝大多数题目确实是这样,不过本题如果我们定义,dp[i] 为 下标i结尾的字符串有 dp[i]个回文串…

Weblogic 漏洞(详细)

一.weblogic弱口令 访问一下默认用户名:weblogic 密码: Oracle123 然后点击安装 然后再点击上传文件 将jsp木马打包,改为war上传一直下一步,最后点完成 然后使用工具连接 二.CVE-2017-3506 使用工具检测,存在漏洞 …

【C++】模拟实现stack

🦄个人主页:修修修也 🎏所属专栏:实战项目集 ⚙️操作环境:Visual Studio 2022 ​ 目录 一.了解项目功能 📌了解stack官方标准 📌了解模拟实现stack 二.逐步实现项目功能模块及其逻辑详解 📌实现stack成员变量 &…

[pdf]240道《软件方法》强化自测题业务建模需求分析共201页(202408更新)

链接: http://www.umlchina.com/url/quizad.html 如果需要提取码:umlc 文件夹中的“潘加宇《软件方法》强化自测题业务建模需求分析共240题.pdf”

【MATLAB第107期】基于MATLAB的Morris全局敏感性分析模型(无目标函数)

【MATLAB第107期】基于MATLAB的Morris全局敏感性分析模型(无目标函数) 一、原理介绍 1.基本原理: Morris方法采用概率均匀抽样的方式估计每个模型输入因子在输出结果中的重要性,通过比较系统在不同输入参数值上的输出结果变化来…

智观察 | 行业赛道里的AI大模型

‍ “AI改变世界”被炒得热火朝天,结果就换来AI聊天? 实际上,在日常娱乐之下,AI正在暗暗“憋大招”,深入各行各业,发挥更专业的作用。 自动驾驶 最近“萝卜快跑”霸榜热搜长达一周,让无人驾…

ECMAScript 6 入门 学习 日志笔记 2024/8/6 13:59

就读书籍: ECMAScript 6 入门 作者:阮一峰https://www.ruanyifeng.com/ 个人理解笔记 { } 块级 函数不能先用后声明 Let 优先函数表达 不可重复声明同一变量 { letfunction (){ } } 不谈其他,只要在{ } 中即可 ,简单暴力理解 const 和 let 类似 …

语言模型-神经网络模型(二)

神经网络模型语言模型 神经网络模型神经网络的分类神经网络模型和Ngram对比应用一-话者分离对比优劣 应用二-数字归一化应用三-文本打标 神经网络模型 释义: 与ngram模型相似使用,前n个词预测下一个词,输出在字表上的概率分布;过…

【Playwright+Python】使用Playwright进行API接口测试

在当今的自动化测试领域,结合Web UI和API接口测试已成为提升测试覆盖率和效率的关键。Playwright作为一个强大的自动化测试工具,除了在Web UI测试中大放异彩,还能与Python结合,实现强大的API接口测试功能。本文将带你探索如何使用…

面试软件测试岗:经典面试题!全背下来,月薪10K起步...

背题是一个快速应付面试的方式,但如果你想在软件测试行业稳步前进、步步为营的话,建议大家还是有序学习软件测试知识,积累够了,转行、跳槽都是顺其自然的。 1、什么是兼容性测试?兼容性测试侧重哪些方面? …

告别录屏难题:2024四大热门电脑录屏软件推荐

进行在线教学、游戏直播、制作教程视频,录屏已成为我们日常生活和工作的重要需求。电脑怎么录屏?一款好用的录屏软件十分重要。今天,我们就来为大家推荐四款实用的电脑录屏工具。 1. 福昕录屏大师:专业级录屏,满足多样…