I'll put it simply like that:
I want a PDF where I control each and every object's location / size / other properties. Usually the objects are either texts or images. So I ended up with a small piece of code which does that, and returns byte array. The byte array is easier to transmit over the net.
Let's begin with the wrapping:
public byte[] GetPDF()
{
System.IO.MemoryStream ms = new System.IO.MemoryStream();
iTextSharp.text.Document doc = new iTextSharp.text.Document();
iTextSharp.text.pdf.PdfWriter writer = iTextSharp.text.pdf.PdfWriter.GetInstance(doc, ms);
doc.Open();
iTextSharp.text.Rectangle page = doc.PageSize;
iTextSharp.text.pdf.PdfContentByte cb = writer.DirectContent;
string fontsDirName = (string)Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders").GetValue("Fonts");
iTextSharp.text.FontFactory.RegisterDirectory(fontsDirName);
RenderPDFImages(doc);
RenderPDFTexts(cb, doc.PageSize.Height);
doc.Close();
ms.Flush();
return ms.ToArray();
}
Quite self-explanatory, wrap the Render PDF methods with the creation of the document and the transform to byte array. Note that RenderPDFImages gets the document and RenderPDFTexts gets the content + page's height.
Both of the render methods loop over the objects and call the "Add" method. I'm supplying the "Add" methods, instead of the complete loop.
Important things to remember:
1. The Y coordinate is calculated from the bottom, not from the top. For this reason the code is full of Page Height - Y - Local Height.
2. Before starting to add texts call cb.BeginText(); and when you're done call cb.EndText();
First the AddImage:
private void AddImage(iTextSharp.text.Document doc, System.Drawing.Image img, float X, float Y)
{
iTextSharp.text.Image gif = iTextSharp.text.Image.GetInstance(imageToByteArray(img));
gif.Alignment = iTextSharp.text.Image.ALIGN_LEFT;
gif.SetAbsolutePosition(X, doc.PageSize.Height - Y - gif.PlainHeight);
doc.Add(gif);
}
Note: I convert the image to byte array, that way I can control the type of image inserted + it avoids a strange behavior I've encountered when trying to add it directly.
And the last method, AddText:
private void AddText(iTextSharp.text.pdf.PdfContentByte cb, float PageHeight, string txt, System.Drawing.Font fnt, System.Drawing.Color clr, float x, float y)
{
iTextSharp.text.pdf.BaseFont bf = iTextSharp.text.FontFactory.GetFont(fnt.Name).BaseFont;
cb.SetRGBColorFill(clr.R, clr.G, clr.B);
cb.SetFontAndSize(bf, fnt.Size);
cb.SetTextMatrix(x, PageHeight - y - fnt.Height);
cb.ShowText(txt);
}
There are many more things which can be done with those objects. I used the bare minimum to get the output in PDF format while making sure it looks almost like the original picture.
Subscribe to:
Post Comments (Atom)
1 comment:
Hi,
Nice blog! Anyone uses iTextSharp to create PDFs containing form fields. It is for a form that is generated from a database. iTextSharp is a C# port of a popular java library for creating Adobe Acrobat PDF files. It's powerful and flexible. It would be great if you can provide more details about it. Thank you.
Adobe Digital Rights
Post a Comment