用Python的win32api库,WPS文档自动化生成技巧!
【摘要】 你好,我是忆~遂愿,全网4w+粉丝,《遂愿盈创》社群主理人。副业启航① | 遂愿盈创(对副业感兴趣免费可入,多种赚钱实战项目等你来,一起探寻副业快速变现的途径;以及对接互联网大厂商务合作,一起来搞点小外快,认识更多互联网大咖)目前群里已经带很多小伙伴(大部分大学生)变现几百块啦,程序员搞副业有额外加成~ 对副业感兴趣可+V : suiyuan2ying 拉你进群。在办公室搬砖的日子里,天天要...
你好,我是忆~遂愿,全网4w+粉丝,《遂愿盈创》社群主理人。
副业启航① | 遂愿盈创(对副业感兴趣免费可入,多种赚钱实战项目等你来,一起探寻副业快速变现的途径;以及对接互联网大厂商务合作,一起来搞点小外快,认识更多互联网大咖)
目前群里已经带很多小伙伴(大部分大学生)变现几百块啦,程序员搞副业有额外加成~ 对副业感兴趣可+V : suiyuan2ying 拉你进群。
在办公室搬砖的日子里,天天要写各种文档报告,复制粘贴改来改去,烦都烦死了。
每次都是打开Word,找模板,改内容,调格式,一天下来手都快点麻了。
最烦的是改完一份,还有一堆在等着,而且总会不小心改错几个地方。
直到我发现了Python的win32api库,这简直就是救命稻草啊!一个脚本搞定文档生成,不光省时间,还特别准确。
写好模板,准备好数据,一键运行就完事了,再也不用担心改错或者漏改了。
说实话,我一开始也没想到Python还能这么玩。
总觉得写文档这种事情,不就是复制粘贴吗?谁知道用代码来处理,不仅效率高得吓人,而且准确度简直完美。
要不是那天加班到半夜,实在受不了无止境的文档修改,也不会想到用代码来解放双手。
记得那天改到眼睛都花了,突然灵光一闪:这种重复性的工作,不就是最适合用代码来处理的吗?
现在好了,一杯咖啡的功夫,几百份文档就搞定了,老板都以为我加班到很晚呢!
最关键的是,代码生成的文档格式统一,内容准确,质量反而比手工做的更好。这下不仅省了时间,还收获了老板的赞赏,简直是一举两得!
说白了,win32api就是个能操控Windows程序的Python库。
它就像是个神奇的遥控器,能让Python代码直接控制Windows上的各种应用程序,包括Word、Excel、PowerPoint等办公软件。
它能直接跟WPS对话,就像你在用鼠标键盘操作一样。
比如你想打开一个Word文档,修改内容,调整格式,保存文件,这些都能用代码来完成,而且速度比手动操作快多了。
装这个库超简单,一行命令就搞定:
pip install pywin32
不过得注意啊,电脑上得先装好WPS或者Office,不然这代码就跑不起来了。
因为win32api本质上是在模拟你操作这些软件,没有安装相应的软件,代码自然就无处施展了。
还有个事儿,装完之后最好重启一下电脑,不然有时候会莫名其妙报错。
这是因为win32api需要在系统层面注册一些组件,重启能确保这些组件都正确加载了。
使用win32api的好处是,它能完美兼容现有的办公软件,你之前的文档模板都能继续用,不用改来改去。
而且它的操作特别灵活,几乎所有你能手动完成的操作,都能用代码来实现。对于需要批量处理文档的人来说,这简直就是办公自动化的利器!
来看看怎么跟WPS搭上线:
import win32com.client
import os
import time
from typing import Optional, Dict, List
class WPSConnection:
def __init__(self):
self.wps = None
self.doc = None
def connect(self) -> bool:
"""建立与WPS的连接"""
try:
self.wps = win32com.client.Dispatch('KWps.Application')
self.wps.Visible = True
print('WPS连接成功!')
return True
except Exception as e:
print(f'连接WPS失败:{str(e)}')
return False
def create_new_doc(self) -> bool:
"""创建新文档"""
try:
self.doc = self.wps.Documents.Add()
return True
except Exception as e:
print(f'创建文档失败:{str(e)}')
return False
def open_doc(self, path: str) -> bool:
"""打开现有文档"""
try:
self.doc = self.wps.Documents.Open(path)
return True
except Exception as e:
print(f'打开文档失败:{str(e)}')
return False
def close(self):
"""关闭连接"""
if self.doc:
self.doc.Close()
if self.wps:
self.wps.Quit()
温馨提示:要是报错说找不到KWps.Application,把KWps改成Word试试,有些版本用这个。
整个文档生成的过程,说复杂也不复杂。咱们先从简单的开始:
class DocumentGenerator:
def __init__(self):
self.wps_conn = WPSConnection()
def generate_simple_doc(self, title: str, content: str, save_path: str) -> bool:
"""生成简单文档"""
if not self.wps_conn.connect():
return False
try:
if not self.wps_conn.create_new_doc():
return False
selection = self.wps_conn.wps.Selection
# 写入标题
selection.TypeText(title)
selection.Font.Size = 16
selection.Font.Bold = True
selection.TypeParagraph()
# 写入正文
selection.TypeText(content)
selection.Font.Size = 12
selection.Font.Bold = False
# 保存文档
self.wps_conn.doc.SaveAs(save_path)
return True
except Exception as e:
print(f'生成文档时出错:{str(e)}')
return False
finally:
self.wps_conn.close()
这就是最基础的文档生成了。但是实际工作中,咱们往往需要更复杂的操作,比如:
来点进阶操作,看看怎么玩出花样:
class AdvancedDocumentGenerator:
def __init__(self):
self.wps_conn = WPSConnection()
def create_fancy_doc(self, config: Dict) -> bool:
"""创建花里胡哨的文档"""
if not self.wps_conn.connect():
return False
try:
if not self.wps_conn.create_new_doc():
return False
doc = self.wps_conn.doc
selection = self.wps_conn.wps.Selection
# 设置页面格式
doc.PageSetup.TopMargin = 72 # 1英寸
doc.PageSetup.BottomMargin = 72
doc.PageSetup.LeftMargin = 72
doc.PageSetup.RightMargin = 72
# 添加页眉
if config.get('header'):
header = doc.Sections(1).Headers(1)
header.Range.Text = config['header']
header.Range.Font.Size = 10
# 添加标题
selection.TypeText(config['title'])
selection.Font.Size = 20
selection.Font.Bold = True
selection.ParagraphFormat.Alignment = 1 # 居中
selection.TypeParagraph()
# 添加副标题
if config.get('subtitle'):
selection.TypeText(config['subtitle'])
selection.Font.Size = 14
selection.Font.Bold = True
selection.ParagraphFormat.Alignment = 1
selection.TypeParagraph()
# 添加正文
for paragraph in config['content']:
selection.TypeText(paragraph)
selection.Font.Size = 12
selection.Font.Bold = False
selection.ParagraphFormat.Alignment = 0 # 左对齐
selection.TypeParagraph()
# 插入表格
if config.get('table_data'):
table_data = config['table_data']
table = doc.Tables.Add(selection.Range,
len(table_data),
len(table_data[0]))
table.Borders.Enable = True
for i, row in enumerate(table_data):
for j, cell_value in enumerate(row):
table.Cell(i+1, j+1).Range.Text = str(cell_value)
selection.TypeParagraph()
# 插入图片
if config.get('images'):
for img_path in config['images']:
if self._check_image(img_path):
doc.InlineShapes.AddPicture(img_path)
selection.TypeParagraph()
# 添加页脚
if config.get('footer'):
footer = doc.Sections(1).Footers(1)
footer.Range.Text = config['footer']
footer.Range.Font.Size = 10
# 保存文档
doc.SaveAs(config['save_path'])
return True
except Exception as e:
print(f'生成高级文档时出错:{str(e)}')
return False
finally:
self.wps_conn.close()
def _check_image(self, image_path: str) -> bool:
"""检查图片是否合法"""
allowed_formats = ['.png', '.jpg', '.jpeg']
try:
file_size = os.path.getsize(image_path) / (1024 * 1024)
if not any(image_path.lower().endswith(fmt) for fmt in allowed_formats):
print(f'图片 {image_path} 格式不支持')
return False
if file_size > 5:
print(f'图片 {image_path} 太大了({file_size:.2f}MB)')
return False
return True
except Exception as e:
print(f'检查图片时出错:{str(e)}')
return False
办公室最常见的就是各种报表了,来看看怎么自动化生成:
class ReportGenerator:
def __init__(self):
self.wps_conn = WPSConnection()
def generate_weekly_report(self,
week_num: int,
data: Dict[str, List[str]],
template_path: Optional[str] = None) -> bool:
"""生成周报"""
if not self.wps_conn.connect():
return False
try:
# 使用模板或创建新文档
if template_path and os.path.exists(template_path):
if not self.wps_conn.open_doc(template_path):
return False
else:
if not self.wps_conn.create_new_doc():
return False
doc = self.wps_conn.doc
selection = self.wps_conn.wps.Selection
# 优化性能
self._optimize_performance()
# 设置标题
selection.TypeText(f'第{week_num}周工作周报')
selection.Font.Size = 16
selection.Font.Bold = True
selection.ParagraphFormat.Alignment = 1
selection.TypeParagraph()
selection.TypeParagraph()
# 工作内容
if data.get('completed_tasks'):
selection.TypeText('本周完成工作:')
selection.Font.Size = 14
selection.Font.Bold = True
selection.TypeParagraph()
for task in data['completed_tasks']:
selection.TypeText(f' • {task}')
selection.Font.Size = 12
selection.Font.Bold = False
selection.TypeParagraph()
selection.TypeParagraph()
# 下周计划
if data.get('planned_tasks'):
selection.TypeText('下周工作计划:')
selection.Font.Size = 14
selection.Font.Bold = True
selection.TypeParagraph()
for task in data['planned_tasks']:
selection.TypeText(f' • {task}')
selection.Font.Size = 12
selection.Font.Bold = False
selection.TypeParagraph()
selection.TypeParagraph()
# 问题和建议
if data.get('issues'):
selection.TypeText('存在的问题和建议:')
selection.Font.Size = 14
selection.Font.Bold = True
selection.TypeParagraph()
for issue in data['issues']:
selection.TypeText(f' • {issue}')
selection.Font.Size = 12
selection.Font.Bold = False
selection.TypeParagraph()
# 添加签名和日期
selection.TypeParagraph()
selection.TypeParagraph()
selection.TypeText('汇报人:' + data.get('reporter', ''))
selection.TypeParagraph()
selection.TypeText('日期:' + time.strftime('%Y-%m-%d'))
# 保存文档
save_path = os.path.join(os.getcwd(), f'周报_{week_num}.docx')
doc.SaveAs(save_path)
return True
except Exception as e:
print(f'生成周报时出错:{str(e)}')
return False
finally:
# 恢复性能设置
self._restore_performance()
self.wps_conn.close()
def _optimize_performance(self):
"""优化性能设置"""
self.wps_conn.wps.ScreenUpdating = False
self.wps_conn.wps.Options.BackgroundSave = False
def _restore_performance(self):
"""恢复性能设置"""
self.wps_conn.wps.ScreenUpdating = True
self.wps_conn.wps.Options.BackgroundSave = True
要是要处理几百份文档,一个一个来肯定不行,得上批量处理:
class BatchProcessor:
def __init__(self):
self.wps_conn = WPSConnection()
def process_multiple_docs(self,
source_folder: str,
output_folder: str,
process_func,
max_workers: int = 4) -> Dict[str, int]:
"""批量处理文档"""
from concurrent.futures import ThreadPoolExecutor
import threading
if not os.path.exists(output_folder):
os.makedirs(output_folder)
# 统计数据
stats = {
'success': 0,
'failed': 0,
'skipped': 0
}
stats_lock = threading.Lock()
def process_single_doc(file_path: str):
try:
if not file_path.endswith(('.doc', '.docx')):
with stats_lock:
stats['skipped'] += 1
return
output_path = os.path.join(
output_folder,
f'processed_{os.path.basename(file_path)}'
)
if process_func(file_path, output_path):
with stats_lock:
stats['success'] += 1
else:
with stats_lock:
stats['failed'] += 1
except Exception as e:
print(f'处理文件 {file_path} 时出错:{str(e)}')
with stats_lock:
stats['failed'] += 1
# 获取所有文件
files = [
os.path.join(source_folder, f)
for f in os.listdir(source_folder)
if os.path.isfile(os.path.join(source_folder, f))
]
# 使用线程池处理
with ThreadPoolExecutor(max_workers=max_workers) as executor:
executor.map(process_single_doc, files)
return stats
平时工作中经常用到的一些小功能,我都封装成了工具类:
class DocUtils:
@staticmethod
def convert_to_pdf(doc_path: str, pdf_path: str) -> bool:
"""转换文档为PDF"""
try:
wps = win32com.client.Dispatch('KWps.Application')
doc = wps.Documents.Open(doc_path)
doc.SaveAs(pdf_path, 17) # 17 是 PDF 格式的代码
doc.Close()
wps.Quit()
return True
except Exception as e:
print(f'转换PDF时出错:{str(e)}')
return False
@staticmethod
def merge_docs(doc_paths: List[str], output_path: str) -> bool:
"""合并多个文档"""
try:
wps = win32com.client.Dispatch('KWps.Application')
merged_doc = wps.Documents.Add()
for doc_path in doc_paths:
merged_doc.Application.Selection.InsertFile(doc_path)
merged_doc.Application.Selection.InsertBreak(7) # 分页符
merged_doc.SaveAs(output_path)
merged_doc.Close()
wps.Quit()
return True
except Exception as e:
print(f'合并文档时出错:{str(e)}')
return False
@staticmethod
def extract_text(doc_path: str) -> str:
"""提取文档中的文本"""
try:
wps = win32com.client.Dispatch('KWps.Application')
doc = wps.Documents.Open(doc_path)
text = doc.Content.Text
doc.Close()
wps.Quit()
return text
except Exception as e:
print(f'提取文本时出错:{str(e)}')
return ''
来看看怎么用这些类:
def main():
# 生成简单文档
gen = DocumentGenerator()
gen.generate_simple_doc(
title="测试文档",
content="这是一个测试文档的内容",
save_path="test.docx"
)
# 生成周报
report_gen = ReportGenerator()
report_data = {
'completed_tasks': [
'完成了项目A的开发',
'修复了3个bug',
'参加了2次技术评审'
],
'planned_tasks': [
'开始项目B的开发',
'优化现有代码'
],
'issues': [
'服务器性能需要优化',
'需要更多的单元测试'
],
'reporter': '小忆'
}
report_gen.generate_weekly_report(1, report_data)
# 批量处理文档
batch = BatchProcessor()
stats = batch.process_multiple_docs(
'input_folder',
'output_folder',
lambda x, y: DocUtils.convert_to_pdf(x, y)
)
print(f'处理结果:{stats}')
这些代码够你玩一阵子了。记住啊,代码写完多测试,别一上来就真实数据,万一出问题就尴尬了。
自动化是好,但也得留个心眼,别把文档搞丢了。
还有个事儿,这些代码都是我实际用过的,但是不同的WPS版本可能会有点差异,用的时候记得调试一下。
要是遇到问题,就在代码里加点日志,方便排查。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
评论(0)