编辑iTextSharp PdfSmartCopy类的DirectContent

在我的工作中,有时我必须合并几个到几百个pdf文件。 我一直在使用WriterImportedPages类。 但是当我将所有文件合并为一个文件时,文件大小变得巨大,所有合并文件大小的总和,因为字体附加到每个页面,而不是重复使用(字体嵌入到每个页面,而不是整个文档)。

不久前我发现了PdfSmartCopy类,它重用了嵌入的字体和图像。 在这里,问题就出现了。很多时候,在将文件合并到一起之前,我必须向它们添加其他内容(图像,文本)。 为此,我通常使用Writer对象的PdfContentByte

 Document doc = new Document(); PdfWriter writer = PdfWriter.GetInstance(doc, new FileStream("C:\test.pdf", FileMode.Create)); PdfContentByte cb = writer.DirectContent; cb.Rectangle(100, 100, 100, 100); cb.SetColorStroke(BaseColor.RED); cb.SetColorFill(BaseColor.RED); cb.FillStroke(); 

当我使用PdfSmartCopy对象执行类似PdfSmartCopy ,会合并页面,但不会添加其他内容。 使用PdfSmartCopy测试的完整代码:

 using (Document doc = new Document()) { using (PdfSmartCopy copy = new PdfSmartCopy(doc, new FileStream(Path.GetDirectoryName(pdfPath[0]) + "\\testas.pdf", FileMode.Create))) { doc.Open(); PdfContentByte cb = copy.DirectContent; for (int i = 0; i < pdfPath.Length; i++) { PdfReader reader = new PdfReader(pdfPath[i]); for (int ii = 0; ii < reader.NumberOfPages; ii++) { PdfImportedPage import = copy.GetImportedPage(reader, ii + 1); copy.AddPage(import); cb.Rectangle(100, 100, 100, 100); cb.SetColorStroke(BaseColor.RED); cb.SetColorFill(BaseColor.RED); cb.FillStroke(); doc.NewPage();// net nesessary line //ColumnText col = new ColumnText(cb); //col.SetSimpleColumn(100,100,500,500); //col.AddText(new Chunk("wdasdasd", PdfFontManager.GetFont(@"C:\Windows\Fonts\arial.ttf", 20))); //col.Go(); } } } } } 

现在我有几个问题:

  1. 是否可以编辑PdfSmartCopy对象的DirectContent?
  2. 如果没有,是否有另一种方法将多个pdf文件合并为一个不显着增加其大小的文件,并且仍然能够在合并时向页面添加其他内容?

首先这个:使用PdfWriter / PdfImportedPage不是一个好主意。 你抛弃所有互动function! 作为iText的作者,尽管我写了两本关于这个的书,并且尽管我说服我的出版商提供了一个最重要的章节,但是这么多人犯了同样的错误是非常令人沮丧的。免费: http : //www.manning.com/lowagie2/samplechapter6.pdf

我的写作真的那么糟糕吗? 或者还有另一个原因让人们继续使用PdfWriter / PdfImportedPage合并文档?

至于您的具体问题,以下是答案:

  1. 是。 下载示例章节并在PDF文件中搜索PageStamp
  2. 仅在两次通过中创建PDF时。 例如:首先创建巨大的PDF,然后通过PdfCopy传递它来缩小尺寸; 或者首先使用PdfCopy创建合并的PDF,然后使用PdfStamper在第二遍中添加额外的内容。

使用Bruno Lowagie回答后的代码

 for (int i = 0; i < pdfPath.Length; i++) { PdfReader reader = new PdfReader(pdfPath[i]); PdfImportedPage page; PdfSmartCopy.PageStamp stamp; for (int ii = 0; ii < reader.NumberOfPages; ii++) { page = copy.GetImportedPage(reader, ii + 1); stamp = copy.CreatePageStamp(page); PdfContentByte cb = stamp.GetOverContent(); cb.Rectangle(100, 100, 100, 100); cb.SetColorStroke(BaseColor.RED); cb.SetColorFill(BaseColor.RED); cb.FillStroke(); stamp.AlterContents(); // don't forget to add this line copy.AddPage(page); } } 

2.仅在两次通过中创建PDF。 例如:首先创建巨大的PDF,然后通过PdfCopy传递它来缩小尺寸; 或者首先使用PdfCopy创建合并的PDF,然后使用PdfStamper在第二遍中添加额外的内容。

使用第二遍PdfStamper要困难得多。 当您处理大量数据时,创建1个pdf标记会更容易,然后追加。

PdfCopyFields在这方面运作良好。 现在它在5.4.4.0版本中不起作用,这就是我在这里的原因。