C# iTextSharp添加现有页面的新实例

C# iTextSharp添加现有页面的新实例,c#,pdf,pdf-generation,itextsharp,itext,C#,Pdf,Pdf Generation,Itextsharp,Itext,假设我有一个三页的PDF,三个都有acrofield。我需要能够生成一个新的PDF与第2页重复N次。第2页的每个新实例都需要修改字段名,使其与第2页的其他实例不同。以前解决过这个问题的人能提供一个语法示例吗?这个示例对此进行了解释。您应该将文档分为3个文档,每个文档有一页。使用renameFields()方法创建第二页的变体 连接表单的方式如下所示: Document document = new Document(); PdfCopy copy = new PdfCopy(document,

假设我有一个三页的PDF,三个都有acrofield。我需要能够生成一个新的PDF与第2页重复N次。第2页的每个新实例都需要修改字段名,使其与第2页的其他实例不同。以前解决过这个问题的人能提供一个语法示例吗?

这个示例对此进行了解释。您应该将文档分为3个文档,每个文档有一页。使用
renameFields()
方法创建第二页的变体

连接表单的方式如下所示:

Document document = new Document();
PdfCopy copy = new PdfCopy(document, new FileOutputStream(dest));
copy.setMergeFields();
document.open();
List<PdfReader> readers = new ArrayList<PdfReader>();
for (int i = 0; i < 3; ) {
    PdfReader reader = new PdfReader(renameFields(src, ++i));
    readers.add(reader);
    copy.addDocument(reader);
}
document.close();
for (PdfReader reader : readers) {
    reader.close();
}
Document Document=新文档();
PdfCopy copy=新PdfCopy(文档,新文件输出流(dest));
copy.setMergeFields();
document.open();
列表读取器=新的ArrayList();
对于(int i=0;i<3;){
PdfReader reader=新的PdfReader(重命名字段(src,++i));
readers.add(reader);
副本。添加文件(读卡器);
}
document.close();
for(PDF阅读器:阅读器){
reader.close();
}

一个常见的错误是忘记了
setMergeFields()
方法。

这可以工作,但会生成一个大文件。我猜这是因为第2页上的图像被复制了很多次,而不是被重复使用

public static void ExpandRepeatingPages(string sourcePdfPath, string outputPdfPath)
{
    /* figure out how many pages we are working with */
    var transientPdfReader = new PdfReader(sourcePdfPath);
    var numberOfPages = transientPdfReader.NumberOfPages;
    transientPdfReader.Close();

    var outputFileStream = new FileStream(outputPdfPath, FileMode.Create);
    var pdfCopyFields = new PdfCopyFields(outputFileStream);

    foreach (var pageNumber in Enumerable.Range(1, numberOfPages))
    {
        var pdfBytes = ExtractPageToBytes(sourcePdfPath, pageNumber);
        var pdfReader = new PdfReader(pdfBytes);
        pdfCopyFields.AddDocument(pdfReader);
        pdfReader.Close();

        if (pageNumber == 2)
        {
            foreach (var extraPageNumber in Enumerable.Range(2, 200))
            {
                var extraPagePdfBytes = RenamePageFields(pdfBytes, extraPageNumber);
                pdfReader = new PdfReader(extraPagePdfBytes);
                pdfCopyFields.AddDocument(pdfReader);
                pdfReader.Close();
            }
        }
    }

    pdfCopyFields.Close();
}

public static byte[] ExtractPageToBytes(string sourcePdfPath, int pageNumber)
{
    using (var memoryStream = new MemoryStream())
    {
        var pageNumbers = new System.Collections.ArrayList { pageNumber };
        var pdfReader = new PdfReader(sourcePdfPath);
        var pdfCopyFields = new PdfCopyFields(memoryStream);

        pdfReader.SelectPages(pageNumbers);
        pdfCopyFields.AddDocument(pdfReader);
        pdfReader.RemoveUnusedObjects();
        pdfCopyFields.Close();
        pdfReader.Close();
        return memoryStream.ToArray();
    }
}

