Python:ODT转PDF前检查文件是否存在以避免重复转换
解决ODT转PDF的重复转换问题:检查对应文件是否存在
这个重复转换的问题确实挺浪费资源的,我来给你几个实用的解决方案——核心逻辑就是先检查目标PDF是否存在,甚至可以判断原ODT文件有没有更新,再决定要不要执行转换操作。
核心思路
对于目录里的每个.odt文件,我们需要做两件事:
- 生成对应的
.pdf文件名(比如report.odt对应report.pdf) - 检查:
- 如果对应的PDF文件不存在,就执行转换
- 如果PDF已存在,但原ODT文件的修改时间比PDF晚(说明ODT内容更新过),也需要重新转换
- 否则直接跳过
方案1:用Bash脚本实现(适合Linux/macOS终端)
如果习惯用命令行批量处理,这个脚本很方便:
#!/bin/bash # 遍历当前目录下所有.odt文件 for odt_file in *.odt; do # 提取不带后缀的文件名(比如把"note.odt"变成"note") base_name="${odt_file%.odt}" pdf_file="${base_name}.pdf" # 检查PDF是否不存在,或者ODT比PDF更新 if [ ! -f "$pdf_file" ] || [ "$odt_file" -nt "$pdf_file" ]; then echo "正在转换:$odt_file → $pdf_file" # 这里用LibreOffice的无头模式转换,你可以替换成自己的转换命令 libreoffice --headless --convert-to pdf "$odt_file" else echo "跳过:$pdf_file 已存在且未过时" fi done
关键命令解释
${odt_file%.odt}:自动去掉文件名的.odt后缀,生成基础文件名[ ! -f "$pdf_file" ]:判断PDF文件是否不存在[ "$odt_file" -nt "$pdf_file" ]:判断ODT文件的修改时间比PDF新(-nt是"newer than"的缩写)
方案2:用Python脚本实现(跨平台)
如果更熟悉Python,这个跨平台的脚本也很实用:
import os import subprocess def convert_odt(odt_filename): # 生成对应的PDF文件名 base_name = os.path.splitext(odt_filename)[0] pdf_filename = f"{base_name}.pdf" # 检查PDF状态 pdf_exists = os.path.exists(pdf_filename) if not pdf_exists: print(f"转换:{odt_filename} → {pdf_filename}") run_conversion(odt_filename) else: # 比较修改时间,判断ODT是否更新过 odt_mtime = os.path.getmtime(odt_filename) pdf_mtime = os.path.getmtime(pdf_filename) if odt_mtime > pdf_mtime: print(f"重新转换:{odt_filename} 已更新,覆盖旧PDF") run_conversion(odt_filename) else: print(f"跳过:{pdf_filename} 已存在且未过时") def run_conversion(odt_file): # 调用转换工具,这里用LibreOffice,可替换为你实际使用的命令 try: subprocess.run( ["libreoffice", "--headless", "--convert-to", "pdf", odt_file], check=True, capture_output=True ) except subprocess.CalledProcessError as e: print(f"转换失败:{odt_file},错误信息:{e.stderr.decode()}") # 遍历当前目录下的所有ODT文件 for file in os.listdir("."): if file.lower().endswith(".odt"): convert_odt(file)
注意事项
- 不管用哪种方案,只要替换掉脚本里的转换命令(比如你如果用其他工具转ODT,把
libreoffice相关的命令换成你的工具命令就行) - 如果需要处理子目录里的ODT文件,可以修改遍历逻辑(Bash用
find命令,Python用os.walk)
内容的提问来源于stack exchange,提问作者user7748633




