I am using itextsharp
to populate my PDFs. I have no issues with this. Basically what I am doing is getting the PDF and populating the fields in memory then passing back the MemoryStream
to be displayed on a webpage. All this is working with a single document PDF.
What I am trying to figure out now, is merging multiple PDFs into one MemoryStream
. The part I cant figure out is, the documents I am populating are identical. So for example, I have a List<Person>
that contains 5 persons. I want to fill out a PDF for each person and merge them all into one, in memory. Bare in mind I am going to fill out the same type of document for each person.
The problem I am getting is that when I try to add a second copy of the same PDF to be filled out for the second iteration, it just overwrites the first populated PDF, since it's the same document, therefore not adding a second copy for the second Person
at all.
So basically if I had the 5 people, I would end up with a single page with the data of the 5th person, instead of a PDF with 5 like pages that contain the data of each person respectively.
Here's some code...
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();
}
}
I have created a working solution, I hope this helps someone along the way.
Create a PopulatePDF()
method that takes the Person
object and returns a 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();
}
Create a MergePDFs()
method that returns the 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;
}
Example Implementation:
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With