【问题标题】:Populate Multiple PDFs填充多个 PDF
【发布时间】:2011-02-21 10:12:45
【问题描述】:

我正在使用 itextsharp 来填充我的 PDF。我对此没有任何问题。基本上我正在做的是获取 PDF 并填充内存中的字段,然后传回 MemoryStream 以显示在网页上。所有这些都适用于单个文档 PDF。

我现在想弄清楚的是,将多个 PDF 合并为一个 MemoryStream。我无法弄清楚的部分是,我填充的文档是相同的。例如,我有一个包含 5 个人的 List<Person>。我想为每个人填写一份 PDF 并将它们合并为一个,在内存中。请记住,我将为每个人填写相同类型的文档。

我遇到的问题是,当我尝试添加要为第二次迭代填写的同一 PDF 的第二个副本时,它只会覆盖第一个填充的 PDF,因为它是同一个文档,因此不添加第二个完全复制第二个Person

所以基本上,如果我有 5 个人,我最终会得到一个包含第 5 个人数据的页面,而不是一个包含 5 个类似页面的 PDF,分别包含每个人的数据。

这里有一些代码...

MemoryStream ms = ms = new MemoryStream();
PdfReader docReader = null;
PdfStamper Stamper = null;
List<Person> persons = new List<Person>() {
   new Person("Larry", "David"),
   new Person("Dustin", "Byfuglien"),
   new Person("Patrick", "Kane"),
   new Person("Johnathan", "Toews"),
   new Person("Marian", "Hossa")
};

try
{
   // Iterate thru all persons and populate a PDF for each
   foreach(var person in persons){
      PdfCopyFields Copier = new PdfCopyFields(ms);
      Copier.AddDocument(GetReader("Person.pdf"));
      Copier.Close();

      docReader = new PdfReader(ms.ToArray());
      Stamper = new PdfStamper(docReader, ms);
      AcroFields Fields = Stamper.AcroFields;
      Fields.SetField("FirstName", person.FirstName);
   }
}catch(Exception e){
  // handle error
}finally{
   if (Stamper != null)
   {
      Stamper.Close();
   }
   if (docReader != null)
   {
      docReader.Close();
   }
}

【问题讨论】:

  • 芝加哥黑鹰队+1!! :)
  • @Cameron Peters - 是的,他们是一个团队。

标签: c# asp.net-mvc pdf itextsharp


【解决方案1】:

我已经创建了一个可行的解决方案,我希望这可以帮助某人。

创建一个 PopulatePDF() 方法,该方法接受 Person 对象并返回一个 byte[]

private byte[] PopulatePersonPDF(Person obj)
{
   MemoryStream ms = new MemoryStream();
   PdfStamper Stamper = null;

   try
   {
      PdfCopyFields Copier = new PdfCopyFields(ms);
      Copier.AddDocument(GetReader("Person.pdf"));
      Copier.Close();

      PdfReader docReader = new PdfReader(ms.ToArray());
      ms = new MemoryStream();
      Stamper = new PdfStamper(docReader, ms);
      AcroFields Fields = Stamper.AcroFields;
      Fields.SetField("FirstName", obj.FirstName);
   }
   finally
   {
      if (Stamper != null)
      {
         Stamper.Close();
      }
   }
   return ms.ToArray();
}

创建一个 MergePDFs() 方法,该方法返回 MemoryStream

private MemoryStream MergePDFs(List<byte[]> pdfs)
{
   MemoryStream ms = new MemoryStream();
   PdfCopyFields Copier = new PdfCopyFields(ms);

   foreach (var pdf in pdfs)
      Copier.AddDocument(new PdfReader(pdf));
   Copier.Close();
   return ms;
}

示例实现:

List<Person> persons = new List<Person>() {
   new Person("Larry", "David"),
   new Person("Dustin", "Byfuglien"),
   new Person("Patrick", "Kane"),
   new Person("Johnathan", "Toews"),
   new Person("Marian", "Hossa")
};

List<byte[]> pdfs = new List<byte[]>();

foreach(var person in persons)
   pdfs.Add(PopulatePersonPDF(person));

MemoryStream ms = MergePDFs(pdfs);

【讨论】:

  • 如何在不加载模板 10 次的情况下做到这一点?获得 10 倍的大小
  • PdfCopyFields 似乎是大赚一笔。如果您正在使用内存中的流,这非常重要:PdfCopyFields Copier = new PdfCopyFields(ms); Copier.Writer.CloseStream = false
【解决方案2】:

这可能是您解决方案的另一个答案:Batch Pdf generation

【讨论】:

    【解决方案3】:

    检查 PdfStamper 构造函数签名是否有一个重载,它采用一个布尔值,告诉它附加到当前文档。

    【讨论】:

      猜你喜欢
      • 2020-06-10
      • 1970-01-01
      • 1970-01-01
      • 2022-07-20
      • 2015-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多