上传文件
  1. base64hub
  2. 文件工具
  3. Base64 转 PDF

Base64 转 PDF

把 API 响应、电子发票或邮件附件里的 Base64 粘贴进来,PDF 就会在本页打开,并附带下载按钮。解码和预览都在你的浏览器中完成。

免费 无需注册,不限次数 本地 不上传任何内容 检查项 版本、页数、标题、加密 更新于 2026年10月27日
输入 –输出 –大小 –

在你的浏览器中处理。此页面无法将你的数据发送到任何地方: 我们如何确认

如何将 Base64 解码为 PDF

  1. 把字符串粘贴到 Base64 或 data URI。完整的 data:application/pdf;base64,… URI 可以直接用,换行、两侧的引号、URL 安全的 Base64(- 和 _)以及缺失的 = 填充也都没问题。如果长字符串保存在文件里,请使用 打开 .txt 文件 或把文件拖到输入框上;超过 4 MB 的内容会直接解码,不在文本框中显示。
  2. 预览会出现在按钮下方。粘贴后立即开始解码;如果想自己点击 解码,取消勾选 实时 即可。
  3. 检查 文件名。默认是 decoded,但如果 data URI 中有 name= 参数,或者你打开的是文本文件,就会沿用那个名字:invoice.pdf.b64.txt 会变成 invoice.pdf。
  4. 点击 下载文件。预览下方的 在新标签页中打开 链接会以全尺寸显示同一个 PDF。

页面打开时会加载一个示例 PDF,在粘贴自己的数据之前,你可以先看看正常的结果是什么样子。

Base64 PDF 从哪里来

JSON 无法直接承载原始字节,所以通过 JSON API 返回文档的服务会把文档作为 Base64 字符串发送,字段名通常类似 content、document、file 或 label。

  • 面单和物流 API 会把可打印的快递面单作为 Base64 PDF 返回。同一个请求往往也可以根据格式参数返回 ZPL 或 PNG,所以名为“PDF”的字段不一定真的是 PDF(见下文的表格)。
  • 电子签名服务会在完成响应或 webhook 中以 Base64 返回已签署的文档,常常还附带一份单独的审计证书。
  • UBL XML 格式的电子发票会在 <cbc:EmbeddedDocumentBinaryObject mimeCode="application/pdf" filename="INV-1001.pdf"> 这样的元素中嵌入一份便于阅读的 PDF 副本。复制标签之间的文本即可;filename 属性告诉你 文件名 里该填什么。
  • 在电子邮件的原始源码中,PDF 附件是一个带 Content-Transfer-Encoding: base64 的 MIME 部分,每行 76 个字符。只粘贴编码块就行,或者用 EML 解码器 打开整封邮件,它会列出所有附件。邮件中的 Base64 讲解了邮件结构。
  • 存放在数据库 BLOB 列中的文档经常被导出为文本。PostgreSQL 的 encode(data, 'base64') 以及 MySQL 或 MariaDB 的 TO_BASE64() 都会每 76 个字符插入一个换行;解码器会跳过它们。

如果一个 JSON 响应里有多个编码字段,解码 JSON 中的 Base64 可以一次性找到并全部解码。反方向操作,即把 PDF 文件转成字符串,请使用 PDF 转 Base64。

预览会显示什么

字段来源
PDF 版本文件头行,例如 %PDF-1.7
页数根据文件中的页面对象统计(见下文)
标题文档信息中的标题,前提是以纯文本存储
已加密文件含有加密字典时出现:可能是打开密码,也可能只是权限限制
SHA-256解码后字节的哈希。让发送方对比 sha256sum invoice.pdf 的结果,就能证明文件完好送达

预览本身就是浏览器的 PDF 查看器,它通过本地 blob: URL 显示解码后的字节。Chrome、Edge、Firefox 和桌面版 Safari 会直接内嵌显示。如果浏览器被设置为下载 PDF 而不是打开(Chrome:设置、隐私和安全、网站设置、更多内容设置、PDF 文档;Firefox:设置、常规、应用程序、Portable Document Format),预览会保持空白;很多移动浏览器根本无法在页面内渲染 PDF。这些情况下,在新标签页中打开 和 下载文件 仍然可用,预览上方的信息列表也照样会填好。

页数是怎么统计的

工具不会为了统计页数而渲染 PDF。它会在文件的前 32 MB 中统计页面对象(/Type /Page)。如果一个都找不到,就读取页面树的 /Count 条目;如果这个也看不到,就显示 未知。有两种情况会让这个数字和查看器显示的不一致:

  • 页数偏多。 创建后又经过编辑、批注或签名的 PDF 通常采用增量保存:修改过的页面作为新对象追加到文件末尾,旧版本仍留在文件中。在一个有 2 页、其中一页被重写过的测试文件中,统计结果是 3。
  • 未知。 从 PDF 1.5 开始,对象可以打包进压缩的对象流,这时不解压就既读不到页面对象,也读不到页面树。

