At my work sometimes I have to merge from few to few hundreds pdf files. All the time I've been using Writer
and ImportedPages
classes. But when I have merged all files into one, file size becomes enormous, sum of all merged files sizes, because fonts being attached to every page, and not reused (fonts are embedded to every page, not whole document).
Not very long time ago I found out about PdfSmartCopy
class, which reuses embedded fonts and images. And here the problem kicks in. Very often, before merging files together, I have to add additional content to them (images, text). For this purpose I usually use PdfContentByte
from Writer
object.
Document doc = new Document();
PdfWriter writer = PdfWriter.GetInstance(doc, new FileStream("C:\test.pdf", FileMode.Create));
PdfContentByte cb = writer.DirectContent;
cb.Rectangle(100, 100, 100, 100);
cb.SetColorStroke(BaseColor.RED);
cb.SetColorFill(BaseColor.RED);
cb.FillStroke();
When I do similar thing with PdfSmartCopy
object, pages are merged, but no additional content being added. Full code of my test with PdfSmartCopy
:
using (Document doc = new Document())
{
using (PdfSmartCopy copy = new PdfSmartCopy(doc, new FileStream(Path.GetDirectoryName(pdfPath[0]) + "\\testas.pdf", FileMode.Create)))
{
doc.Open();
PdfContentByte cb = copy.DirectContent;
for (int i = 0; i < pdfPath.Length; i++)
{
PdfReader reader = new PdfReader(pdfPath[i]);
for (int ii = 0; ii < reader.NumberOfPages; ii++)
{
PdfImportedPage import = copy.GetImportedPage(reader, ii + 1);
copy.AddPage(import);
cb.Rectangle(100, 100, 100, 100);
cb.SetColorStroke(BaseColor.RED);
cb.SetColorFill(BaseColor.RED);
cb.FillStroke();
doc.NewPage();// net nesessary line
//ColumnText col = new ColumnText(cb);
//col.SetSimpleColumn(100,100,500,500);
//col.AddText(new Chunk("wdasdasd", PdfFontManager.GetFont(@"C:\Windows\Fonts\arial.ttf", 20)));
//col.Go();
}
}
}
}
}
Now I have few questions:
PdfSmartCopy
object's DirectContent?First this: using PdfWriter
/PdfImportedPage
is not a good idea. You throw away all interactive features! Being the author of iText, it's very frustrating to so many people making the same mistake in spite of the fact that I wrote two books about this, and in spite of the fact that I convinced my publisher to offer one of the most important chapters for free: http://www.manning.com/lowagie2/samplechapter6.pdf
Is my writing really that bad? Or is there another reason why people keep on merging documents using PdfWriter
/PdfImportedPage
?
As for your specific questions, here are the answers:
PageStamp
.PdfCopy
; or create the merged PDF first with PdfCopy, then add the extra content in a second pass using PdfStamper
.Code after using Bruno Lowagie answer
for (int i = 0; i < pdfPath.Length; i++)
{
PdfReader reader = new PdfReader(pdfPath[i]);
PdfImportedPage page;
PdfSmartCopy.PageStamp stamp;
for (int ii = 0; ii < reader.NumberOfPages; ii++)
{
page = copy.GetImportedPage(reader, ii + 1);
stamp = copy.CreatePageStamp(page);
PdfContentByte cb = stamp.GetOverContent();
cb.Rectangle(100, 100, 100, 100);
cb.SetColorStroke(BaseColor.RED);
cb.SetColorFill(BaseColor.RED);
cb.FillStroke();
stamp.AlterContents(); // don't forget to add this line
copy.AddPage(page);
}
}
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