如何在C#中使用iTextSharp合并带图层PDF且不丢失图层
在C#中用iTextSharp合并带图层PDF且不丢失图层的解决方案
我来帮你解决这个合并PDF丢失图层的问题——这是iTextSharp里常见的小坑,主要是默认的PdfCopy不会自动处理PDF的**可选内容组(OCG,也就是你说的图层)**信息。下面给你两种靠谱的解决方案:
方法一:用PdfSmartCopy替代PdfCopy(推荐)
PdfSmartCopy是PdfCopy的子类,它不仅能智能复用PDF中的重复资源,还会自动处理图层相关的配置,代码改动很小:
// step 1: 创建文档对象 Document document = new Document(); // step 2: 替换为PdfSmartCopy,它会自动处理图层 PdfSmartCopy writer = new PdfSmartCopy(document, new FileStream(outPutFilePath, FileMode.Create)); if(writer == null) { return; } // step 3: 打开文档 document.Open(); foreach(string fileName in filesPath) { // 创建源PDF的阅读器 PdfReader reader = new PdfReader(fileName); // 逐个复制页面到目标文档 for (int pageNum = 1; pageNum <= reader.NumberOfPages; pageNum++) { writer.AddPage(writer.GetImportedPage(reader, pageNum)); } // 复制表单及图层相关的附加信息 writer.CopyAcroForm(reader); // 记得关闭阅读器释放资源 reader.Close(); } // 收尾工作:关闭文档和写入器 document.Close(); writer.Close();
方法二:手动配置PdfCopy保留图层
如果你因为某些原因必须用PdfCopy,可以手动复制每个源PDF的图层字典到目标文档中,确保图层信息不丢失:
Document document = new Document(); PdfCopy writer = new PdfCopy(document, new FileStream(outPutFilePath, FileMode.Create)); if(writer == null) { return; } document.Open(); foreach(string fileName in filesPath) { PdfReader reader = new PdfReader(fileName); // 手动复制源PDF的OCG(图层)字典到目标文档 PdfDictionary sourceOcProps = reader.Catalog.GetAsDict(PdfName.OCPROPERTIES); if (sourceOcProps != null) { PdfDictionary destOcProps = writer.Catalog.GetAsDict(PdfName.OCPROPERTIES); // 如果目标文档还没有OCG配置,先创建一个空字典 if (destOcProps == null) { destOcProps = new PdfDictionary(); writer.Catalog.Put(PdfName.OCPROPERTIES, destOcProps); } // 复制图层列表 PdfArray sourceOcgs = sourceOcProps.GetAsArray(PdfName.OCGS); if (sourceOcgs != null) { PdfArray destOcgs = destOcProps.GetAsArray(PdfName.OCGS); if (destOcgs == null) { destOcgs = new PdfArray(); destOcProps.Put(PdfName.OCGS, destOcgs); } foreach (PdfObject ocg in sourceOcgs) { destOcgs.Add(writer.GetImportedObject(ocg)); } } // 复制图层的显示配置(比如默认状态) PdfDictionary displayConfig = sourceOcProps.GetAsDict(PdfName.D); if (displayConfig != null) { destOcProps.Put(PdfName.D, writer.GetImportedObject(displayConfig)); } } // 复制所有页面 for (int pageNum = 1; pageNum <= reader.NumberOfPages; pageNum++) { writer.AddPage(writer.GetImportedPage(reader, pageNum)); } reader.Close(); } document.Close(); writer.Close();
额外说明
- 方法一的
PdfSmartCopy已经封装了大部分资源和图层处理逻辑,代码更简洁,优先推荐使用。 - 上述代码适用于iTextSharp 5.x系列版本,如果你用的是更新的iText 7,API会有差异,但核心思路都是保留OCG字典信息。
内容的提问来源于stack exchange,提问作者user3524135
相关产品推荐
相关产品推荐

