Python Excel转PDF:表格不溢出分页打印
用Python+LibreOffice把xlsx批量转PDF,自动适配A4纸张、缩放列宽,避免表格被切到多页,适合把对账单、报表批量导出成PDF归档。
场景痛点
Excel报表发给客户,对方没装Office打开就是乱码;手动在Excel里设置打印区域、缩放到一页宽、另存PDF,几十个工作表做一遍人就废了。直接复制LibreOffice的转换命令最省事,配合一个简单的"每页一页宽"配置,转出来的PDF表格不裁切、不溢出。
用到的库
# 同样依赖 LibreOffice(见 Word 转 PDF 那篇的安装方式)
pip install openpyxl # 可选,用来微调打印设置
完整代码
# -*- coding: utf-8 -*-
"""
把 xlsx 文件批量转成 PDF,自动设置打印缩放为"一页宽",防止表格被切断。
"""
import subprocess
from pathlib import Path
from openpyxl import load_workbook
from openpyxl.worksheet.page import PageMargins
def setup_print_area(xlsx_path: str):
"""用 openpyxl 给每个工作表设置打印参数:A4、横向、一页宽、窄边距。"""
wb = load_workbook(xlsx_path)
for ws in wb.worksheets:
ws.page_setup.paperSize = ws.PAPERSIZE_A4
ws.page_setup.orientation = ws.ORIENTATION_LANDSCAPE
# fitToWidth=1 表示宽度缩到 1 页高,fitToHeight=0 表示高度不限制
ws.page_setup.fitToWidth = 1
ws.page_setup.fitToHeight = 0
ws.sheet_properties.pageSetUpPr.fitToPage = True
ws.page_margins = PageMargins(left=0.4, right=0.4, top=0.5, bottom=0.5)
wb.save(xlsx_path)
def excel_to_pdf(xlsx_path: str, output_dir: str, soffice: str = "soffice") -> str:
out = Path(output_dir)
out.mkdir(parents=True, exist_ok=True)
cmd = [
soffice, "--headless", "--norestore",
"--convert-to", "pdf:calc_pdf_Export:SinglePageSheets",
"--outdir", str(out),
str(xlsx_path),
]
subprocess.run(cmd, check=True, capture_output=True)
return str(out / (Path(xlsx_path).stem + ".pdf"))
def batch_excel_to_pdf(input_dir: str, output_dir: str, soffice: str = "soffice"):
src = Path(input_dir)
files = list(src.glob("*.xlsx")) + list(src.glob("*.xls"))
print(f"发现 {len(files)} 个 Excel 文件")
for f in files:
try:
# 先调整打印设置
setup_print_area(str(f))
pdf = excel_to_pdf(str(f), output_dir, soffice)
print(f"完成:{pdf}")
except Exception as e:
print(f"失败:{f.name} -> {e}")
if __name__ == "__main__":
batch_excel_to_pdf(
input_dir="excel_files",
output_dir="pdf_out",
soffice="soffice", # Windows 改成完整路径,如 C:/Program Files/LibreOffice/program/soffice.exe
)
代码讲解
setup_print_area先用openpyxl打开原文件,给每个sheet设置:A4纸、横向打印、fitToWidth=1让所有列缩在一页宽里、fitToHeight=0允许纵向多页,这样长表格不会被从中间切断。ws.sheet_properties.pageSetUpPr.fitToPage = True这行必须有,否则上面的fitToWidth设置不生效。--convert-to "pdf:calc_pdf_Export:SinglePageSheets"是LibreOffice Calc专用的PDF导出过滤器,参数SinglePageSheets让每个工作表单独成页。- 流程是"先改打印设置→再调LibreOffice转换",两步缺一不可。
运行结果
把xlsx放进excel_files/,跑完在pdf_out/得到同名PDF,打开后每个工作表占一页或多页,但所有列都在同一页宽度内,不会出现一列被切到下一页的情况。
注意事项
- openpyxl只能读写
.xlsx,老的.xls不支持读打印设置,这一步会跳过,但LibreOffice本身还能转。 - 中文字体在Linux服务器上如果没装,转出来PDF里的中文会变成方块,记得装
fonts-wqy-zenhei之类的中文字体包。 - 公式单元格转PDF时显示的是计算后的值,LibreOffice会自动重算,不用担心。
- 如果只需要把某几个sheet转PDF,改
setup_print_area里遍历工作表的逻辑,跳过不需要的sheet即可。

更新时间:2026-09-14 21:40:17