使用iText7的PdfSplitter分割PDF时文件大小倍增的问题咨询
使用iText7分割PDF时文件大小异常膨胀的解决方法
问题描述
使用iText7中的PdfSplitter分割PDF文件时,单个分割文件的大小会翻倍;若分割为多个文件,总大小会呈倍数增长。将这些分割后的文件重新合并后,得到的文件大小为原文件的n倍。如何避免这种情况?
测试文件:TestFile
相关代码
private sealed class _PdfSplitter_95 : PdfSplitter { public _PdfSplitter_95(PdfDocument baseArg1, string pdfPath) : base(baseArg1) { this._pdfPath = pdfPath; } string _pdfPath; int currPageIndex = 0; protected override PdfWriter GetNextPdfWriter(PageRange documentPageRange) { currPageIndex++; return new PdfWriter(_pdfPath.Replace(".pdf", $"_{currPageIndex}.pdf")); } } static void Main(string[] args) { string inputFileName = @"TestSplit.pdf"; using (PdfDocument inputPdfDoc = new PdfDocument(new PdfReader(inputFileName))) { _PdfSplitter_95 _PdfSplitter_95 = new _PdfSplitter_95(inputPdfDoc, inputFileName); IList<PdfDocument> splitDocuments = _PdfSplitter_95.SplitByPageCount(1); foreach (PdfDocument doc in splitDocuments) { doc.Close(); } } }
解决方案
问题出在默认情况下,PdfSplitter会把原PDF里的所有共享资源(比如字体、图片、表单模板这些)完整复制到每个分割后的文件里,导致每个小文件都带着重复的资源,总大小自然就暴涨了。可以用这两种方法解决:
1. 开启资源重用优化(推荐)
创建PdfWriter的时候,给它加个WriterProperties配置,让iText自动复用原文档的共享资源,避免重复复制:
protected override PdfWriter GetNextPdfWriter(PageRange documentPageRange) { currPageIndex++; // 配置WriterProperties,开启资源重用 WriterProperties properties = new WriterProperties() .SetReuseXObject(true) .SetReuseFont(true); return new PdfWriter(_pdfPath.Replace(".pdf", $"_{currPageIndex}.pdf"), properties); }
SetReuseXObject(true):重用图片、表单这类XObject资源SetReuseFont(true):重用字体资源
开了这俩配置,分割后的文件只会保留当前页面需要的资源,共享资源不会重复存储。
2. 手动复制必要资源(复杂版)
如果需要更精细的控制,可以在分割时通过PdfSplitter的构造参数或自定义逻辑,只复制当前页面依赖的资源。不过这种方法复杂度较高,一般优先用第一种方案。
额外优化:压缩输出文件
还能在WriterProperties里开启压缩,进一步缩小文件体积:
WriterProperties properties = new WriterProperties() .SetReuseXObject(true) .SetReuseFont(true) .SetCompressionLevel(CompressionLevel.BEST_COMPRESSION);
验证效果
修改代码后重新分割,单个文件的大小会接近原文件单页的实际大小,总大小也会大幅降低;合并后的文件大小与原文件基本一致(或略大,因为合并时可能会有少量额外结构)。
内容的提问来源于stack exchange,提问作者zhusp
相关产品推荐
相关产品推荐

