node.js 不能直接用 fs.readfile 读取 pdf 文本,因 pdf 是二进制格式,需用 pdf-parse 等专用库解析;pdf-parse 轻量、支持中文,但要求 pdf 含文本层,扫描件或加密 pdf 无法提取。

Node.js 读取 PDF 文件为什么不能直接用 fs.readFile
PDF 不是纯文本格式,fs.readFile 读出来的是一串二进制或乱码字符串,直接 toString() 拿不到可读文字。必须用专门解析 PDF 结构的库,比如 pdf-parse 或 pdf-lib(后者侧重编辑,不推荐用于提取)。pdf-parse 轻量、无原生依赖、支持中文(需确保 PDF 内嵌字体或使用 Unicode 编码),是最常用的选择。
安装 pdf-parse 并处理常见报错
在 VSCode 终端中执行:
npm install pdf-parse注意:不要装错成
pdfparse(旧版、已弃用)或 pdfjs-dist(体积大、需额外配置 worker)。如果遇到 Error: Cannot find module 'pdfjs-dist',说明你误装了依赖不全的版本——pdf-parse 内部已封装好所需 PDF.js 模块,无需手动引入。
- Windows 下若报
node-gyp错误,说明你装了带 C++ 扩展的 PDF 库(如pdfjs-dist),换回pdf-parse即可 - 路径必须是绝对路径或相对于当前工作目录的正确路径;
./data/sample.pdf在调试时容易因process.cwd()变化而失败,建议用path.resolve(__dirname, 'data', 'sample.pdf') - PDF 若为扫描件(图片型),
pdf-parse无法提取文字——它只处理可选中文本流,不带 OCR 功能
VSCode 调试时读取本地 PDF 的最小可行代码
新建 parse-pdf.js,确保文件与 PDF 在同一项目下:
const fs = require('fs');
const path = require('path');
const pdfParse = require('pdf-parse');
const pdfPath = path.resolve(__dirname, 'invoice.pdf'); // ← 必须用 path.resolve
fs.readFile(pdfPath, (err, data) => {
if (err) throw err;
pdfParse(data).then(result => {
console.log(result.text.substring(0, 200)); // 前 200 字符预览
}).catch(err => {
console.error('PDF 解析失败:', err.message); // 常见:损坏文件、加密 PDF、无文本层
});
});
-
pdfParse()返回 Promise,别用同步写法(如pdfParse.sync已移除) - 加密 PDF 会直接 reject,错误信息通常是
Invalid password或PDF is encrypted,需提前解密或跳过 - 结果对象中的
text是字符串,pages是数组,含每页文本和元数据,按需取用
中文乱码或空内容的三个检查点
不是所有 PDF 都能顺利提取中文,关键看 PDF 生成方式:
- 导出 PDF 时是否勾选“保留文本可选择性”(如 Word / WPS / Chrome 打印 → 更多设置 → 勾选“背景图形”不影响,但“仅限图像”会丢文本)
- PDF 是否使用 CID 字体(常见于某些 LaTeX 或日文排版),
pdf-parse对部分 CID 支持有限,可尝试用pdfjs-dist+ 自定义worker,但复杂度陡增 - Node 版本建议 ≥16.14,低版本可能触发
TextDecoder编码异常,导致中文变
真正卡住的地方往往不是代码,而是 PDF 本身有没有文本层——打开 Adobe Reader 或 Edge,试试能否用鼠标划选文字。不能选,就不是解析工具的问题。











