Discussion:
[itextsharp-questions] how to mail merge using a template and database
Matthew
2006-12-27 11:09:42 UTC
Permalink
Hello

I have only been working with iTextSharp for today and am really impressed
with its wide range of capabilities. Please forgive me if this has been
answered already, I have searched the mailing list for about an hour with no
luck.

I would like to take a pdf form creating in adobe designer and the as I
itterate through records in a database create a single multi page pdf
document with each record using a copy of the template. This functionality
is similar to a mail merge operation suing MSWord. At the moment I can read
the template and fill out the form fields once using PdfStamper, what I'm
stuck on is how to get the template multiple times and use it to create
multiple pages, I guess I have to flatten at the end of each record so that
the next time I use SetField() there is only one instance.

Anyway, any help or rough design on how this would work would be great.

Should I order the book iText In Action, is it applicable for iTextSharp?


Cheers

Matthew
Paulo Soares
2006-12-27 13:40:33 UTC
Permalink
----- Original Message -----
From: "Matthew" <***@newcastlecreativemedia.com.au>
To: <itextsharp-***@lists.sourceforge.net>
Sent: Wednesday, December 27, 2006 11:09 AM
Subject: [itextsharp-questions] how to mail merge using a template
anddatabase
Post by Matthew
Hello
I have only been working with iTextSharp for today and am really impressed
with its wide range of capabilities. Please forgive me if this has been
answered already, I have searched the mailing list for about an hour with no
luck.
I would like to take a pdf form creating in adobe designer and the as I
itterate through records in a database create a single multi page pdf
document with each record using a copy of the template. This functionality
is similar to a mail merge operation suing MSWord. At the moment I can read
the template and fill out the form fields once using PdfStamper, what I'm
stuck on is how to get the template multiple times and use it to create
multiple pages, I guess I have to flatten at the end of each record so that
the next time I use SetField() there is only one instance.
You fill and flatten each template with PdfStamper and add it to PdfCopy.
Post by Matthew
Anyway, any help or rough design on how this would work would be great.
Should I order the book iText In Action, is it applicable for iTextSharp?
You should buy the book. The examples and explanations are in Java but it's
trivial to adapt them to C# or VB.NET. For example, what you're asking is
described in chapter 16.1.

Paulo
Matthew
2006-12-28 13:15:38 UTC
Permalink
Quote: You fill and flatten each template with PdfStamper and add it to
PdfCopy.

OK, Thanks for the clue. This is what I have so far

protected void Page_Load(object sender, EventArgs e)
{

string formFile = @"c:\form.pdf";
string newFile = @"c:\new.pdf";
string tempFile = @"c:\temp.pdf";
PdfReader formReader = new PdfReader(formFile);

//MemoryStream ms = new MemoryStream();
PdfStamper stamper = new PdfStamper(formReader, new
FileStream(tempFile, FileMode.Create));

AcroFields fields;
fields = stamper.AcroFields;
fields.SetField("name", "John Doe");
fields.SetField("address", "2 Milky Way, London");
stamper.FormFlattening = true;

Document doc = new Document();
PdfCopy pdfcopy = new PdfCopy(doc, new FileStream(newFile,
FileMode.Create));
doc.Open();

pdfcopy.AddPage(stamper.Writer.GetImportedPage(formReader, 1));

doc.Close();

stamper.Close();
}

What I'm stuck on is how to keep using the stamper to fill out the form and
add it to the new PDF. What I have here doesn't work in a number of areas.

1. I'm creating a temporary file, should I use a stream, or can I populate
the form fields in another way

2. pdfcopy.AddPage(stamper.Writer.GetImportedPage(formReader, 1)); This adds
a new page but it has no fields filled out in it, so I'm just trying to
guess here how this might work.

Could you spare some seudo-code or c# example?

Thanks again.


uote: You should buy the book. The examples and explanations are in Java but
it's
trivial to adapt them to C# or VB.NET. For example, what you're asking is
described in chapter 16.1.

OK, I have orderd the book but have about 14 days before it arrives. Any
help in the mean time would be great.

Cheers.


-----Original Message-----
From: Matthew [mailto:***@newcastlecreativemedia.com.au]
Sent: Wednesday, 27 December 2006 10:10 PM
To: 'itextsharp-***@lists.sourceforge.net'
Subject: how to mail merge using a template and database

