去年接手公司文档数字化项目时,我频繁遇到两个痛点场景:一是需要将大量产品照片归档为PDF报告,二是收到的PDF技术文档需要转为Word进行二次编辑。市面上的在线工具要么收费昂贵,要么存在数据安全隐患。于是我用Python+PySide6开发了这款本地复合文件处理工具,今天就把完整开发过程和关键技术点分享给大家。
这个工具最核心的价值在于:
在GUI框架选型时,我对比了Tkinter、PyQt和PySide6三个主流方案:
| 框架 | 授权协议 | 文档完善度 | 社区活跃度 | 开发效率 |
|---|---|---|---|---|
| Tkinter | Python标准 | 一般 | 低 | 低 |
| PyQt | 商业授权 | 优秀 | 高 | 高 |
| PySide6 | LGPL | 优秀 | 高 | 高 |
最终选择PySide6主要基于:
python复制# 主要依赖库
requirements = [
"PySide6>=6.4.0", # GUI框架
"reportlab>=3.6.12", # PDF生成
"pdf2docx>=0.5.6", # PDF转Word
"Pillow>=9.5.0", # 图像处理
"qasync>=0.23.0" # 异步支持
]
特别说明几个关键库的选择考量:
核心代码结构:
python复制class ImageLoader(QWidget):
def __init__(self):
self.image_list = [] # 存储图片路径
self.current_index = -1
def dragEnterEvent(self, event):
"""支持拖拽文件到窗口"""
if event.mimeData().hasUrls():
event.accept()
def dropEvent(self, event):
"""处理拖放文件"""
for url in event.mimeData().urls():
file_path = url.toLocalFile()
if self._is_image(file_path):
self.image_list.append(file_path)
self._update_preview()
关键实现细节:
实测中发现当处理大量高清图片时,会出现内存不足问题。通过以下优化解决:
python复制def generate_pdf(output_path, image_paths):
c = canvas.Canvas(output_path, pagesize=A4)
for i, img_path in enumerate(image_paths):
img = Image.open(img_path)
# 尺寸调整逻辑
if max(img.size) > 2000:
img.thumbnail((2000, 2000))
# 居中绘制
draw_image_centered(c, img)
c.showPage()
# 每10页保存一次
if i % 10 == 0:
c.save()
c.save()
为避免大文件转换时界面卡死,采用如下异步方案:
python复制class ConverterThread(QThread):
progress_updated = Signal(int)
def __init__(self, pdf_path, docx_path):
self.pdf_path = pdf_path
self.docx_path = docx_path
def run(self):
parse(pdf_path=self.pdf_path,
docx_path=self.docx_path,
progress_callback=self._update_progress)
def _update_progress(self, progress):
self.progress_updated.emit(progress)
使用注意:
通过分析pdf2docx的转换逻辑,发现以下优化点:
python复制def convert_pdf_to_word(pdf_path, docx_path):
cv = Converter(pdf_path)
cv.convert(docx_path,
font_map={"SimSun": "宋体"}, # 字体映射
table_settings={"min_row_gap": 10}, # 表格识别
image_settings={"min_dpi": 150}) # 图片质量
cv.close()
采用Qt Designer设计.ui文件,主要区域划分:
xml复制<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<widget class="QTabWidget" name="tabWidget">
<widget class="QWidget" name="tabImage2Pdf">
<!-- 图片转PDF界面 -->
</widget>
<widget class="QWidget" name="tabPdf2Word">
<!-- PDF转Word界面 -->
</widget>
</widget>
</widget>
</ui>
为提升操作反馈,添加了以下微交互:
实现代码示例:
python复制# 删除动画
animation = QPropertyAnimation(item, b"opacity")
animation.setDuration(300)
animation.setStartValue(1.0)
animation.setEndValue(0.0)
animation.finished.connect(lambda: item.deleteLater())
animation.start()
推荐配置:
bash复制pyinstaller --onefile --windowed \
--add-data "assets;assets" \
--icon=app.ico \
main.py
常见问题处理:
使用Inno Setup创建Windows安装程序:
ini复制[Setup]
AppName=复合文件工具
AppVersion=1.0
DefaultDirName={pf}\FileTool
OutputDir=output
Compression=lzma2
[Files]
Source: "dist\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs
图片排序算法:实现自然排序(如img1, img2,...img10),避免字典序导致的错乱
python复制import re
def natural_sort_key(s):
return [int(text) if text.isdigit() else text.lower()
for text in re.split('([0-9]+)', s)]
sorted_images = sorted(images, key=natural_sort_key)
PDF加密处理:遇到加密PDF时自动跳过并提示
python复制try:
cv = Converter(pdf_path)
except Exception as e:
if "encrypted" in str(e):
show_warning("该PDF已加密,请先解除密码")
性能监控:添加内存使用警告
python复制if psutil.virtual_memory().percent > 90:
show_warning("内存使用过高,建议减少处理文件数量")
这个项目让我深刻体会到,即使是看似简单的工具开发,也需要考虑异常处理、性能优化、用户体验等方方面面。后续计划加入OCR文字识别功能,让PDF转Word时能提取扫描件中的文字。