· 喵窝资源铺
投递季最常见的死循环:招聘平台只收 PDF,你手里是几十份 .docx 简历,一个个「另存为 PDF」改到怀疑人生。本篇用 soffice --headless --convert-to pdf 批量转,走的是 LibreOffice 渲染引擎——字体、表格、分页和你在 Word 里看到的几乎一致,是「保真」路线;如果只要正文和表格内容、服务器上不方便装 LibreOffice,可以看纯 Python 版(python-docx + reportlab),两篇互为补充。
文中代码实跑验证,真实输出贴在下面,坑也是实跑踩出来的。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Word简历批量转PDF:soffice --convert-to pdf,只扫顶层,
锁文件/非docx跳过,同名不覆盖"""
import os, sys, subprocess
SRC = sys.argv[1] if len(sys.argv) > 1 else "."
OUT = sys.argv[2] if len(sys.argv) > 2 else os.path.join(SRC, "pdf")
os.makedirs(OUT, exist_ok=True)
moved, skipped = [], []
for f in sorted(os.listdir(SRC)):
p = os.path.join(SRC, f)
if not os.path.isfile(p):
continue # 子目录不递归,防输出目录套娃
if f.startswith("~$"):
skipped.append((f, "Office锁文件")); continue
if not f.lower().endswith(".docx"):
skipped.append((f, "非.docx")); continue
dst = os.path.join(OUT, f[:-5] + ".pdf")
if os.path.exists(dst):
skipped.append((f, "目标PDF已存在,不覆盖")); continue
# 一次转一个文件最稳(并发实例会抢同一 profile 互相踢)
r = subprocess.run(
["soffice", "--headless", "--convert-to", "pdf",
"--outdir", OUT, p],
capture_output=True, text=True, timeout=120)
if r.returncode == 0 and os.path.exists(dst):
moved.append((f, os.path.basename(dst)))
else:
skipped.append((f, "转换失败: "
+ (r.stderr or r.stdout).strip()[:80]))
print(f"共转换 {len(moved)} 个,跳过 {len(skipped)} 个")
for f, d in moved: print(f" [转出] {f} -> {d}")
for f, d in skipped: print(f" [跳过] {f}: {d}")
测试集:5 份简历(中文 4 + 英文文件名 1)、1 个 说明.txt、1 个 Word 锁文件 ~$张三简历.docx、1 个子目录(里面还藏了份简历)、输出目录 pdf/ 就放在源目录里,且预先放了一份旧的假 张三简历.pdf(内容 "OLD"):
共转换 4 个,跳过 4 个 [转出] Tom_Smith简历.docx -> Tom_Smith简历.pdf [转出] 李四简历.docx -> 李四简历.pdf [转出] 王五简历.docx -> 王五简历.pdf [转出] 赵六简历.docx -> 赵六简历.pdf [跳过] batch_docx2pdf.py: 非.docx [跳过] ~$张三简历.docx: Office锁文件 [跳过] 张三简历.docx: 目标PDF已存在,不覆盖 [跳过] 说明.txt: 非.docx
第二遍再跑:
共转换 0 个,跳过 8 个 (全部「目标PDF已存在,不覆盖」——幂等)
转出的 PDF 用 pdftotext 抽文本核对,标题/姓名/意向逐份对得上,中文字形正常。预置的假 张三简历.pdf(3 字节的 "OLD")全程原封未动。
soffice --convert-to,输出里轻飘飘一行 Overwriting: ...,旧文件直接没了、退出码 0。批量场景里上一批的成果可能被冲掉——所以脚本先查 exists 跳过并报告,不搞自动改名(文件悄悄变多对不上账更糟)。--outdir 指到源目录本身,soffice 直接拒绝转换。实测报错罢工。所以输出目录要么独立、要么像本例的 pdf/ 子目录——反正脚本只扫顶层不递归,不会把自己的输出再吃进去。-env:UserInstallation=file:///tmp/lo_profile_N 给每个实例分独立 profile。~$ 锁文件会被当正经文件转。Word 开着的文档旁边有个 ~$xxx.docx 临时文件,扔给 soffice 转出来是个垃圾 PDF。文件名开头判断 startswith("~$") 直接跳过。(和之前归档脚本踩的是同一个家族的坑:临时文件不在目录列表末尾,按扩展名过滤拦不住。)apt-get install libreoffice-writer,无界面也能跑);完全没有安装权限的服务器请用纯 Python 版。← 返回喵窝资源铺 · 相关:纯 Python 版 Word 批量转 PDF(不装 LibreOffice) · 相关:乱码文件批量转 UTF-8