5

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

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

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

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 文件合并为一个而不显着增加其大小并且仍然能够在合并时向页面添加其他内容?
4

3 回答 3

11

首先:使用PdfWriter/PdfImportedPage不是一个好主意。你扔掉了所有的交互功能!作为 iText 的作者,尽管我写了两本关于此的书,尽管我说服我的出版商为免费: http: //www.manning.com/lowagie2/samplechapter6.pdf

我的文笔真的那么差吗?PdfWriter还是人们继续使用/合并文档的另一个原因PdfImportedPage

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

  1. 是的。下载示例章节并在 PDF 文件中搜索PageStamp.
  2. 仅当您分两次创建 PDF 时。例如:首先创建巨大的PDF,然后通过传递它来减小大小PdfCopy;或首先使用 PdfCopy 创建合并的 PDF,然后使用PdfStamper.
于 2012-10-05T07:00:10.537 回答
7

使用 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);                  
        }
}
于 2012-10-08T12:41:02.440 回答
0

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

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

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

于 2013-11-01T22:55:41.750 回答