两者不一致时,以查看器显示的页数为准。

结果不是 PDF 时

如果解码后的字节是其他内容,字段上方会有一条提示说明检测到了什么,例如“这看起来是 HTML,而不是 PDF。”,并附带 下载为 .html 按钮。Base64 的开头通常就能说明问题所在:

Base64 开头实际内容
JVBERi0PDF(%PDF-)
SlZCRVJpMH被编码了两次的 PDF:JVBERi0… 的 Base64
H4sIgzip 压缩的数据
PCFET0NUWVBF、PCFkb2N0eXBl、PGh0bWwHTML 页面,通常是错误页或登录页
eyJJSON,常常是 {"error":… 这样的错误消息
XlhB热敏打印机用的 ZPL 面单(^XA)
iVBORw0KGgoPNG 图片

对于双重编码的字符串或 gzip 数据,工具会再显示一条提示,带有 再次解码 按钮,它会把输入替换为内层数据;返回 可以回到你粘贴的原始内容。对于损坏或无法识别的文件,提示会写着“这看起来不像 PDF”,并给出检测到的类型;扩展名保持 .pdf,你仍然可以下载这些字节,换个阅读器试试。

解码之前出现的错误另有原因:

  • 原始 JSON 中的转义,例如 \/(PHP 的 json_encode 会这样写斜杠)或行与行之间的字面 \n,会被自动去除。如果其他 \ 转义仍然触发 无效字符 \,请使用 修复 Base64,或者先解析 JSON 再复制值。
  • 无效字符 % 说明字符串经过了 URL 编码。+、/ 和 = 的转义(%2B、%2F、%3D)会被自动修正;其他情况请先用 URL 解码器 处理一遍。
  • 能识别为 PDF 却什么也不显示,通常是数据被截断了。文件头还在,所以检测能通过,但文件末尾存放交叉引用表的部分丢失了。其他常见原因见 Base64 常见错误。

在代码中将 Base64 解码为 PDF

Python,从 JSON 响应中读取:

import base64, json

with open("response.json") as f:
    b64 = json.load(f)["document"]

if b64.startswith("data:"):
    b64 = b64.split(",", 1)[1]

pdf = base64.b64decode(b64)
if not pdf.startswith(b"%PDF-"):
    raise ValueError(f"not a PDF, starts with {pdf[:16]!r}")

with open("document.pdf", "wb") as f:
    f.write(pdf)

b64decode 会悄悄丢弃标准字母表以外的字符,所以含 - 和 _ 的 URL 安全字符串会解码成乱码,而且不报错。这类字符串请使用 base64.urlsafe_b64decode。Node.js 一次调用就能同时接受两种字母表:

import { readFile, writeFile } from "node:fs/promises";

const { document } = JSON.parse(await readFile("response.json", "utf8"));
const pdf = Buffer.from(document.replace(/^data:[^,]*,/, ""), "base64");

if (pdf.toString("latin1", 0, 5) !== "%PDF-") throw new Error("not a PDF");
await writeFile("document.pdf", pdf);

在 shell 中,jq -r 很关键:不加 -r,值会带着引号,base64 -d 会报错“invalid input”并停止。

jq -r '.document' response.json | base64 -d > document.pdf

键名 document 只是占位符,换成你的 API 实际使用的字段名即可。更多写法见 Python 中的 Base64、Node.js 中的 Base64 和 Bash 中的 Base64。

常见问题

怎么把 Base64 字符串转换成 PDF 文件?

把字符串粘贴到上方的输入框,确认预览无误后点击 下载文件。如果来自 JSON,只复制引号之间的值;data:application/pdf;base64, 前缀和换行可以保留。

为什么解码出来的 PDF 打不开或是一片空白?

几乎都是因为字符串被截断了:日志的单行长度限制、数据库字段长度或复制粘贴的上限都会切掉文件末尾。完整的 PDF 以 %%EOF 结尾;可以把解码后的大小和发送方给出的大小对比一下。

能查看有密码保护的 PDF 吗?

可以。信息列表会显示 已加密:是,Chrome 和 Firefox 的内置查看器会在预览中要求输入密码。下载的文件保持原样,用同一个密码即可打开。

为什么工具提示我的 Base64 不是 PDF?

解码后的字节不是以 %PDF- 开头。最常见的原因是 API 返回的是错误页面或 JSON 消息,而不是文档;警告会说明检测到了什么,并提供按该扩展名保存的选项,方便你查看内容。

在这里解码机密 PDF 安全吗?

PDF 在你的浏览器内解码和显示,页面的内容安全策略会阻止它发出除 Cloudflare 的浏览量统计以外的网络请求。页面加载完成后,你甚至可以断网继续使用。