如何在内存中将ZipArchive中的多个PDF合并为单个PDF
内存中直接读取Zip内PDF并合并(替代过时iTextSharp方案)
要实现内存中直接读取Zip归档里的PDF文件并合并成单个PDF,无需先将文件写入磁盘,你可以使用iText 7(iTextSharp的官方替代版本)来完成,全程内存操作能大幅提升效率。
第一步:安装依赖
首先需要安装NuGet包iText 7 Core(包名:itext7),可以通过NuGet包管理器搜索安装,或者使用Package Manager命令:
Install-Package itext7
完整实现代码
using System.IO; using System.IO.Compression; using iText.Kernel.Pdf; using iText.Merge; public static void ProcessZipAndMergePdfs(string zipFile, string outputPdfPath) { try { using (var finalStream = new MemoryStream()) { // 初始化目标PDF文档 using (var writer = new PdfWriter(finalStream)) using (var targetDoc = new PdfDocument(writer)) { var merger = new PdfMerger(targetDoc); using (ZipArchive archive = ZipFile.OpenRead(zipFile)) { foreach (ZipArchiveEntry entry in archive.Entries) { // 过滤非PDF文件和空目录条目 if (!entry.FullName.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase) || entry.Length == 0) continue; // 直接从Zip条目打开流,无需写入磁盘 using (var entryStream = entry.Open()) using (var sourceDoc = new PdfDocument(new PdfReader(entryStream))) { // 合并当前PDF的所有页面到目标文档 merger.Merge(sourceDoc, 1, sourceDoc.GetNumberOfPages()); } } } // 将合并后的内存流写入输出文件 finalStream.Position = 0; using (var fileStream = new FileStream(outputPdfPath, FileMode.Create, FileAccess.Write)) { finalStream.CopyTo(fileStream); } } } } catch (Exception e) { // 添加日志记录逻辑,示例: // Console.WriteLine($"合并失败:{e.Message}"); } }
关键细节说明
- 避免磁盘I/O:通过
ZipArchiveEntry.Open()直接获取PDF文件的流,全程在内存中处理,没有中间文件写入操作 - 过滤无效条目:跳过Zip中的目录项(长度为0的条目)和非PDF文件,防止读取错误
- 资源自动释放:所有流、文档对象都用
using语句包裹,确保资源及时释放,避免内存泄漏 - 高效合并:iText 7的
PdfMerger是专门为PDF合并设计的API,相比旧版iTextSharp的PdfCopyFields性能更优,功能更完善
内容的提问来源于stack exchange,提问作者FatherOfDiwaffe
相关产品推荐
相关产品推荐

