iText7 C#重复合并同一PDF文件却未按预期增大文件体积问题
问题
我有一个基于.NET 6.0的Windows Forms应用,已通过NuGet包管理器引入iText7。UI包含:选择单个PDF文件的打开文件对话框、输入重复次数的文本框、生成输出PDF的按钮。点击按钮需生成将原PDF内容重复指定次数的单个输出PDF。
现有代码可正常生成内容符合要求的PDF,但存在问题:原PDF为2MB时,重复10次后输出文件仅约2.7MB,即使设置了无压缩级别也是如此,所有类型内容(文本、图片等)均出现此情况。我希望输出文件体积按重复次数倍增,想了解如何覆盖iText7的这种优化行为。
现有代码如下:
GenerateContentDuplicatedPDF(string existingFileFullPath, string outputFileFullPath, int iNumberOfMerges) { using (var memoryStream = new MemoryStream()) { using (PdfReader pdfReader = new PdfReader(existingFileFullPath)) { using (PdfDocument SourceDocument1 = new PdfDocument(pdfReader)) { WriterProperties properties = new WriterProperties().SetCompressionLevel(CompressionConstants.NO_COMPRESSION); using (PdfWriter pdfWriter = new PdfWriter(memoryStream, properties)) { using (PdfDocument pdfDocument = new PdfDocument(pdfWriter)) { PdfMerger merge = new PdfMerger(pdfDocument); for (int i = 0; i < iNumberOfMerges; i++) { merge.Merge(SourceDocument1, 1, SourceDocument1.GetNumberOfPages()); } merge.Close(); SourceDocument1.Close(); byte[] result = memoryStream.ToArray(); File.WriteAllBytes(outputFileFullPath, result); } } } } } }
解决方案
iText7的PdfMerger默认会复用源PDF中的资源(比如字体、图片、表单对象等),相同资源仅写入输出PDF一次,后续页面仅引用这些资源,这就是重复多次后文件体积未倍增的原因。要实现体积随重复次数倍增,需每次合并时创建新的源PDF读取实例,强制iText7重复写入所有资源。
修改后的代码如下:
GenerateContentDuplicatedPDF(string existingFileFullPath, string outputFileFullPath, int iNumberOfMerges) { using (var memoryStream = new MemoryStream()) { WriterProperties properties = new WriterProperties().SetCompressionLevel(CompressionConstants.NO_COMPRESSION); using (PdfWriter pdfWriter = new PdfWriter(memoryStream, properties)) { using (PdfDocument pdfDocument = new PdfDocument(pdfWriter)) { PdfMerger merge = new PdfMerger(pdfDocument); for (int i = 0; i < iNumberOfMerges; i++) { // 每次循环重新创建PdfReader和PdfDocument实例,避免资源复用 using (PdfReader pdfReader = new PdfReader(existingFileFullPath)) { using (PdfDocument sourceDoc = new PdfDocument(pdfReader)) { merge.Merge(sourceDoc, 1, sourceDoc.GetNumberOfPages()); } } } merge.Close(); byte[] result = memoryStream.ToArray(); File.WriteAllBytes(outputFileFullPath, result); } } } }
关键修改说明
- 将
PdfReader和源PdfDocument的创建逻辑移至循环内部,每次合并都重新读取原PDF,生成独立的文档实例。 - 这种方式会让iText7无法复用之前写入的资源,每次合并都会完整写入原PDF的所有资源,从而实现体积随重复次数倍增的效果。
- 保留
SetCompressionLevel(CompressionConstants.NO_COMPRESSION)设置,确保无额外压缩影响体积计算。
内容的提问来源于stack exchange,提问作者user20576686
相关产品推荐
相关产品推荐

