#005 Python实现批量 Word to PNG图片
ztj100 2024-11-27 23:33 18 浏览 0 评论
有个网友在WordtoPDF的文章中留言说有没有WORDTOPNG。
有需求,必须安排,业务场景做出来再聊聊。
一、思路
第一种:用WORD TO PDF的库(win32com.client)来实现
查资料发现这个库的SaveAs方法里面的WdSaveFormat 没有图片格式。
参考微软的官方说明:
https://learn.microsoft.com/zh-cn/office/vba/api/word.wdsaveformat
这个方法应该是行不通了。
第二种:百度出来Aspose这家商业的py库可以
立刻安排:Demo都跑成功了,结果图片上有这家的水印。
裤子都脱了,给我安排这个,就这?
第三种:曲线救国
STEP1:DOC先转PDF
SETP2:PDF转PNG
看起来可行
二、实现和讲解
先贴代码,再来讲解注意事项:
# -*- coding: utf-8 -*-
"""
@Author : Nick
@Time : 2023/9/7
@Comment : #005 doc to pdf to png
"""
from datetime import datetime
from pathlib import Path
import fitz #pip install PyMuPDF
import cv2 # pip3 install opencv-python -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
import numpy as np
import os
from shutil import copyfile
import win32com.client #pip install pywin32
def is_blank(line):
"""
判断本行是否空白行
"""
for pixel in line:
if not all(n == 255 for n in pixel):
return False
return True
def get_blank_block(img, begin_row, end_row, need_height):
"""
获取高度大于等于输入值的整块空白区域
"""
if (img is None) or (begin_row < 0) or (end_row < begin_row) or (need_height <= 0):
return False, 0, 0
if (end_row - begin_row) < need_height:
return False, 0, 0
start_row = -1
found = False
found_height = 0
for row in range(begin_row, end_row):
line = img[row, :]
if not is_blank(line):
# 非空白,则判断高度是否符合
if found_height >= need_height:
break
start_row = -1
found_height = 0
continue
# 是空白行
if start_row < 0:
start_row = row
found_height += 1
if found_height >= need_height:
found = True
return found, start_row, found_height
def shrink_img(img, blank_height=50, reserve_height=20):
"""
将图片中过长的空白背景截取删除:对于图片中整行都是白色,且超过一定高度的,仅保留指定高度区域,其余删除。
"""
# 读取原始图片宽高
height, width = img.shape[:2]
found = True
img_stack = None
begin_row = 0
while found:
found, begin_blank_row, found_height = get_blank_block(img, begin_row, height, blank_height)
if found:
# 找到空白区域,将搜索起始行到空白起始行之间的图像加入stack,跳过空白区域,继续搜索
img2 = img[begin_row: begin_blank_row + reserve_height, :]
begin_row = begin_blank_row + found_height
else:
# 没找到空白区域,将搜索起始行到结束行的图像加入stack
img2 = img[begin_row:height, :]
if img_stack is None:
img_stack = np.vstack((img2,))
else:
img_stack = np.vstack((img_stack, img2))
if img_stack is None:
img_stack = img
return img_stack
def pdf_2_png(pdf_name,png_name=None):
print(pdf_name)
pdf_path = Path(pdf_name).parent
doc = fitz.open(pdf_name)
img_stack = None
temp = 0
# 每页pdf生产一个临时图片
for pg in range(doc.page_count):
page = doc[pg]
temp += 1
rotate = int(0)
# 每个尺寸的缩放系数为2,这将为我们生成分辨率提高四倍的图像。
zoom_x = 2.0
zoom_y = 2.0
trans = fitz.Matrix(zoom_x, zoom_y).prerotate(rotate)
pixmap = page.get_pixmap(matrix=trans, alpha=False)
# 生成临时png文件路径
pic_name = str(pdf_path.joinpath('_temp_{}.png'.format(temp)).absolute())
pixmap.save(pic_name)
# pm_img = cv2.imread(pic_name) # 此方式不支持中文目录,改用下方方法
pm_img = cv2.imdecode(np.fromfile(pic_name, dtype=np.uint8), cv2.IMREAD_COLOR + cv2.IMREAD_IGNORE_ORIENTATION)
pm_img = cv2.resize(pm_img, (1191, 1684))
# 删除临时图片文件
Path(pic_name).unlink(True)
# 拼长图
if img_stack is None:
img_stack = np.vstack((pm_img,))
else:
img_stack = np.vstack((img_stack, pm_img))
# 删除长图中的空白区域
thin_img = shrink_img(img_stack, 100, 20)
output_file = png_name if png_name is not None else str(pdf_path.joinpath(Path(pdf_name).stem + ".png").absolute())
# cv2.imwrite(str(tmp_img_name.absolute()), thin_img) # 不支持中文目录
# 采用下述方法保存到带中文的目录
cv2.imencode('.png', thin_img)[1].tofile(output_file)
def shrink_file(img_file,target_file):
pm_img = cv2.imread(img_file)
im = shrink_img(pm_img, 120, 20)
cv2.imwrite(target_file, im)
# Word文件转换为PDF
def doc_to_pdf(word_path, pdf_path):
try:
# 创建Word应用程序对象
word_app = win32com.client.Dispatch('Word.Application')
# 打开Word文档
doc = word_app.Documents.Open(word_path)
# 保存为PDF
doc.SaveAs(pdf_path, FileFormat=17)
# 关闭文档和应用程序
doc.Close()
word_app.Quit()
print(f'成功转换:{word_path} -> {pdf_path}')
return True
except Exception as e:
print(f'转换失败:{word_path},错误信息:{str(e)}')
return False
# 批量转换Word文件夹下的所有文档
def batch_doc_to_pdf_to_png(word_folder, pdf_folder):
# 检查PDF保存目录是否存在,若不存在则创建
if not os.path.exists(pdf_folder):
os.makedirs(pdf_folder)
# 遍历Word文件夹下的所有文件
for filename in os.listdir(word_folder):
if filename.endswith('.doc') or filename.endswith('.docx'):
word_path = os.path.join(word_folder, filename)
pdf_path = os.path.join(pdf_folder, f'{os.path.splitext(filename)[0]}.pdf')
print("STEP1:正在处理DOC_TO_PDF:")
print("DOC:" + word_path)
print("PDF:" + pdf_path)
doc_to_pdf(word_path, pdf_path)
print("STEP2:正在处理PDF_TO_PNG:")
pdf_2_png(pdf_path)
print("PDF:" + pdf_path + "转PNG完成")
if __name__ == '__main__':
# 调用批量转换函数进行转换
folder_path = os.path.dirname(os.path.abspath(__file__)) #py所在的文件夹
batch_doc_to_pdf_to_png(folder_path, folder_path)
注意事项:
1.要按照代码上的备注安装好依赖库。不常用的,我都写了备注。
2.把这个代发贴到py文件以后,把文件和WORD文档放在一个目录下,双击执行就可以。
3.注意:PDF合并成一张长图的时候,需要的时间较长,需要耐性等待一会。
三、执行效果
执行过程:
效果:
部分功能参考了网友的代码:
https://blog.csdn.net/trivialboy/article/details/130380086
相关推荐
- 30天学会Python编程:16. Python常用标准库使用教程
-
16.1collections模块16.1.1高级数据结构16.1.2示例...
- 强烈推荐!Python 这个宝藏库 re 正则匹配
-
Python的re模块(RegularExpression正则表达式)提供各种正则表达式的匹配操作。...
- Python爬虫中正则表达式的用法,只讲如何应用,不讲原理
-
Python爬虫:正则的用法(非原理)。大家好,这节课给大家讲正则的实际用法,不讲原理,通俗易懂的讲如何用正则抓取内容。·导入re库,这里是需要从html这段字符串中提取出中间的那几个文字。实例一个对...
- Python数据分析实战-正则提取文本的URL网址和邮箱(源码和效果)
-
实现功能:Python数据分析实战-利用正则表达式提取文本中的URL网址和邮箱...
- python爬虫教程之爬取当当网 Top 500 本五星好评书籍
-
我们使用requests和re来写一个爬虫作为一个爱看书的你(说的跟真的似的)怎么能发现好书呢?所以我们爬取当当网的前500本好五星评书籍怎么样?ok接下来就是学习python的正确姿...
- 深入理解re模块:Python中的正则表达式神器解析
-
在Python中,"re"是一个强大的模块,用于处理正则表达式(regularexpressions)。正则表达式是一种强大的文本模式匹配工具,用于在字符串中查找、替换或提取特定模式...
- 如何使用正则表达式和 Python 匹配不以模式开头的字符串
-
需要在Python中使用正则表达式来匹配不以给定模式开头的字符串吗?如果是这样,你可以使用下面的语法来查找所有的字符串,除了那些不以https开始的字符串。r"^(?!https).*&...
- 先Mark后用!8分钟读懂 Python 性能优化
-
从本文总结了Python开发时,遇到的性能优化问题的定位和解决。概述:性能优化的原则——优化需要优化的部分。性能优化的一般步骤:首先,让你的程序跑起来结果一切正常。然后,运行这个结果正常的代码,看看它...
- Python“三步”即可爬取,毋庸置疑
-
声明:本实例仅供学习,切忌遵守robots协议,请不要使用多线程等方式频繁访问网站。#第一步导入模块importreimportrequests#第二步获取你想爬取的网页地址,发送请求,获取网页内...
- 简单学Python——re库(正则表达式)2(split、findall、和sub)
-
1、split():分割字符串,返回列表语法:re.split('分隔符','目标字符串')例如:importrere.split(',','...
- Lavazza拉瓦萨再度牵手上海大师赛
-
阅读此文前,麻烦您点击一下“关注”,方便您进行讨论和分享。Lavazza拉瓦萨再度牵手上海大师赛标题:2024上海大师赛:网球与咖啡的浪漫邂逅在2024年的上海劳力士大师赛上,拉瓦萨咖啡再次成为官...
- ArkUI-X构建Android平台AAR及使用
-
本教程主要讲述如何利用ArkUI-XSDK完成AndroidAAR开发,实现基于ArkTS的声明式开发范式在android平台显示。包括:1.跨平台Library工程开发介绍...
- Deepseek写歌详细教程(怎样用deepseek写歌功能)
-
以下为结合DeepSeek及相关工具实现AI写歌的详细教程,涵盖作词、作曲、演唱全流程:一、核心流程三步法1.AI生成歌词-打开DeepSeek(网页/APP/API),使用结构化提示词生成歌词:...
- “AI说唱解说影视”走红,“零基础入行”靠谱吗?本报记者实测
-
“手里翻找冻鱼,精心的布局;老漠却不言语,脸上带笑意……”《狂飙》剧情被写成歌词,再配上“科目三”背景音乐的演唱,这段1分钟30秒的视频受到了无数网友的点赞。最近一段时间随着AI技术的发展,说唱解说影...
- AI音乐制作神器揭秘!3款工具让你秒变高手
-
在音乐创作的领域里,每个人都有一颗想要成为大师的心。但是面对复杂的乐理知识和繁复的制作过程,许多人的热情被一点点消磨。...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- 30天学会Python编程:16. Python常用标准库使用教程
- 强烈推荐!Python 这个宝藏库 re 正则匹配
- Python爬虫中正则表达式的用法,只讲如何应用,不讲原理
- Python数据分析实战-正则提取文本的URL网址和邮箱(源码和效果)
- python爬虫教程之爬取当当网 Top 500 本五星好评书籍
- 深入理解re模块:Python中的正则表达式神器解析
- 如何使用正则表达式和 Python 匹配不以模式开头的字符串
- 先Mark后用!8分钟读懂 Python 性能优化
- Python“三步”即可爬取,毋庸置疑
- 简单学Python——re库(正则表达式)2(split、findall、和sub)
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)
- vmware17pro最新密钥 (34)
- mysql单表最大数据量 (35)