我的知识记录

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即可。

Python Excel转PDF:表格不溢出分页打印

标签:

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

上一篇:Python PDF提取目录书签 大纲导出教程

下一篇:Python加密PDF与解密PDF PyPDF2 方法