Hello

I have only been working with iTextSharp for today and am really impressed
with its wide range of capabilities. Please forgive me if this has been
answered already, I have searched the mailing list for about an hour with no
luck.

I would like to take a pdf form creating in adobe designer and the as I
itterate through records in a database create a single multi page pdf
document with each record using a copy of the template. This functionality
is similar to a mail merge operation suing MSWord. At the moment I can read
the template and fill out the form fields once using PdfStamper, what I'm
stuck on is how to get the template multiple times and use it to create
multiple pages, I guess I have to flatten at the end of each record so that
the next time I use SetField() there is only one instance.

Anyway, any help or rough design on how this would work would be great.

Should I order the book iText In Action, is it applicable for iTextSharp?


Cheers

Matthew
Paulo Soares
2006-12-28 13:27:29 UTC
Permalink
Adapting your example:

protected void Page_Load(object sender, EventArgs e)
{

string formFile = @"c:\form.pdf";
string newFile = @"c:\new.pdf";
string tempFile = @"c:\temp.pdf";
PdfReader formReaderOriginal = new PdfReader(formFile);
PdfReader formReader = new PdfReader(formReaderOriginal); //faster
than reading from file

MemoryStream ms = new MemoryStream();
PdfStamper stamper = new PdfStamper(formReader, ms);

AcroFields fields;
fields = stamper.AcroFields;
fields.SetField("name", "John Doe");
fields.SetField("address", "2 Milky Way, London");
stamper.FormFlattening = true;
stamper.Close();

PdfReader r = new PdfReader(ms.ToArray());
Document doc = new Document();
PdfCopy pdfcopy = new PdfCopy(doc, new FileStream(newFile,
FileMode.Create));
doc.Open();

pdfcopy.AddPage(pdfcopy.GetImportedPage(r, 1));

doc.Close();

}

Paulo

----- Original Message -----
From: "Matthew" <***@newcastlecreativemedia.com.au>
To: <itextsharp-***@lists.sourceforge.net>
Sent: Thursday, December 28, 2006 1:15 PM
Subject: Re: [itextsharp-questions] how to mail merge using a template
anddatabase
Post by Matthew
Quote: You fill and flatten each template with PdfStamper and add it to
PdfCopy.
OK, Thanks for the clue. This is what I have so far
protected void Page_Load(object sender, EventArgs e)
{
PdfReader formReader = new PdfReader(formFile);
//MemoryStream ms = new MemoryStream();
PdfStamper stamper = new PdfStamper(formReader, new
FileStream(tempFile, FileMode.Create));
AcroFields fields;
fields = stamper.AcroFields;
fields.SetField("name", "John Doe");
fields.SetField("address", "2 Milky Way, London");
stamper.FormFlattening = true;
Document doc = new Document();
PdfCopy pdfcopy = new PdfCopy(doc, new FileStream(newFile,
FileMode.Create));
doc.Open();
pdfcopy.AddPage(stamper.Writer.GetImportedPage(formReader, 1));
doc.Close();
stamper.Close();
}
What I'm stuck on is how to keep using the stamper to fill out the form and
add it to the new PDF. What I have here doesn't work in a number of areas.
1. I'm creating a temporary file, should I use a stream, or can I populate
the form fields in another way
2. pdfcopy.AddPage(stamper.Writer.GetImportedPage(formReader, 1)); This adds
a new page but it has no fields filled out in it, so I'm just trying to
guess here how this might work.
Could you spare some seudo-code or c# example?
Thanks again.
uote: You should buy the book. The examples and explanations are in Java but
it's
trivial to adapt them to C# or VB.NET. For example, what you're asking is
described in chapter 16.1.
OK, I have orderd the book but have about 14 days before it arrives. Any
help in the mean time would be great.
Cheers.
-----Original Message-----
Sent: Wednesday, 27 December 2006 10:10 PM
Subject: how to mail merge using a template and database
Hello
I have only been working with iTextSharp for today and am really impressed
with its wide range of capabilities. Please forgive me if this has been
answered already, I have searched the mailing list for about an hour with no
luck.
I would like to take a pdf form creating in adobe designer and the as I
itterate through records in a database create a single multi page pdf
document with each record using a copy of the template. This functionality
is similar to a mail merge operation suing MSWord. At the moment I can read
the template and fill out the form fields once using PdfStamper, what I'm
stuck on is how to get the template multiple times and use it to create
multiple pages, I guess I have to flatten at the end of each record so that
the next time I use SetField() there is only one instance.
Anyway, any help or rough design on how this would work would be great.
Should I order the book iText In Action, is it applicable for iTextSharp?
Cheers
Matthew
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share
your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
itextsharp-questions mailing list
https://lists.sourceforge.net/lists/listinfo/itextsharp-questions
Matthew
2006-12-28 23:07:10 UTC
Permalink
Thanks very much for the help. This is what I have now, just running a dummy
loop, I get 100 pages with unique data on each page.

