Заполните несколько PDF-файлов - PullRequest
5 голосов
/ 19 мая 2010

Я использую itextsharp для заполнения моих PDF-файлов. У меня нет проблем с этим. По сути, я делаю получение PDF и заполнение полей в памяти, а затем возвращаю MemoryStream для отображения на веб-странице. Все это работает с одним документом PDF.

То, что я сейчас пытаюсь выяснить, это объединение нескольких PDF-файлов в один MemoryStream. Часть, которую я не могу понять, состоит в том, что документы, которые я заполняю, идентичны. Так, например, у меня есть List<Person>, который содержит 5 человек. Я хочу заполнить PDF для каждого человека и объединить их в один, в памяти. Не берите в голову, я собираюсь заполнить один и тот же тип документа для каждого человека.

Проблема, которую я получаю, заключается в том, что, когда я пытаюсь добавить вторую копию того же PDF-файла для заполнения для второй итерации, он просто перезаписывает первый заполненный PDF-файл, поскольку это тот же документ, поэтому не добавляется второй скопируйте для второго Person на всех.

Таким образом, в основном, если бы у меня было 5 человек, я бы в итоге получил одну страницу с данными 5-го человека, а не PDF-файл с 5 подобными страницами, которые содержат данные каждого человека соответственно.

Вот код ...

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();
   }
}

Ответы [ 3 ]

2 голосов
/ 19 мая 2010

Я создал рабочее решение, надеюсь, это поможет кому-то на этом пути.

Создать метод 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);
0 голосов
/ 22 января 2011

здесь может быть другой ответ на ваше решение: Пакетная генерация PDF

0 голосов
/ 19 мая 2010

Проверьте сигнатуру конструктора PdfStamper, есть перегрузка, которая принимает логическое значение, которое говорит ему добавить в текущий документ.

...