PDF 版式固定、跨端一致,是合同、报告、图册等文档分发的首选格式,但包含大量高分辨率图片或内嵌字体的 PDF 体积往往很大,既占用存储空间,也让邮件发送、网页上传与下载变得缓慢。若能在浏览器端直接给文档“瘦身”,在尽量保持可读性的前提下显著减小体积,就能明显改善分发与加载体验,而不必把文件上传到服务器再下载处理。
Spire.PDF for JavaScript 基于 WebAssembly 在浏览器端直接完成 PDF 的加载、压缩与保存,通过虚拟文件系统(VFS)管理输入输出文件,无需后端服务支持。它提供专用的 PdfCompressor 压缩器,其 Options 可以从三个维度分别控制压缩策略:一是用 ImageCompressionOptions 对文档里的图片做缩放与重压缩,二是用 TextCompressionOptions 压缩字体数据甚至取消字体内嵌,三是用 CompressContents 重新压缩页面的内容流。三者在一次压缩中可以自由组合,兼顾画质与体积。
本文先从三个维度介绍 PdfCompressor 的压缩方式,再给出把它们组合起来的完整可运行示例:
有关安装和项目配置,请参考 React 项目中集成 Spire.PDF for JavaScript。以下示例默认已安装 Spire.PDF 并完成 WebAssembly 模块初始化。
压缩 PDF 中的图片
页面中的高分辨率位图通常是 PDF 体积的主要来源。Options.ImageCompressionOptions 用三个属性共同控制图片的缩放与重编码:
| 选项 | 作用 | 效果与取舍 |
|---|---|---|
ResizeImages |
等比缩小图片后再重新编码 | 显著减小体积,适合分辨率过高的大图 |
CompressImage |
对图片做有损压缩 | 以少量画质损失换取体积下降 |
ImageQuality |
控制重编码的画质档位 | High 画质更高、体积略大;Low 体积更小、画质可能变模糊 |
对以图片为主的文档,通常先开启 ResizeImages 与 CompressImage,再按对画质的容忍度选择合适的 ImageQuality 档位:
// 压缩文档中的图片:缩放图片、重新压缩并降低画质
compressor.Options.ImageCompressionOptions.ResizeImages = true;
compressor.Options.ImageCompressionOptions.CompressImage = true;
compressor.Options.ImageCompressionOptions.ImageQuality = pdfModule.ImageQuality.Low;
压缩 PDF 中的字体并取消字体嵌入
PDF 会把正文用到的字体作为子集嵌入文件内,多个字体、多种字重叠加起来也占不少体积。Options.TextCompressionOptions 提供两种处理字体的方式:
| 选项 | 作用 | 效果与取舍 |
|---|---|---|
CompressFonts |
压缩内嵌字体数据,保留字体 | 显示不变,体积更小 |
UnembedFonts |
移除内嵌字体,改用系统字体渲染 | 体积更小;阅读端缺对应字体时字形可能被替换 |
UnembedFonts 能压得更小但有显示风险,是否开启需结合文档去向判断:
// 压缩字体数据;UnembedFonts 进一步取消字体内嵌
compressor.Options.TextCompressionOptions.CompressFonts = true;
compressor.Options.TextCompressionOptions.UnembedFonts = true;
压缩 PDF 的内容流
PDF 页面中的文字与矢量绘制指令以“内容流(Content Stream)”的形式存储,生成时虽通常会压缩,但经过多次编辑或不同工具处理后仍可能存在冗余。Options.CompressContents 会重新压缩文档的内容流,开启后对文字较多、版式复杂的文档也能挤出一部分空间:
// 重新压缩文档的内容流
compressor.Options.CompressContents = true;
综合三种方式压缩 PDF 文档
把上面三种方式组合起来即可得到兼顾效果与速度的完整压缩流程:加载 PDF 后一次开启图片、字体与内容流三类压缩,再调用 CompressToFile 把结果写入新文件。下图示例对一份同时包含高分辨率图片与文字的 PDF 同时启用了 ResizeImages、CompressImage(High 画质)、CompressFonts、UnembedFonts 与 CompressContents,得到体积明显减小的新文档:
function App() {
const compressPdfDocument = async () => {
// 获取 Spire.PDF WASM 模块
const pdfModule = window.wasmModule?.spirepdf;
// 检查模块是否就绪
if (!pdfModule) {
alert('Spire.PDF is not ready yet');
return;
}
// 将待压缩的 PDF 文件载入 VFS
const inputFileName = '图片文档.pdf';
await window.spire.FetchFileToVFS(inputFileName, "", `${process.env.PUBLIC_URL}/data/`);
// 创建 PdfCompressor 对象并指定要压缩的 PDF 文件
let compressor = new pdfModule.PdfCompressor({ filePath: inputFileName });
// 1. 图片压缩:缩放图片并重新压缩,使用较高画质
compressor.Options.ImageCompressionOptions.ResizeImages = true;
compressor.Options.ImageCompressionOptions.CompressImage = true;
compressor.Options.ImageCompressionOptions.ImageQuality = pdfModule.ImageQuality.High;
// 2. 字体压缩:压缩字体数据并取消字体内嵌
compressor.Options.TextCompressionOptions.CompressFonts = true;
compressor.Options.TextCompressionOptions.UnembedFonts = true;
// 3. 内容压缩:重新压缩文档的内容流
compressor.Options.CompressContents = true;
// 定义输出文件名并压缩到该文件
const outputFileName = '压缩后的文档.pdf';
compressor.CompressToFile(outputFileName);
// 从 VFS 读取生成的文件,触发下载
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'application/pdf' });
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>Compress PDF Document</h1>
<button onClick={compressPdfDocument}>
Generate
</button>
</div>
);
}
export default App;
综合三种方式压缩后的 PDF 文档

常见问题
PDF 中图片不多,为什么压缩后体积还是很大
原因:文档体积未必都来自图片。当页面以文字为主时,体积更多来自内嵌字体与页面内容流,只开启图片压缩自然收效甚微。
解决:把压缩维度补齐——用 TextCompressionOptions 压缩字体数据(必要时 UnembedFonts 取消嵌入),用 CompressContents 重新压缩内容流,与图片压缩一起组合使用,才能在文字类文档上也明显减小体积。
取消字体嵌入后,文字会不会显示异常
原因:UnembedFonts 会从 PDF 中去掉字体程序,阅读端渲染时改用系统里已安装的字体;若目标环境缺少该字体,就可能出现字形替换或间距变化。
解决:文档若是分发给字体环境不确定的用户,建议保留内嵌,仅用 CompressFonts 压缩字体数据;只有当你能确认阅读端具备对应字体时,再开启 UnembedFonts:
// 保留内嵌但压缩字体数据,避免去嵌入带来的显示风险
compressor.Options.TextCompressionOptions.UnembedFonts = false;
compressor.Options.TextCompressionOptions.CompressFonts = true;
图片画质档位与各压缩方式如何取舍
原因:ImageQuality 只影响图片重编码的画质与体积;文档构成不同,对体积贡献最大的部分也不同,单一维度难以达到理想的压缩率。
解决:图片为主时,先开 ResizeImages 与 CompressImage 并在 High/Low 之间选档;文字为主时,重点用字体压缩与内容压缩。需要保留字体内嵌的文档关掉 UnembedFonts 即可,不影响其余压缩项:
// 图片为主时选较低的画质档位以换更小体积
compressor.Options.ImageCompressionOptions.ImageQuality = pdfModule.ImageQuality.Low;
获取免费许可证
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。







