Python 批量 TXT 转 PDF(WeasyPrint 极简版)

Python 批量 TXT 转 PDF(WeasyPrint 极简版)

一、功能

  • 批量 .txt → 单个 output.pdf
  • 每个 TXT 自动分页
  • 第一行作为标题(加粗居中)
  • 中文正常显示
  • 自动页码(右下角)

二、安装依赖

1. 安装 WeasyPrint

bash 复制代码
pip3 install weasyprint

2. Mac 额外依赖

bash 复制代码
brew install pango cairo libffi

三、使用方法

1. 准备 TXT 文件

text 复制代码
1.txt
2.txt
10.txt

2. 新建脚本 txt2pdf.py

复制下面代码:

python 复制代码
from pathlib import Path
from html import escape
from weasyprint import HTML
import re


def natural_sort_key(p: Path):
    """
    让 1.txt 2.txt 10.txt 按数字顺序排序,而不是字符串排序
    """
    return [
        int(x) if x.isdigit() else x.lower()
        for x in re.split(r"(\d+)", p.stem)
    ]


TEMPLATE = """<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">

<style>

@page {{
    size: A4;
    margin: 10mm 8mm;

    @bottom-right {{
        content: counter(page);
        font-family: "PingFang SC", "Hiragino Sans GB", "STHeiti", "Noto Sans CJK SC", sans-serif;
        font-size: 10pt;
        color: #666;
    }}
}}

body {{
    margin: 0;
    padding: 0;

    background: white;
    color: #222;

    font-family:
        "PingFang SC",
        "Hiragino Sans GB",
        "STHeiti",
        "Noto Sans CJK SC",
        sans-serif;

    font-size: 16px;
    line-height: 1.6;

    -webkit-font-smoothing: antialiased;
}}

.chapter {{
    break-before: page;
}}

.chapter:first-child {{
    break-before: auto;
}}

.title {{
    font-size: 22px;
    font-weight: bold;
    text-align: center;

    line-height: 1.4;

    margin: 0 0 18px 0;
    padding-bottom: 10px;

    border-bottom: 1px solid #ddd;
}}

pre {{
    margin: 0;

    font: inherit;
    line-height: inherit;

    white-space: pre-wrap;
    word-break: break-word;
    overflow-wrap: anywhere;
}}

</style>

</head>
<body>

{content}

</body>
</html>
"""


def build_chapters(txt_files):
    chapters = []

    for txt_file in txt_files:
        text = txt_file.read_text(encoding="utf-8")

        lines = text.splitlines()

        if lines:
            title = escape(lines[0].strip())
            body = escape("\n".join(lines[1:]))
        else:
            title = ""
            body = ""

        chapters.append(f"""
<div class="chapter">
    <div class="title">{title}</div>
    <pre>{body}</pre>
</div>
""")

    return "\n".join(chapters)


def main():
    txt_files = sorted(
        Path(".").glob("*.txt"),
        key=natural_sort_key
    )

    if not txt_files:
        print("没有找到 txt 文件")
        return

    content = build_chapters(txt_files)

    html = TEMPLATE.format(content=content)

    HTML(
        string=html,
        base_url="."
    ).write_pdf("output.pdf")

    print(f"✓ 已生成 output.pdf,共 {len(txt_files)} 个 TXT 文件")


if __name__ == "__main__":
    main()

3. 运行

bash 复制代码
python3 txt2pdf.py

四、效果

  • 每个 TXT 自动分页
  • 第一行自动变标题
  • 右下角页码
  • 中文正常

五、一句话原理

用 HTML 做排版,用 WeasyPrint 转 PDF


六、后续可扩展(可选)

  • 封面页
  • 目录页
  • 小说首行缩进
  • 页眉文件名