private static byte[] RenamePageFields(byte[] pdfBytes, int pageNumber)
{
    using (var memoryStream = new MemoryStream())
    {
        var pdfReader = new PdfReader(pdfBytes);
        var pdfStamper = new PdfStamper(pdfReader, memoryStream);
        var acroFields = pdfStamper.AcroFields;
        var fieldNames = acroFields.Fields.Keys.Cast<String>().ToList();

        foreach (var fieldName in fieldNames)
        {
            var newName = String.Format("{0}_{1}", fieldName, pageNumber);
            acroFields.RenameField(fieldName, newName);
        }

        pdfStamper.Close();
        pdfReader.Close();
        return memoryStream.ToArray();
    }
}
publicstaticvoidexpandrepeatingpages(stringsourcepdfpath、stringoutputpdfpath)
{
/*计算出我们正在处理的页面数*/
var transientPdfReader=新的PdfReader(sourcePdfPath);
var numberOfPages=transientPdfReader.numberOfPages;
transientPdfReader.Close();
var outputFileStream=newfilestream(outputPdfPath,FileMode.Create);
var pdfCopyFields=新的pdfCopyFields(outputFileStream);
foreach(可枚举范围中的变量页码(1,numberOfPages))
{
var pdfBytes=提取页面字节(sourcePdfPath,页码);
var pdfReader=新pdfReader(pdfBytes);
pdfCopyFields.AddDocument(pdfReader);
pdfReader.Close();
如果(页码==2)
{
foreach(可枚举范围(2200)中的var外部页码)
{
var extraPagePdfBytes=RenamePageFields(pdfBytes,extraPageNumber);
pdfReader=新pdfReader(页外PDFBytes);
pdfCopyFields.AddDocument(pdfReader);
pdfReader.Close();
}
}
}
pdfCopyFields.Close();
}
公共静态字节[]ExtractPageToBytes(字符串sourcePdfPath,int pageNumber)
{
使用(var memoryStream=new memoryStream())
{
var pageNumbers=new System.Collections.ArrayList{pageNumbers};
var pdfReader=新的pdfReader(sourcePdfPath);
var pdfCopyFields=新的pdfCopyFields(memoryStream);
PDF阅读器。选择页面(页码);
pdfCopyFields.AddDocument(pdfReader);
pdfReader.RemoveUnusedObjects();
pdfCopyFields.Close();
pdfReader.Close();
返回memoryStream.ToArray();
}
}
私有静态字节[]重命名字段(字节[]pdfBytes,整数页码)
{
使用(var memoryStream=new memoryStream())
{
var pdfReader=新pdfReader(pdfBytes);
var pdfStamper=新的pdfStamper(pdfReader,memoryStream);
var acroFields=pdfStamper.acroFields;
var fieldNames=acroFields.Fields.Keys.Cast().ToList();
foreach(字段名中的变量字段名)
{
var newName=String.Format(“{0}{1}”,字段名,页码);
acroFields.RenameField(fieldName,newName);
}
pdfStamper.Close();
pdfReader.Close();
返回memoryStream.ToArray();
}
}

这里的问题是,由于AGPL版本中的许可限制,我不得不使用iTextSharp 4.1.6.0。我不想通过加入这个警告来阻止任何人回答,因为我确信现在几乎没有人再使用这个版本了。旧版本似乎带有第22条军规。我可能有200个第2页的实例,这使得PdfSmartCopy几乎成为一种必要,但由于我处理的是acro字段,文档让我相信我必须使用PdfCopyFields。“由于AGPL中的许可限制”,显示出缺乏经济学人才。使用旧软件的成本可能高于商业许可证的成本。成本并不是一个真正的问题,而是我没有时间花在冗长的内部购买过程上。解决方案需要在明天交付。当前版本是否有任何新功能可以绕过PdfCopyFields与PdfSmartCopy catch-22?