Reputation: 984
I have a PDF form that is 4 x A4 pages. I complete the fields using iTextSharp. All good with this part.
I then need to combine a number of these forms into one PDF document. Plan on using this approach : Using iTextSharp to generate multiple page PDF from existing PDF Form.
These A4 pages however, need to be combined into a single A3 sheet, printed in a "booklet" type configuration, i.e. front and back like below
A3 Front ----- turn over ----> A3 Back
------------------------------- -------------------------------
| | | | | |
| | | | | |
| | | | | |
| Page | Page | | Page | Page |
| 4 | 1 | | 2 | 3 |
| | | | | |
| | | | | |
| | | | | |
------------------------------- -------------------------------
(ascii ftw)
When the A3 is then folded in half, it would read (left to right), page 1, page 2, page 3, page 4. I would then combine all my completed forms in this manner, then print the whole PDF document on A3 back-to-back.
I found this post (http://forums.asp.net/t/1692347.aspx?Merging+two+pdf+pages+into+one+using+itextsharp) that mentions putting a PdfPTable on the page, then grabbing an Image of the page, and embedding it in the table cell...
If I did it this, wouldn't the PDF file be massive, since its basically full of images? Is there a better way to achieve this?
Upvotes: 0
Views: 1848
Reputation: 984
Figured it out... follow this approach:
using (var copyms = new MemoryStream())
{
var document = new Document();
using (PdfSmartCopy copy = new PdfSmartCopy(document, copyms))
{
document.Open();
foreach (var item in Items)
{
// Read the template
var pdfReader = new PdfReader(TemplateLocation);
// Save the current completed template to a MemoryStream
using (var ms = new MemoryStream())
{
using (PdfStamper stamper = new PdfStamper(pdfReader, ms))
{
var fields = stamper.AcroFields;
// Set the field values here
stamper.FormFlattening = true;
}
pdfReader = new PdfReader(ms.ToArray());
// Copy the memorystream to the main document
copy.AddDocument(pdfReader);
}
}
}
document.CloseDocument();
// Combine on A3 pages in new document
var a3doc = new Document(PageSize.A3.Rotate(), 0, 0, 0, 0);
var a3reader = new PdfReader(copyms.ToArray());
var a3writer = PdfWriter.GetInstance(a3doc, new FileStream(outputFileLocation, FileMode.Create));
a3doc.Open();
var a3cb = a3writer.DirectContent;
PdfImportedPage page;
int totalPages = a3reader.NumberOfPages;
for (int i = 1; i <= (int)Math.Ceiling(totalPages / 2); i++)
{
// Create an A3 page
a3doc.NewPage();
var a3size = PageSize.A3.Rotate();
page = a3writer.GetImportedPage(a3reader, (i * 2) + 1);
a3cb.AddTemplate(page, 0, 0);
page = a3writer.GetImportedPage(a3reader, (i * 2) + 2);
a3cb.AddTemplate(page, (int)(a3size.Width / 2), 0);
}
a3doc.CloseDocument();
}
So basically, keep everything in memory, and at the end use the writer's DirectContent to paste the A4 page somewhere on the A3 page. Also, use PdfSmartCopy to keep the file size low since the template page stuff isn't being added everytime you add a filled copy.
Upvotes: 1