我开源了一个支持中文和大文件的 TXT 转 PDF 工具

0 阅读4分钟

最近把一个自己在用的 TXT -> PDF 在线工具整理开源了。

项目地址:

这个项目本来只是想解决一个很朴素的问题:

把中文 TXT 文件稳定地转成 PDF。

但真正做起来之后,问题很快就从“文本转 PDF”本身,变成了:

  • 中文渲染怎么保证不乱码
  • 大文件怎么处理
  • Serverless 平台上怎么避免请求体超限
  • 多片 PDF 最后怎么合并才不会炸

最后整理成了这个项目:

  • 支持中文 TXT 转 PDF
  • 支持大文件分片转换
  • 支持浏览器端合并 PDF
  • 支持部署到 Vercel
  • 支持在线上传、预览、导出

为什么会做这个

很多在线 txt 转 pdf 工具在下面这些场景里很容易出问题:

  • 中文内容导出后乱码
  • 稍大一点的 TXT 文件直接失败
  • 代码、日志、小说这类纯文本内容导出排版一般
  • 放到 Vercel 这种 Serverless 平台后,大文件流程很容易撞限制

这个项目就是围绕这些问题一点点补出来的。


最初方案其实很直观

一开始的思路很简单:

  1. 前端上传 TXT
  2. 后端把文本转成 PDF
  3. 如果文件太大,就切片上传
  4. 后端再把多个 PDF 片段合并成一个完整 PDF

看起来很合理,但真正部署到 Vercel 之后,很快就遇到了问题。


真正的坑:不是转换,而是“合并”

单片转换其实问题不大。

文本按 3MB 左右切片后,逐片调用 /api/convert,每片独立生成 PDF,这一段在 Vercel 上是能跑通的。

真正麻烦的是最后一步:

多个 PDF 片段怎么合并。

最开始我走的是服务端合并:

  • 每片 TXT 转完后得到 PDF
  • 前端把这些 PDF 再传给 /api/merge
  • 后端用 pypdf 合并

这个方案本地没问题,但在线上很快碰到典型错误:

FUNCTION_PAYLOAD_TOO_LARGE
Request Entity Too Large

也就是说:

问题不是 Python 逻辑写错,而是合并请求本身超过了平台限制。


为什么会超限

原因其实也不复杂。

大文件会被切成多个文本片段,每个片段再转换成 PDF。
如果最后把这些 PDF 一次性回传给服务端合并,不管你是:

  • JSON + base64
  • multipart/form-data
  • 分批合并后再继续上传

只要合并后的中间 PDF 越来越大,最终还是会继续撞请求体上限。

这类问题在 Serverless 场景里特别典型:

  • 单步逻辑看起来没问题
  • 但链路一长,请求体、超时、内存这些限制就会一起冒出来

最后怎么解决

最后这条链路我改成了:

后端负责“生成每一片 PDF”,浏览器负责“合并所有 PDF”。

也就是:

text

TXT 大文件 → 前端切片 → 每片请求 /api/convert → 得到多个 PDF Blob → 浏览器端使用 pdf-lib 合并 → 直接下载最终 PDF

这一步改完之后,整个思路就顺了很多:

  • Vercel 只负责单片 PDF 生成
  • 不再承受超大的 merge 请求体
  • 最容易炸的部分直接转移到浏览器端
  • 大文件场景也更稳定

这其实是一个很典型的经验:

当平台对请求体和函数执行有明显限制时,尽量让服务端做“单步、短链路、可分片”的事,把可前移的聚合逻辑前移到客户端。


当前实现方案

项目现在的核心思路是:

1. 中文 PDF 渲染

使用 reportlab + STSong-Light CID 字体,解决中文显示问题。

2. 大文件分片转换

前端读取 TXT 后按字节分片,避免单次请求过大。

3. 浏览器端合并 PDF

前端拿到所有片段 PDF 后,通过 pdf-lib 在浏览器中直接合并,不再依赖服务端 merge。

4. Vercel 部署

保留“静态前端 + Python Function”的简单部署结构,尽量让项目易部署、易演示、易复用。


适合什么场景

这个项目目前比较适合:

  • 中文小说 TXT 转 PDF
  • 代码文件、日志文件归档成 PDF
  • 做一个可在线使用的 txt2pdf 小工具
  • 参考“Serverless + 浏览器端合并”的处理方式

目前仓库已经补了这些内容

为了把它做成一个更完整的开源项目,我也顺手把仓库门面整理了一下:

  • 中英文 README
  • 在线演示地址
  • 首页截图
  • Demo GIF
  • Use Cases
  • Roadmap
  • v1.0.0 tag / release

仓库地址:
github.com/xqnode/txt2…


后续计划

后面还打算继续补这些能力:

  • 自定义边距、字号、行距
  • 页眉页脚、页码、封面
  • 更多文本格式支持
  • 更适合超大文件的后端方案(对象存储 / 队列 / 任务化处理)

最后

如果你也在做这类文本处理、PDF 导出,或者刚好在 Vercel / Serverless 场景里碰到类似的请求体限制问题,欢迎来看看这个项目。

在线体验:
txt2pdf.vercel.app/

GitHub:
github.com/xqnode/txt2…