PDF 版式稳定、便于分发,代价是正文被锁在页面结构里,想改一个字往往要从头排版。Markdown 是另一条路:纯文本、层级清楚,能直接进 Git 仓库和知识库,也方便交给大语言模型做摘要或问答。把 PDF 转成 Markdown,本质上就是让内容重新变回可编辑的结构化文本。
Spire.PDF for JavaScript 基于 WebAssembly,在浏览器里就能完成 PDF 的加载、转换与保存,输入输出交给虚拟文件系统(VFS)管理,全过程不需要后端服务。转换有两个入口:PdfDocument.SaveToFile 把输出格式指定为 FileFormat.Markdown 即可一步到位;PdfToMarkdownConverter 则提供了 MarkdownOptions,可以按需要调整转换时的细节。
本文介绍两个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.PDF for JavaScript。以下示例默认已安装 Spire.PDF 并完成 WebAssembly 模块初始化。
将 PDF 转换为 Markdown
PdfDocument.SaveToFile 同样可以输出 Markdown:把 fileFormat 指定为 FileFormat.Markdown,PDF 里的标题、段落与列表便会按原有层级整理成 Markdown 文本。文档中的图片默认也会一并提取出来。
function App() {
const convertPdfToMarkdown = async () => {
// 获取 Spire.PDF WASM 模块
const pdfModule = window.wasmModule?.spirepdf;
// 检查模块是否就绪
if (!pdfModule) {
alert('Spire.PDF is not ready yet');
return;
}
// 将待转换的 PDF 文件载入虚拟文件系统
const inputFileName = '花卉.pdf';
await window.spire.FetchFileToVFS(inputFileName, "", `${process.env.PUBLIC_URL}/data/`);
// 载入字体到虚拟文件系统(WebAssembly 环境没有系统字体)
await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
// 创建 PdfDocument 对象并加载 PDF 文档
let doc = new pdfModule.PdfDocument();
doc.LoadFromFile(inputFileName);
// 定义输出文件名并转换为 Markdown 格式
const outputFileName = '转换结果.md';
doc.SaveToFile({ fileName: outputFileName, fileFormat: pdfModule.FileFormat.Markdown });
doc.Close();
// 从 VFS 读取生成的文件,触发下载
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'text/markdown' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>Convert PDF to Markdown</h1>
<button onClick={convertPdfToMarkdown}>
Convert
</button>
</div>
);
}
export default App;
转换得到的 Markdown 文件

跳过图片只转换文字
只要文字的话,用 PdfToMarkdownConverter 更直接。它默认会把文档里的图片一并提取,把 MarkdownOptions.IgnoreImage 设为 true 后,输出就只剩纯文本。
function App() {
const convertPdfToTextOnlyMarkdown = async () => {
// 获取 Spire.PDF WASM 模块
const pdfModule = window.wasmModule?.spirepdf;
// 检查模块是否就绪
if (!pdfModule) {
alert('Spire.PDF is not ready yet');
return;
}
// 将待转换的 PDF 文件载入虚拟文件系统
const inputFileName = '花卉.pdf';
await window.spire.FetchFileToVFS(inputFileName, "", `${process.env.PUBLIC_URL}/data/`);
// 载入字体到虚拟文件系统(WebAssembly 环境没有系统字体)
await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
// 创建转换器,并设置忽略图片
const converter = new pdfModule.PdfToMarkdownConverter(inputFileName);
converter.MarkdownOptions.IgnoreImage = true;
// 定义输出文件名并执行转换
const outputFileName = '纯文本转换结果.md';
converter.ConvertToMarkdown(outputFileName);
converter.Dispose();
// 从 VFS 读取生成的文件,触发下载
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'text/markdown' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>Convert PDF to Text-only Markdown</h1>
<button onClick={convertPdfToTextOnlyMarkdown}>
Convert
</button>
</div>
);
}
export default App;
只保留文字、跳过图片的转换结果

常见问题
转换后标题和列表的层级是怎么来的
原因:PDF 里并不存在“标题”“列表”这类语义标记,只有一个个带坐标的文本片段。转换器需要根据字号、字重、缩进和行间距等版式线索,反推出原本的结构。
解决:Spire.PDF 会按上述线索判断层级并输出对应的 Markdown 标记。如果源文档的版式比较随意(例如用空格而不是真正的字号差异来区分标题),反推结果可能不理想,此时建议先调整源 PDF 的版式,或对转换结果做一次人工校对:
// 转换后读取 Markdown 文本进行检查
let doc = new pdfModule.PdfDocument();
doc.LoadFromFile(inputFileName);
doc.SaveToFile({ fileName: outputFileName, fileFormat: pdfModule.FileFormat.Markdown });
doc.Close();
设置了 IgnoreImage 为什么图片不见了
原因:MarkdownOptions.IgnoreImage 的含义就是“转换时跳过图片”,设为 true 后,图片既不会被提取成独立文件,也不会在 Markdown 里留下图片引用。
解决:如果既要文字又要图片,把这个属性去掉或设为 false 即可,转换器会照常处理图片:
// 保留图片(默认行为)
const converter = new pdfModule.PdfToMarkdownConverter(inputFileName);
converter.MarkdownOptions.IgnoreImage = false;
converter.ConvertToMarkdown(outputFileName);
converter.Dispose();
扫描件转换出来是空白的
原因:扫描件是整页图片,没有文字层,转换器从中提取不到任何文本,所以输出几乎为空。
解决:这类 PDF 需要先做 OCR,把图片识别成文字层,再交给 Spire.PDF 转换。判断方法很简单,用阅读器打开试着选中文字,如果选不中,就说明是扫描件:
// 从 VFS 读回结果,确认是否真的产生了文本
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
console.log('输出大小:', fileArray.length, 'bytes');
获取免费许可证
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。









