如何在PDFBox拆分PDF时缩小拆分后文档的体积?
优化拆分后PDF体积的方案
你遇到的问题根源在于:默认拆分逻辑会让每个单页文档保留原PDF的全量共享资源(比如嵌入字体、全局元数据、未被当前页使用的图像等),这些冗余内容直接推高了单页文档的体积。下面是几个能在拆分过程中完成优化的具体方案,可直接结合你的代码修改:
1. 用PDFBox自带Optimizer自动优化
这是最省心的方式,Optimizer类会自动移除未使用资源、压缩内容流,大幅削减冗余:
先导入所需类:
import org.apache.pdfbox.pdmodel.optimize.Optimizer; import org.apache.pdfbox.pdmodel.optimize.OptimizationOptions;
然后修改保存循环部分:
//Saving each page as an individual document int i = 1; while(iterator.hasNext()) { PDDocument pd = iterator.next(); // 配置优化选项 OptimizationOptions options = new OptimizationOptions(); options.setRemoveUnusedResources(true); // 移除未使用的资源 options.setCompressContentStreams(true); // 压缩内容流 // 执行优化 Optimizer.optimize(pd, options); // 保存优化后的文档 pd.save("sample"+ i++ +".pdf"); // 必须关闭单页文档,避免内存泄漏 pd.close(); }
2. 手动清理冗余资源(精细控制)
如果自动优化不够彻底,可手动遍历单页资源,精准移除未被当前页使用的字体、图像:
导入所需类:
import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.font.PDFont; import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; import java.util.Set; import java.util.Map;
修改保存循环:
int i = 1; while(iterator.hasNext()) { PDDocument pd = iterator.next(); PDPage page = pd.getPage(0); PDResources resources = page.getResources(); // 清理未使用的字体 Set<String> usedFontNames = resources.getFontNames(); Map<String, PDFont> fonts = resources.getFonts(); fonts.entrySet().removeIf(entry -> !usedFontNames.contains(entry.getKey())); // 清理未使用的图像 Set<String> usedImageNames = resources.getXObjectNames(); Map<String, ?> xObjects = resources.getXObjects(); xObjects.entrySet().removeIf(entry -> !usedImageNames.contains(entry.getKey()) && entry.getValue() instanceof PDImageXObject); pd.save("sample"+ i++ +".pdf"); pd.close(); }
3. 针对图片密集型PDF的图像压缩
如果原PDF包含高分辨率图片,可通过调整图像参数进一步压缩:
导入所需类:
import org.apache.pdfbox.pdmodel.optimize.OptimizationOptions; import org.apache.pdfbox.pdmodel.optimize.ImageOptions;
修改保存循环:
int i = 1; while(iterator.hasNext()) { PDDocument pd = iterator.next(); OptimizationOptions options = new OptimizationOptions(); ImageOptions imageOptions = new ImageOptions(); imageOptions.setMaxResolution(72); // 限制图像分辨率为72DPI(适合屏幕显示) imageOptions.setJpegQuality(0.5f); // 设置JPEG压缩质量(0-1之间,0.5平衡体积与画质) options.setImageOptions(imageOptions); Optimizer.optimize(pd, options); pd.save("sample"+ i++ +".pdf"); pd.close(); }
额外注意事项
- 务必在保存后关闭每个单页的
PDDocument对象,否则会造成内存泄漏,甚至导致文件写入不完整。 - 如果原PDF是加密状态,需先确保文档已正确解密后再执行优化操作。
内容的提问来源于stack exchange,提问作者Sanket Gupta
相关产品推荐
相关产品推荐