protected void Page_Load(object sender, EventArgs e)
{
string formFile = @"c:\form.pdf";
string newFile = @"c:\new.pdf";
PdfReader formReaderOriginal = new PdfReader(formFile);
PdfReader formReader;
Document doc = new Document();
MemoryStream ms;
PdfCopy pdfcopy = new PdfCopy(doc, new FileStream(newFile,
FileMode.Create));
PdfStamper stamper;
AcroFields fields;
doc.Open();

for (int i = 0; i <= 100; i++)
{
//pass 1
ms = new MemoryStream();
formReader = new PdfReader(formReaderOriginal);
stamper = new PdfStamper(formReader, ms);
fields = stamper.AcroFields;
fields.SetField("name", "John Doe " + i.ToString());
fields.SetField("address", "2 Milky Way, London");
stamper.FormFlattening = true;
stamper.Close();
PdfReader r = new PdfReader(ms.ToArray());
pdfcopy.AddPage(pdfcopy.GetImportedPage(r, 1));
}

doc.Close();
}
doc.Close();

This correctly gives me what I want, I will look at some optimisations
later.

Thanks again.
Paulo Soares
2006-12-28 23:29:50 UTC
Permalink
After using the reader free the memory with:

PdfReader r = new PdfReader(ms.ToArray());
pdfcopy.AddPage(pdfcopy.GetImportedPage(r, 1));
pdfcopy.FreeReader(r);

It's not important for 100 pages but you'll find it useful for 10000 pages.

Paulo

----- Original Message -----
From: "Matthew" <***@newcastlecreativemedia.com.au>
To: <itextsharp-***@lists.sourceforge.net>
Sent: Thursday, December 28, 2006 11:07 PM
Subject: Re: [itextsharp-questions] how to mail merge using a template
anddatabase
Post by Matthew
Thanks very much for the help. This is what I have now, just running a dummy
loop, I get 100 pages with unique data on each page.
protected void Page_Load(object sender, EventArgs e)
{
PdfReader formReaderOriginal = new PdfReader(formFile);
PdfReader formReader;
Document doc = new Document();
MemoryStream ms;
PdfCopy pdfcopy = new PdfCopy(doc, new FileStream(newFile,
FileMode.Create));
PdfStamper stamper;
AcroFields fields;
doc.Open();
for (int i = 0; i <= 100; i++)
{
//pass 1
ms = new MemoryStream();
formReader = new PdfReader(formReaderOriginal);
stamper = new PdfStamper(formReader, ms);
fields = stamper.AcroFields;
fields.SetField("name", "John Doe " + i.ToString());
fields.SetField("address", "2 Milky Way, London");
stamper.FormFlattening = true;
stamper.Close();
PdfReader r = new PdfReader(ms.ToArray());
pdfcopy.AddPage(pdfcopy.GetImportedPage(r, 1));
}
doc.Close();
}
doc.Close();
This correctly gives me what I want, I will look at some optimisations
later.
Thanks again.
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share
your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
itextsharp-questions mailing list
https://lists.sourceforge.net/lists/listinfo/itextsharp-questions
Matthew
2006-12-29 01:28:22 UTC
Permalink
Thanks for the extra tip.

I'm finding that if I have an initiall input PDF file size of around 100k
(and this is just a page with two form fields on it), that when I create a
new 1000 page pdf with the fields filled out on each page that the final
file size is about 98MB. Any tips on how to reduce this? There are no
graphics in the source PDF.

Cheers

Loading...