C# 编辑iTextSharp PdfSmartCopy类的DirectContent

C# 编辑iTextSharp PdfSmartCopy类的DirectContent,c#,java,merge,itextsharp,itext,C#,Java,Merge,Itextsharp,Itext,在我的工作中,有时我不得不合并几个到几百个pdf文件。我一直在使用Writer和ImportedPages类。但当我将所有文件合并为一个文件时,文件大小变得巨大,是所有合并文件大小的总和,因为字体附加到每个页面,而不是重复使用(字体嵌入到每个页面,而不是整个文档) 不久前,我发现了PdfSmartCopy类,它重用嵌入的字体和图像。现在问题来了。通常,在合并文件之前,我必须向它们添加额外的内容(图像、文本)。为此,我通常使用Writer对象中的PdfContentByte Document do

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

不久前,我发现了
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
测试的完整代码:

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();                            
                    }
                }
            }
        }
    }
使用(Document doc=new Document())
{
使用(PdfSmartCopy copy=newpdfsmartcopy(doc,newfilestream(Path.GetDirectoryName(pdfPath[0])+“\\testas.pdf”,FileMode.Create)))
{
doc.Open();
PdfContentByte cb=copy.DirectContent;
for(int i=0;i
现在我有几个问题:

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

  • 首先,使用
    PdfWriter
    /
    PdfImportedPage
    不是一个好主意。你扔掉了所有的互动功能!作为iText的作者,尽管我写了两本关于这一点的书,尽管我说服我的出版商免费提供其中一个最重要的章节,但这么多人都犯了同样的错误,这让人非常沮丧:

    我的写作真的那么糟糕吗?还是人们一直使用
    PdfWriter
    /
    PdfImportedPage
    合并文档的另一个原因

    关于你的具体问题,以下是答案:

  • 对。下载示例章节并在PDF文件中搜索
    PageStamp
  • 仅当您在两个过程中创建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);                  
            }
    }
    
    for(int i=0;i
    2。仅当您在两次过程中创建PDF时。例如:先创建巨大的PDF,然后通过PdfCopy传递来减小大小;或者首先使用PdfCopy创建合并的PDF,然后使用PdfStamper在第二次传递中添加额外的内容

    使用PdfStamper进行第二次传递要困难得多。当您处理大量数据时,创建1个pdf戳记然后追加要容易得多


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

    感谢您接受答案。我希望它能帮助人们找到通往自由篇章的道路;-)回答你的反问:因为我从来不需要交互式PDF功能。我正在做一些事情,比如合并、基于内容的爆破、双工和重新组织PDF报告。我用iTextSharp操作的PDF都没有可点击的URL或书签导航。绝大多数是PDF格式v1.3。我没有失去任何东西,如果我失去了,我就不需要失去什么。