编辑iTextSharp PdfSmartCopy类的DirectContent

Mas*_*ius 5 c# java merge itext itextsharp

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

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

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();
Run Code Online (Sandbox Code Playgroud)

当我对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();                            
                    }
                }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

现在我有几个问题:

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

Bru*_*gie 10

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

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

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

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


Mas*_*ius 6

使用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);                  
        }
}
Run Code Online (Sandbox Code Playgroud)