1. Introduction
The PDF File Writer C# class library
PdfFileWriter allows you to create PDF files directly from your .net application. The library shields you from the details of the PDF file structure. To use the library, you need to add a reference to the attached
PdfFileWriter.dll class library file, add a
using PdfFileWriter statement in every source file that is using the library and include the
PdfFileWriter.dll with your distribution. For more details go to
2.17 Installation. Alternatively, you can include the source code of the library with your application and avoid the need to distribute a separate data link library file. The minimum development requirement is .NET Framework 4.0 (Visual Studio 2010).
Version 1.12 Enhancements
- Reorder pages. The library allows you to move any page to a new position. Section 2.16 Reorder Pages.
- Enhanced support for data table border lines. Section 2.12 Data Table Support. Upgrading from previous version might require some changes.
|
The PDF File Writer C# class library supports the following PDF document's features:
Creating a PDF is a six steps process.
- Step 1: Create one document object
PdfDocument.
- Step 2: Create resource objects such as fonts or images (i.e.
PdfFont or PdfImage).
- Step 3: Create page object
PdfPage.
- Step 4: Create contents object
PdfContents.
- Step 5: Add text and graphics to the contents object (using
PdfContents methods).
- Repeat steps 3, 4 and 5 for additional pages
- Step 6: Create your PDF document file by calling
CreateFile method of PdfDocument.
Step 5 is where most of your programming effort will be spent. Adding contents is achieved by calling the methods of
PdfContents class to render graphics and text. The contents class has a rich set (about 100) of methods for adding text and graphics to your document.
The demo program attached to this article is the test program developed to debug the library. The
TestPdfFileWriter has six buttons on the main screen. Five buttons to produce examples of PDF files and one button to display all fonts available on your computer. The first button “Article Example” creates the PDF file displayed at the top of this article. Section
3. Development Guide by Example.
As stated before, the
PdfFileWriter C# class library shields you from the complexities of the PDF file structure. However, good understanding of PDF file is always an advantage. Adobe PDF file specification document available from Adobe website:
“PDF Reference, Sixth Edition, Adobe Portable Document Format Version 1.7 November 2006”. It is an intimidating 1310 pages document. I would strongly recommend reading Chapter 4 Graphics and sections 5.2 and 5.3 of the Text chapter 5.
If you want to analyze the PDF files created by this project, or if you want to understand PDF file structure in general, you can use the demo program attached to my previous article
"PDF File Analyzer With C# Parsing Classes". This article provides a concise overview of the PDF specifications.
2. PDF File Writer Library General Notes
The PDF coordinate system origin is at the bottom left corner of the page. The X-axis is pointing to the right. The Y-axis is pointing in upward direction.
The PDF unit of measure is point. There are 72 points in one inch. The PDF File writer allows you to select your own unit of measure. All methods arguments representing position, width or height must be in your unit of measure. There are two exceptions: font size and resolution. Font size is always in points. Resolution is always in pixels per inch. The PDF File Writer converts all input arguments to points. All internal measurement values and calculations are done with double precision. At the final step when the PDF file is created, the values are converted to text strings. The conversion precision is six digits. The conversion formula used is:
Hide Copy Code
String Result = ((Single) Math.Round(Value, 6, MidpointRounding.AwayFromZero)).ToString();
2.2. Decimal separator
PDF readers such as Adobe Acrobat expect real numbers with a fraction to use period as the decimal separator. Some of the world regions use other decimal separators such as comma. Since Version 1.1 of the PDF File Writer library will use period as decimal separator regardless of regional setting of your computer.
The PDF File Writer library is using TrueType fonts. Please note Section 5.5 Simple Fonts of the PDF specifications. TrueType fonts are defined as simple fonts with the property "Glyphs in the font are selected by single-byte character codes obtained from a string that is shown by the text-showing operators". In other words this library is limited to one byte encoding, 0 to 255. Not all values within this range are available. Control codes 0 to 31 and 128 to 159 are excluded. The result is that this class library supports characters in the range 32 to 126 and 160 to 255. These characters are encoded using WinAnsiEncoding. It is Windows Code Page 1252, often called the “Windows ANSI” encoding. This is the standard Windows encoding for Latin text in Western writing systems.
Most TrueType fonts such as Arial supports character values greater than 255. The PDF File Library allows you to perform a substitution. You can use any Unicode character and map it into the available one byte range. It is performed by
CharSubstitution method of the
PdfFont class. Two characters within the allowable range: space (32) and non breaking space (160) cannot be replaced.
Hide Copy Code
PdfFont.CharSubstitution(int OriginStart, int OriginEnd, int DestStart);
For example, Unicode Greek low case letters are encoded starting with 945. To use the first 6 letters we will map them to position 161.
Hide Copy Code
ArialNormal = new PdfFont(Document, "Arial", FontStyle.Regular, true);
ArialNormal.CharSubstitution(945, 950, 161);
To print them:
Hide Copy Code
Contents.DrawText(ArialNormal, FontSize, TextPos, BaseLine, "αβγδεζ");
In versions prior to 1.4, the characters in the text string had to be recalculated. Starting with Version 1.4 you just put the Unicode string as is. If the text string contains characters that were not substituted, the program will fail with exception.
Another example, Unicode Hebrew letters are encoded in a block from 1488 to 1514. To use Hebrew letters we map them again to 161.
Hide Copy Code
ArialNormal.CharSubstitution(1488, 1514, 161);
Hebrew is a right to left language. PDF readers print left to right. If we print in the same way as Greek the result will be reversed string. To get the correct result, the PDF File Writer has a new method
PdfContents.ReverseString(String Text).
Hide Copy Code
Contents.DrawText(ArialNormal, FontSize, TextPos, BaseLine, Contents.ReverseString( "עברית");
The support for right to left languages of this package is limited. You can print single lines. To understand the complexities of Bidi support refer to
Unicode Bidirectional Algorithm. You can draw text but you have to remember that PDF prints left to right and text position is to the left of the string by default. Using
DrawText with
TextJustify.Right option will be more natural for Hebrew.
Hide Copy Code
Contents.DrawText(ArialNormal, FontSize, TextPos, BaseLine, TextJustify.Right, Contents.ReverseString( "עברית");
The
ReverseString method reverses the character order. It does not know the language. In other words you cannot reverse a string that contains the letters of right to left language together with numbers or English words or even brackets ()[]<>{}. Another limitation is
TextBox class cannot be used.
Images are always saved in the PDF file as jpeg images. Image source can be any format supported by .net. Adding an image to a PDF document is done as follows.
Define image resource object. There are 6 constructors to the
PdfImage class. The general format is given below.
Hide Copy Code
PdfImage Image = new PdfImage(Document, Image, CropRect, Resolution, ImageQuality);
The arguments are:
Document: The
PdfDocument object of your PDF document.
Image: Can either be an image file name as a
String, or an
Image derived class. Image derived class is either a
Bitmap for raster image or a
Metafile image for vector image. If file name is entered and the extension is .emf or .wmf the file is loaded into a
Metafile, otherwise the file is loaded into a
Bitmap.
CropRect: Crop rectangle is optional. If used, the rectangle defines the image area to be cropped. Note: the rectangle coordinates are in .net standard. Origin is at top left and Y axis is pointing down. The crop rectangle can be
Rectangle. In this case the dimensions are in pixels. If the crop rectangle is
RectangleF the dimensions are in percent of the image width and height. The crop rectangle must be contained within the image.
Resolution: Image resolution is optional. If specified, the PDF image will be set to this value provided that it is smaller than the resolution of source image. Resolution is specified in pixels per inch. Reduced resolution means smaller PDF file.
ImageQuality: Image quality is optional. It is an integer in the range of 0 to 100 representing poor to best quality image. Lower image quality means smaller PDF file.
The
ImageSize method returns the largest rectangle with correct aspect ratio that will fit in a given area.
Hide Copy Code
SizeD ImageSize(Double Width, Double Height);
The
ImageSizePosition method returns the largest rectangle with correct aspect ratio that will fit in a given area and position it based on
ContentAlignmentenumeration.
Hide Copy Code
ImageSizePos ImageSizePosition(Double Width, Double Height, ContentAlignment Alignment);
Finally to draw the image into the contents use
DrawImage method. If you want the image to maintain correct aspect ratio use
ImageSize or
ImageSizePosition to calculate the width and height. If the ratio of width and height is not the same as the image, the image will look stretched in one of the directions.
Hide Copy Code
Contents.DrawImage(Image, PosX, PosY, Width, Height);
It should be noted that in addition to
PdfImage,
PdfQRCode,
PdfChart and
PrintPdfDocument produce PDF images in the PDF document
The code below illustrates how to include UPC-A barcode in a PDF document.
Hide Copy Code
BarcodeEAN13 Barcode = new BarcodeEAN13("123456789010");
Contents.DrawBarcode(PosX, PosY, BarWidth, BarcodeHeight, Barcode, Font, FontSize);
In this case the class is BarcodeEAN13 with 12 digits input string. The result is UPC-A barcode.
The PDF File Writer library includes a base class
Barcode. For each supported barcode one needs a derived class. The class library includes four derived classes:
Barcode128,
Barcode39,
BarcodeInterleaved2of5 and
BarcodeEAN13. The
BarcodeEAN13 produces EAN-13 barcode if the input string is 13 digits and UPC-A if the input string is 12 digits. Input string with 13 digit and a leading zero is considered UPC-A.
The
DrawBarcode method has a number of overloads. You specify the position of the bottom left corner of the barcode, the width of the narrow bar, the height of the barcode and the derived barcode class. There are optional arguments: justification (left, center, right) color and font to display the text. Quiet zone around the barcode is your responsibility. Optional text is displayed below the barcode. If you select color other than black you should make sure the contrast to the background is significant. Usage examples are given in
3.7 Draw Barcodes,
ArticleExample.cs and
OtherExample.cs.
If you want to create a derived class for another barcode, use the source code for the three included classes as an example.
Starting with Version 1.7, the PDF File Writer library provides support to AES 128 encryption. For more information please refer to PDF Reference sixth edition (Version 1.7) section 3.5 Encryption. The PDF File writer supports only one type of encryption filter, the AES-128. It does not support public key security to encode recipient list.
To encrypt your PDF document call one of four
SetEncryption methods defined in
PdfDocument class:
Set Encryption with no arguments.
The PDF File Writer library will encrypt the PDF document using AES-128 encryption. The PDF reader will open the document without requesting a password. Permissions flags are set to allow all.
Hide Copy Code
Document.SetEncryption();
Set Encryption with one argument.
The PDF File Writer library will encrypt the PDF document using AES-128 encryption. The argument is permissions. Permission flags are defined below. You can or together more than one permission. The PDF reference manual has full description of permissions. The PDF reader will open the document without requesting a password.
Hide Copy Code
Document.SetEncryption(Permission Permissions);
Set Encryption with two arguments.
The PDF File Writer library will encrypt the PDF document using AES-128 encryption. The two arguments are user password and permissions. The PDF reader will open the document with user password. Permissions will be set as per argument.
Hide Copy Code
Document.SetEncryption(String UserPassword, Permission Permissions);
Set Encryption with three arguments.
The PDF File Writer library will encrypt the PDF document using AES-128 encryption. The three arguments are user and owner passwords and permissions.
The PDF reader will accept either user or owner password. If owner password is used to open document, the PDF reader will open it with all permissions set to allow operation.
Hide Copy Code
Document.SetEncryption(String UserPassword, String OwnerPassword, Permission Permissions);
Permission flags are as follows:
Hide Copy Code
public enum Permission
{
None = 0,
LowQalityPrint = 4, ModifyContents = 8, ExtractContents = 0x10, Annotation = 0x20, Interactive = 0x100, Accessibility = 0x200, AssembleDoc = 0x400, Print = 0x804, All = 0xf3c, }
Starting with Version 1.7, the PDF File Writer library provides support to web linking. This feature is one of the PDF interactive features described in the PDF reference manual in Section 8 Interactive Features. It is a combination of annotation and action. Annotation associates a web link with an area on the page. When the user clicks on the area, the PDF reader will activate the default web browser navigating to the desired web page.
The annotation area is a rectangle area defined by absolute coordinates relative to the bottom left corner of the page. To add a web link call
AddWebLink method of the
PdfPage class.
Hide Copy Code
Page.AddWebLink(Double LeftPos, Double BottomPos, Double RightPos, Double TopPos, String WebLink);
Annotations are not part of the page contents. In order or the reader of your PDF document to know where to click you need to display appropriate text or graphics in the same area on the page. In other words you need to call two methods. The AddWebLink method associated with the page and a second method associated with the contents. The second method can be a graphic object such as image or a rectangle, or text. Because AddWebLink requires coordinates relative to the bottom left corner of the page, the coordinates of your graphic object must be the same. In other words do not use translation, scaling or rotation. If you do, you need to make sure that the two areas will coincide.
The PDF File Writer has several PdfContents methods supporting text annotation.
Draw a line of text with associated web link. The text will be left justified, underlined and blue. Text position is relative to bottom left corner of the page.
Hide Copy Code
PdfContents.DrawWebLink(PdfPage Page, PdfFont Font, Double FontSize,
Double TextAbsPosX, Double TextAbsPosY, String Text, String WebLink);
Draw a line of text with associated web link. Text position is relative to bottom left corner of the page.
Hide Copy Code
PdfContents.DrawWebLink(PdfPage Page, PdfFont Font, Double FontSize, Double TextAbsPosX, Double TextAbsPosY,
TextJustify Justify, DrawStyle DrawStyle, Color TextColor, String Text, String WebLink);
Drawing web link within
TextBox is a two step process. First you add the text and the web link string to the box using one of the
AddText methods of
TextBoxclass. Second you draw the
TextBox to the page contents using one of the
DrawText methods of
PdfContents.
Add web link to
TextBox. The text will be displayed underlined and blue.
Hide Copy Code
TextBox.AddText(PdfFont Font, Double FontSize, String Text, String WebLink);
Add web link to
TextBox. The text attributes are defined by
DrawStyle and
FontColor.
Hide Copy Code
TextBox.AddText(PdfFont Font, Double FontSize, DrawStyle DrawStyle, Color FontColor, String Text, String WebLink);
Second step draw text to contents. This method assumes no extra line or paragraph spacing. Note, if you call
DrawText without
PdfPage argument on a
TextBoxwith
WebLink information,
ApplicationException will be thrown.
Hide Copy Code
PdfContents.DrawText(Double PosX, ref Double PosYTop, Double PosYBottom, Int32 LineNo, TextBox Box, PdfPage Page);
This method lets you define extra line or paragraph spacing. Note, if you call
DrawText without
PdfPage argument on a
TextBox with
WebLink information,
ApplicationException will be thrown.
Hide Copy Code
PdfContents.DrawText(Double PosX, ref Double PosYTop, Double PosYBottom, Int32 LineNo,
Double LineExtraSpace, Double ParagraphExtraSpace, Boolean FitTextToWidth, TextBox Box, PdfPage Page);
For coding examples please review
3.4 Draw Frame, ArticleExample.cs and OtherExample.cs source code.
Starting with Version 1.7, the PDF File Writer library provides support to QR Code. The program supports three character sets: numeric, alphanumeric and eight bit byte. The program does not support Kanji characters. The QR Code is an image resource. The library converts the QR Code contents into an image. To display a QR Code in a document one needs to define a resource object and add this object to the contents of a page. The program automatically selects the best character set and the best matrix size. The user has to supply data string and desired error correction level. Error correction levels are: L-Low (7%), M-Medium (15%), Q-Medium-High (25%), H-High (30%). Character sets are defined as: Numeric data (digits 0-9). Alphanumeric (digits 0-9, upper case letters A-Z and nine other characters space $ % * + - . / : ), 8-bit byte data. The program will scan the data string input and selects the most effective character set. If your data can be divided into segments with just digits or just alphanumeric characters you can create a QR Code object with array of data strings.
Create QR Code object with single data string.
Hide Copy Code
PdfQRCode QRCode = new PdfQRCode(PdfDocument Document, String DataString, ErrorCorrection ErrorCorrection);
Or, create QR Code object with array of data strings. Use this form if you want to divide the data string into sections of different character sets.
Hide Copy Code
PdfQRCode QRCode = new PdfQRCode(PdfDocument Document, String[] DataString, ErrorCorrection ErrorCorrection);
By default the image created will have 4 by 4 pixels per QR Code module and 16 pixels of quiet space around the image. To override the default use:
Hide Copy Code
QRCode.SetModuleSize(Int32 ModuleSize, Int32 QuietZone);
To draw the QR Code call
DrawQRCode method of
PdfContents. The
QRCode is a square. The width and height are the same.
Hide Copy Code
Contents.DrawQRCode(PdfQRCode QRCode, Double OrigX, Double OrigY, Double Width);
For coding examples please review
3.7 Draw Barcodes, ArticleExample.cs and OtherExample.cs source code.
Bookmarks are described in the PDF specification (section 8.2.2 Document Outline) as follows: "A PDF Document may optionally display a document outline on the screen, allowing the user to navigate interactively from one part of the document to another. The outline consists of a tree-structured hierarchy of outline items (sometimes called bookmarks), which serve as a visual table of contents to display the document's structure to the user. The user can interactively open and close individual item by clicking them with the mouse."
The OtherExample.cs source code has an example of bookmarks. At one location there is a hierarchy of three levels. You can see the result in OtherExample.pdf file.
The first step in adding bookmarks to your application is:
Hide Copy Code
PdfBookmark BookmarkRoot = Document.GetBookmarksRoot();
This step activates bookmarks in your document and returns the root node.
Adding bookmarks is similar to adding controls to a windows form. The first level bookmarks are added to the root. Subsequent levels are added to existing bookmarks. At minimum you have to define a title, page, vertical position on the page and an open entries flag. Page is the PdfPage object of the page to go to. YPos is the vertical position relative to the bottom left corner of the page. Open entries flag is true if the lower level bookmarks are visible and false if the lower level are hidden. The first level is always visible by default.
Hide Copy Code
PdfBookmark FirstLevel_1 = BookmarkRoot.AddBookmark("Chapter 1", Page, YPos, false);
PdfBookmark SecondLevel_11 = FirstLevel_1.AddBookmark("Section 1.1", Page, YPos, false);
PdfBookmark SecondLevel_12 = FirstLevel_1.AddBookmark("Section 1.2", Page, YPos, false);
PdfBookmark ThirdLevel_121 = SecondLevel_12.AddBookmark("Section 1.2.1", Page, YPos, false);
PdfBookmark ThirdLevel_122 = SecondLevel_12.AddBookmark("Section 1.2.2", Page, YPos, false);
PdfBookmark SecondLevel_13 = FirstLevel_1.AddBookmark("Section 1.3", Page, YPos, false);
PdfBookmark FirstLevel_2 = BookmarkRoot.AddBookmark("Chapter 2", Page, YPos, false);
PdfBookmark SecondLevel_21 = FirstLevel_2.AddBookmark("Section 2.1", Page, YPos, false);
PdfBookmark SecondLevel_22 = FirstLevel_2.AddBookmark("Section 2.2", Page, YPos, false);
AddBookmark() method has four overloading variations:
Hide Shrink
Copy Code
public PdfBookmark AddBookmark
(
String Title, PdfPage Page, Double YPos, Boolean OpenEntries )
public PdfBookmark AddBookmark
(
String Title, PdfPage Page, Double YPos, Color Paint, TextStyle TextStyle, Boolean OpenEntries )
public PdfBookmark AddBookmark
(
String Title, PdfPage Page, Double XPos, Double YPos, Double Zoom, Boolean OpenEntries )
public PdfBookmark AddBookmark
(
String Title, PdfPage Page, Double XPos, Double YPos, Double Zoom, Color Paint, TextStyle TextStyle, Boolean OpenEntries )
PdfBookmark class exposes one more method
GetChild. You can get any bookmark by calling
GetChild with one or more integer arguments. Each argument is a zero base argument of the child position in the level. For example
GetChild(2) is the third item of the first level.
GetChild(2, 3) is the forth second level item of the third first level item.
The PDF specification has no specific support for charting. The PDF File Writer library provides charting support by allowing the developer to create a Microsoft Charting object and draw this object as an image into the PDF file. For more information about Microsoft Chart control note MSDN library documentation
Visual Studio 2012 Chart Controls. The documentation for the charting name space is available at
Data Visualization Charting Namespace. The attached
ChartExample.cs has four examples of charts. If you intend to use charting, you need to add
System.Windows.Forms.Visualization reference to your project. In each source module using
Chart you need to add
using System.Windows.Forms.DataVisualization.Charting;.
Adding a chart to a PDF document is four steps process.
- Create Chart object.
- Create PdfChart object.
- Build the chart.
- Draw the PdfChart to PdfContents.
The recommended way to create a chart is to use a static method of
PdfChart object.
Hide Copy Code
Chart MyChart = PdfChart.CreateChart(PdfDocument Document, Double Width, Double Height, Double Resolution);
You can instantiate
Chart class yourself.
Hide Copy Code
Chart MyChart = new Chart();
MyChart.RenderingDpiY = 300; MyChart.Width = 1950; Mychart.Height = 1350;
Next you create a
PdfChart from the
Chart created above. Optionally, you can override the resolution.
Hide Copy Code
PdfChart MyPdfChart = new PdfChart(PdfDocument Document, Chart MyChart, Double Resolution);
Next you build your chart.
ChartExample.cs has four examples. The documentation for building a chart is beyond the scope of this article. There plenty of examples on the Internet.
PdfChart has a
CreateFont method to simplify the creation of fonts. It will calculate font size based on chart's resolution.
Hide Copy Code
Font CreateFont(String FontFamilyName, FontStyle Style, Double FontSize, FontSizeUnit Unit);
The last step is drawing the chart.
Hide Copy Code
public void PdfContents.DrawChart(PdfChart MyPdfChart, Double OrigX, Double OrigY);
public void PdfContents.DrawChart(PdfChart MyPdfChart, Double OrigX, Double OrigY, Double Width, Double Height);
The
PdfChart class provides some optional methods to control image positioning.
The
ImageSize method returns the largest rectangle with correct aspect ratio that will fit in a given area.
Hide Copy Code
SizeD ImageSize(Double Width, Double Height);
The
ImageSizePosition method returns the largest rectangle with correct aspect ratio that will fit in a given area and position it based on
ContentAlignmentenumeration.
Hide Copy Code
ImageSizePos ImageSizePosition(Double Width, Double Height, ContentAlignment Alignment);
Print document support allows you to print a report in the same way as printing to a printer and producing a PDF document. The difference between this method of producing a PDF file and using
PdfContents to produce a PDF file is the difference between raster graphics to vector graphics. Print document support creates one jpeg image per page.
PrintExample.cs has an example of creating a three page document.
Normally each page is a full image of the page. If your page is letter size and the resolution is 300 pixels per inch, each pixel is 3 bytes, the bit map of the page will be 25.245MB long.
PrintPdfDocument has a method
CropRect that can reduce the size of the bit map significantly. Assuming a one inch margin is used, the active size of the bit map will be reduced to 15.795 MB. That is 37.4% reduction.
Hide Shrink
Copy Code
Document = new PdfDocument(PaperType.Letter, false, UnitOfMeasure.Inch);
PrintPdfDocument Print = new PrintPdfDocument(Document, 300.0);
Print.PrintPage += PrintPage;
Print.SetMargins(1.0, 1.0, 1.0, 1.0);
Print.CropRect = new RectangleF(0.95F, 0.95F, 6.6F, 9.1F);
Print.AddPagesToPdfDocument();
Print.Dispose();
Document.CreateFile(FileName);
Example of PrintPage method
Hide Shrink
Copy Code
public void PrintPage(object sender, PrintPageEventArgs e)
{
Graphics G = e.Graphics;
G.SmoothingMode = SmoothingMode.HighQuality;
G.InterpolationMode = InterpolationMode.HighQualityBicubic;
G.PixelOffsetMode = PixelOffsetMode.HighQuality;
G.CompositingQuality = CompositingQuality.HighQuality;
Rectangle PrintArea = e.MarginBounds;
G.DrawRectangle(Pens.DarkBlue, PrintArea);
Int32 LineHeight = DefaultFont.Height + 8;
Rectangle TextRect = new Rectangle(PrintArea.X + 4, PrintArea.Y + 4, PrintArea.Width - 8, LineHeight);
String text = String.Format("Page Bounds: Left {0}, Top {1}, Right {2}, Bottom {3}",
e.PageBounds.Left, e.PageBounds.Top, e.PageBounds.Right, e.PageBounds.Bottom);
G.DrawString(text, DefaultFont, Brushes.Black, TextRect);
TextRect.Y += LineHeight;
text = String.Format("Page Margins: Left {0}, Top {1}, Right {2}, Bottom {3}",
PrintArea.Left, PrintArea.Top, PrintArea.Right, PrintArea.Bottom);
G.DrawString(text, DefaultFont, Brushes.Black, TextRect);
TextRect.Y += LineHeight;
for(Int32 LineNo = 1; ; LineNo++)
{
text = String.Format("Page {0}, Line {1}", PageNo, LineNo);
G.DrawString(text, DefaultFont, Brushes.Black, TextRect);
TextRect.Y += LineHeight;
if(TextRect.Bottom > PrintArea.Bottom) break;
}
PageNo++;
e.HasMorePages = PageNo <= 3;
return;
}
The data table classes allow you to display data tables in your PDF document.
PdfTable is the main class controlling the display of one table. A table is made out of a header row and data rows. Each row is divided into cells.
PdfTableCell controls the display of one header cell or one data cell. If header is used it will be displayed at the top of the table. Optionally it will be displayed at the top of each additional page. To display data in a cell, you load the data into the
Valueproperty of
PdfTableCell. Data can be: text string, basic numeric value, Boolean, Char, TextBox, image, QR code or barcode. Independently of data, you can load the cell with web link. Clicking anywhere within the cell's area will cause the PDF reader to activate web explorer and call the requested page. The display of the data is controlled by
PdfTableStyle class.
PdfTable class contains a default cell style and a default header style. You can override the default styles with private styles within
PdfTableCell. To display a table you create a
PdfTable object. Next you initialize the table, header cells, data cells and styles objects. Finally you set a loop and load the cell values of one row and then draw this row. This loop continues until all data was displayed. Below you will find the necessary sequence of steps to produce a table.
Create a PdfTable object.
Hide Copy Code
PdfTable Table = new PdfTable(Page, Contents, Font, FontSize);
Page is the current PdfPage. Contents is the current PdfContents. Font is the table default font. FontSize is the default font size in points.
Define table's area on the page.
Hide Copy Code
Table.TableArea = new PdfRectangle(Left, Bottom, Right, Top);
Table.RowTopPosition = StartingTopPosition;
The four arguments are the four sides of the table relative to bottom left corner and in user units. If on the first page the table top position is not at the top of the page set
RowTopPosition to the starting top position. On subsequent pages the table will always start at the top. If
TableArea is not specified, the library will set it to default page size less 1 inch margin.
Divide the table width into columns.
Hide Copy Code
StockTable.SetColumnWidth(Width1, Width2, Width3, ...);
The number of arguments is the number of columns. The table width less total border lines will be divided in proportion to these arguments.
Once the number of columns is set with
SetColumnWidth method the library creates two
PdfTableCell arrays. One array for header cells and one array for data cells.
Rows and columns of the data table can be separated by border lines. Border lines properties are defined by
PdfTableBorder and
PdfTableBorderStyle. There are four horizontal border lines:
TopBorder,
BottomBorder,
HeaderHorBorder between the header row and first data row and
CellHorBorder between data rows. There are two sets of vertical border lines:
HeaderVertBorder array for vertical border lines within the header row, and
CellVertBorder array for vertical border lines between columns within the data part of the table. Arrays size is the number of columns plus one. Array element zero is the table's left border. Array element Columns is the table's right border. All other elements are lines separating columns. Each of these lines can be defined individually. There are methods to define all border lines at once or define each individual border line.
Methods to define all border lines:
Hide Copy Code
Table.Borders.ClearAllBorders();
Table.Borders.SetDefaultBorders();
Table.Borders.SetAllBorders(Double Width);
Table.Borders.SetAllBorders(Double Width, Color LineColor);
Table.Borders.SetAllBorders(Double FrameWidth, Double GridWidth);
Table.Borders.SetAllBorders(Double FrameWidth, Color FrameColor, Double GridWidth, Color GridColor);
Table.Borders.SetFrame(Double Width);
Table.Borders.SetFrame(Double Width, Color LineColor);
Each horizontal border line can be cleared or set. The example is for top border line:
Hide Copy Code
Table.Borders.ClearTopBorder();
Table.Borders.SetTopBorder(Double LineWidth);
Table.Borders.SetTopBorder(Double LineWidth, Color LineColor);
Each vertical border line can be cleared or set. The example is for cell's vertical border lines:
Hide Copy Code
Table.Borders.ClearCellVertBorder(Int32 Index);
Table.Borders.SetCellVertBorder(Int32 Index, Double LineWidth);
Table.Borders.SetCellVertBorder(Int32 Index, Double LineWidth, Color LineColor);
Set other optional table properties. The values given in the example below are the defaults.
Hide Copy Code
HeaderOnEachPage = true;
MinRowHeight = 0.0;
Table information is processed one row at a time. Each row is made of cells. One cell per column. The display of cell's information is controlled by
PdfTableStyleclass. There are about 20 style properties. For the complete list view the source code or the help file. Some of these styles are specific to the type of information to be displayed. Here is an example
Hide Copy Code
Table.DefaultHeaderStyle.Alignment = ContentAlignment.BottomRight;
Table.Header[0].Style = Table.HeaderStyle;
Table.Header[0].Style.Alignment = ContentAlignment.MiddleLeft;
Table.Header[0].Value = "Date";
Table.DefaultCellStyle.Alignment = ContentAlignment.MiddleRight;
Table.DefaultCellStyle.Format = "#,##0.00";
Table.Cell[0].Style = StockTable.CellStyle;
Table.Cell[0].Style.Alignment = ContentAlignment.MiddleLeft;
Table.Cell[0].Style.Format = null;
After initialization is done it is time to display the data. The example below is from
TableExample.cs. It is a table of stock prices. There are 6 columns.
Hide Copy Code
StreamReader Reader = new StreamReader("SP500.csv");
Reader.ReadLine();
for(;;)
{
String TextLine = Reader.ReadLine();
if(TextLine == null) break;
String[] Fld = TextLine.Split(new Char[] {','});
Table.Cell[ColDate].Value = Fld[ColDate];
Table.Cell[ColOpen].Value = Double.Parse(Fld[ColOpen], NFI.PeriodDecSep);
Table.Cell[ColHigh].Value = Double.Parse(Fld[ColHigh], NFI.PeriodDecSep);
Table.Cell[ColLow].Value = Double.Parse(Fld[ColLow], NFI.PeriodDecSep);
Table.Cell[ColClose].Value = Double.Parse(Fld[ColClose], NFI.PeriodDecSep);
Table.Cell[ColVolume].Value = Int32.Parse(Fld[ColVolume]);
StockTable.DrawRow();
}
StockTable.Close();
Web link Example.
Hide Copy Code
BookList.Cell[6].Value = new PdfQRCode(Document, WeblinkString, ErrorCorrection.M);
BookList.Cell[6].WebLink = WebLinkString;
For more examples of data table source code look into
ArticleExample.cs and
TableExample.cs. For more detail documentation of
PdfTable,
PdfTableCell,
PdfTableStyle and
PdfTableBorder classes look into
PdfFileWriter.chm help file.
The
PdfFileWriter supports embedding video files in the PDF document. Full examples of playing video files are given in the page 7 of
OtherExample.cs. Adding a video file requires the use of three classes. First you need to embed the video file in the PDF document.
Hide Copy Code
PdfEmbeddedFile VideoFile = new PdfEmbeddedFile(Document, "LooneyTunes.mp4");
Second you need to define how the video is to be played. The
PdfDisplayMedia class has a number of methods to control the video display. Please refer to the class' source code and the documentation help file. For example:
RepeatCount or
ScaleMedia. If you want to play the video in a floating window you must use
SetMediaWindow method.
Hide Copy Code
PdfDisplayMedia DisplayMedia = new PdfDisplayMedia(VideoFile);
Third you need to define the area on the PDF page that the user must click in order to activate the video. If you want to activate the video when the annotation area is visible, use
ActivateActionWhenPageIsVisible.
Hide Copy Code
PdfAnnotation Annotation = new PdfAnnotation(Page, AnnotRect, DisplayMedia);
PdfXObject XObject = new PdfXObject(Document, AnnotRect.Width, AnnotRect.Height);
XObject.DrawText(ArialNormal, 14.0, 0.5 * AnnotRect.Width, 0.5 * AnnotRect.Height, TextJustify.Center, "Click here to play the video");
Annotation.Appearance(XObject);
The
PdfFileWriter supports embedding sound files in the PDF document. Full example of playing sound file is given in the page 7 of
OtherExample.cs. Embedding sound files is essentially the same as video files. The only obvious difference is that there is nothing to display.
Hide Copy Code
PdfEmbeddedFile EmbeddedMediaFile = new PdfEmbeddedFile(Document, "Ring01.wav");
PdfDisplayMedia DisplayMedia = new PdfDisplayMedia(EmbeddedMediaFile);
DisplayMedia.SetMediaWindow(MediaWindow.Hidden);
Double TextWidth = Contents.DrawText(ArialNormal, 12.0, TextPosX, TextPosY, TextJustify.Center, "Click this text to play sound");
PdfRectangle AnnotRect = new PdfRectangle(TextPosX - 0.5 * TextWidth, TextPosY - ArialNormal.DescentPlusLeading(12.0),
TextPosX + 0.5 * TextWidth, TextPosY + ArialNormal.AscentPlusLeading(12.0));
PdfAnnotation Annotation = new PdfAnnotation(Page, AnnotRect, DisplayMedia);
The
PdfFileWriter supports embedding data files in the PDF document. Full example of embedding file is given in the page 7 of
OtherExample.cs. The user can save the files or display the files.
Hide Copy Code
EmbeddedFile = new PdfEmbeddedFile(Document, "BookList.txt");
PdfRectangle AnnotRect = new PdfRectangle(IconPosX, IconPosY, IconPosX + IconWidth, IconPosY + IconHeight);
PdfAnnotation Annotation = new PdfAnnotation(Page, AnnotRect, EmbeddedFile, FileAttachIcon.Paperclip);
The
PdfFileWriter appends new pages to the end of the page list. If you want to move a page from its current position to a new position use the following method.
Hide Copy Code
Document.MovePage(Int32 SourceIndex, Int32 DestinationIndex);
Integrating
PdfFileWriter to your application requires the following steps. Install the attached
PdfFileWriter.dll file in your development area. Start the Visual C# program and open your application. Go to the Solution Explorer, right click on References and select Add Reference. Select the Browse tab and navigate your file system to the location of the
PdfFileWriter.dll. When your application is published, the code>PdfFileWriter.dll must be included.
Source code documentation is available in as a help file
PdfFileWriter.chm. The file is produced by Sandcastle. The result looks like Microsoft documentation pages.
If you want access to the source code of the
PdfFileWriter project, install the
PdfFileWriter project in your development area. The
PdfFileWriter.dll will be in
PdfFileWriter\bin\Release directory.
Add the following statement to all source modules using this library.
Hide Copy Code
using PdfFileWriter;
If you intend to use charting, you need to add reference to:
System.Windows.Forms.Visualization. In each source module using
Chart you need to add
Hide Copy Code
using System.Windows.Forms.DataVisualization.Charting;
This section describes the integration of the PDF File Writer C# class library to your application. The test program
TestPdfFileWriter program is a simulation of your own application. When you press on the “Article Example” button, the program executes the code in
ArticleExample.cs source file. The image above displays the resulted PDF file. This method demonstrates the creation of one page document with some text and graphics. After going through this example, you should have a good understanding of the process. The other example buttons produce a variety of PDF documents. In total, practically every feature of this library is demonstrated by these examples.
The Debug check box, if checked, will create a PDF file that can be viewed with a text editor but cannot be loaded to a PDF reader. The resulted file is not compressed and images and font file are replaced with text place holder. The Debug check box should be used for debugging only.
The TestPdfFileWriter program was developed using Microsoft Visual C# 2012. It was tested for Windows XP, Vista, 7 and 8.
The Test method below demonstrates the six steps described in the introduction for creating a PDF file. The method will be executed when you press on the “Article Example” button of the demo program. The following subsections describe in detail each step.
Hide Shrink
Copy Code
public void Test(Boolean Debug, String FileName)
{
Document = new PdfDocument(PaperType.Letter, false, UnitOfMeasure.Inch, FileName);
Document.Debug = Debug;
DefineFontResources();
DefineTilingPatternResource();
Page = new PdfPage(Document);
Contents = new PdfContents(Page);
DrawFrameAndBackgroundWaterMark();
DrawTwoLinesOfHeading();
DrawHappyFace();
DrawBarcode();
DrawBrickPattern();
DrawImage();
DrawHeart();
DrawChart();
DrawTextBox();
DrawBookOrderForm();
Document.CreateFile();
Process Proc = new Process();
Proc.StartInfo = new ProcessStartInfo(FileName);
Proc.Start();
return;
}
The
DefineFontResources method creates all the font resources used in this example. In addition, you will find an example of one character substitution. Arial character 9679 (decimal) is a full circle glyph is being mapped into character 164 (decimal). The full circle glyph is used as a separator within the text at the bottom left of the PDF example document. To see all the characters available for any font, press the third button “Font Families”. Select a family and view the glyphs defined for each character. To view individual glyph press view or double click.
Hide Shrink
Copy Code
private void DefineFontResources()
{
String FontName1 = "Arial";
String FontName2 = "Times New Roman";
ArialNormal = new PdfFont(Document, FontName1, FontStyle.Regular, true);
ArialBold = new PdfFont(Document, FontName1, FontStyle.Bold, true);
ArialItalic = new PdfFont(Document, FontName1, FontStyle.Italic, true);
ArialBoldItalic = new PdfFont(Document, FontName1, FontStyle.Bold | FontStyle.Italic, true);
TimesNormal = new PdfFont(Document, FontName2, FontStyle.Regular, true);
Comic = new PdfFont(Document, "Comic Sans MS", FontStyle.Bold, true);
ArialNormal.CharSubstitution(9679, 9679, 161); ArialNormal.CharSubstitution(1488, 1514, 162); ArialNormal.CharSubstitution(1040, 1045, 189); ArialNormal.CharSubstitution(945, 950, 195); return;
}
The
DefineTilingPatternResource method defines background pattern resource for the example area. The pattern is the word “PdfFileWriter” in white over light blue background. The pattern is made of two lines of repeating the key word. The two lines are skewed by half word length.
If you want to find interesting patterns, search the internet for catalogs of companies making floor or wall tiles.
Hide Shrink
Copy Code
private void DefineTilingPatternResource()
{
WaterMark = new PdfTilingPattern(Document);
String Mark = "PdfFileWriter";
Double FontSize = 18.0;
Double TextWidth = ArialBold.TextWidth(FontSize, Mark);
Double TextHeight = ArialBold.LineSpacing(FontSize);
Double BaseLine = ArialBold.DescentPlusLeading(FontSize);
Double BoxWidth = TextWidth + 2 * TextHeight;
Double BoxHeight = 4 * TextHeight;
WaterMark.SetTileBox(BoxWidth, BoxHeight);
WaterMark.SaveGraphicsState();
WaterMark.SetColorNonStroking(Color.FromArgb(230, 244, 255));
WaterMark.DrawRectangle(0, 0, BoxWidth, BoxHeight, PaintOp.Fill);
WaterMark.SetColorNonStroking(Color.White);
WaterMark.DrawText(ArialBold, FontSize, BoxWidth / 2, BaseLine, TextJustify.Center, Mark);
BaseLine += BoxHeight / 2;
WaterMark.DrawText(ArialBold, FontSize, 0.0, BaseLine, TextJustify.Center, Mark);
WaterMark.DrawText(ArialBold, FontSize, BoxWidth, BaseLine, TextJustify.Center, Mark);
WaterMark.RestoreGraphicsState();
return;
}
The
DrawFrameAndBackgroundWaterMark method draws a frame around the example area with background water mark pattern. The pattern resource was define in the previous subsection.
Hide Shrink
Copy Code
private void DrawFrameAndBackgroundWaterMark()
{
Contents.SaveGraphicsState();
Contents.SetLineWidth(0.02);
Contents.SetColorStroking(Color.DarkBlue);
Contents.SetPatternNonStroking(WaterMark);
Contents.DrawRectangle(1.0, 1.0, 6.5, 9.0, PaintOp.CloseFillStroke);
Contents.RestoreGraphicsState();
Contents.DrawText(ArialNormal, 9.0, 1.1, 0.85, "PdfFileWriter \u25cf PDF File Writer C# Class Library \u25cf Author: Uzi Granot");
Contents.DrawWebLink(Page, ArialNormal, 9.0, 7.4, 0.85, TextJustify.Right, DrawStyle.Underline, Color.Blue, "Click to view article",
"http://www.codeproject.com/Articles/570682/PDF-File-Writer-Csharp-Class-Library-Version");
return;
}
3.5. Draw Two Lines of Heading
The
DrawTwoLinesOfHeading method draws two heading lines at the center of the page. The first line is drawing text with outline special effect.
Hide Copy Code
private void DrawTwoLinesOfHeading()
{
Contents.DrawText(Comic, 40.0, 4.25, 9.25, TextJustify.Center, 0.02, Color.FromArgb(128, 0, 255), Color.FromArgb(255, 0, 128), "PDF FILE WRITER");
Contents.SaveGraphicsState();
Contents.SetColorNonStroking(Color.Purple);
Contents.DrawText(Comic, 30.0, 4.25, 8.75, TextJustify.Center, "Example");
Contents.RestoreGraphicsState();
return;
}
3.6. Draw Happy Face
The
DrawHappyFace method is an example of drawing oval and constructing path from a line and Bezier curve.
Hide Shrink
Copy Code
private void DrawHappyFace()
{
Contents.SaveGraphicsState();
Contents.Translate(4.25, 7.5);
Contents.SetColorNonStroking(Color.Yellow);
Contents.DrawOval(-1.5, -1.0, 3.0, 2.0, PaintOp.Fill);
Contents.SetLineWidth(0.2);
Contents.SetColorNonStroking(Color.White);
Contents.SetColorStroking(Color.Black);
Contents.DrawOval(-0.75, 0.0, 0.5, 0.5, PaintOp.CloseFillStroke);
Contents.DrawOval(0.25, 0.0, 0.5, 0.5, PaintOp.CloseFillStroke);
Contents.SetColorNonStroking(Color.Black);
Contents.MoveTo(-0.6, -0.4);
Contents.LineTo(0.6, -0.4);
Contents.DrawBezier(0.0, -0.8, 0, -0.8, -0.6, -0.4);
Contents.SetPaintOp(PaintOp.Fill);
Contents.RestoreGraphicsState();
return;
}
The
DrawBarcode method is an example of drawing two barcodes EAN-13 and Code-128
Hide Copy Code
private void DrawBarcode()
{
Contents.SaveGraphicsState();
BarcodeEAN13 Barcode1 = new BarcodeEAN13("1234567890128");
Contents.DrawBarcode(1.3, 7.05, 0.012, 0.75, Barcode1, ArialNormal, 8.0);
PdfQRCode QRCode = new PdfQRCode(Document, "http://www.codeproject.com/Articles/570682/PDF-File-Writer-Csharp-Class-Library-Version", ErrorCorrection.M);
Contents.DrawQRCode(QRCode, 6.0, 6.8, 1.2);
Page.AddWebLink(6.0, 6.8, 7.2, 8.0, "http://www.codeproject.com/Articles/570682/PDF-File-Writer-Csharp-Class-Library-Version");
Contents.RestoreGraphicsState();
return;
}
The
DrawBrickPattern method draws a rectangle with rounded corners. The area is filled with a brick pattern. The
PdfTillingPattern class is a general class to define tiling patterns. The class has two static methods to create specific patterns.
SetBrickPattern to draw a brick wall pattern and
SetWeavePattern to draw a weaving pattern.
Hide Copy Code
private void DrawBrickPattern()
{
PdfTilingPattern BrickPattern = PdfTilingPattern.SetBrickPattern(Document, 0.25, Color.LightYellow, Color.SandyBrown);
Contents.SaveGraphicsState();
Contents.SetLineWidth(0.04);
Contents.SetColorStroking(Color.Purple);
Contents.SetPatternNonStroking(BrickPattern);
Contents.DrawRoundedRectangle(1.1, 5.0, 1.4, 1.5, 0.2, PaintOp.CloseFillStroke);
Contents.RestoreGraphicsState();
return;
}
The
DrawI
mage method is an example of drawing an image. The
PdfFileWriter support drawing images stored in all image files supported by
Bitmap class and
Metafile class. The
ImageFormat class defines all image types. The JPEG image file type is the native image format of the PDF file. If you call the
PdfImageconstructor with JPEG file, the program copies the file as is into the PDF file. If you call the
PdfImage constructor with any other type of image file, the program converts it into JPEG file. In order to keep the PDF file size as small as possible, make sure your image file resolution is not unreasonably high.
The
PdfImage class loads the image and calculates maximum size that can fit a given image size in user coordinates and preserve the original aspect ratio. Before drawing the image we create an oval clipping path to clip the image.
Hide Copy Code
private void DrawImage()
{
PdfImage Image1 = new PdfImage(Document, "TestImage.jpg", 96.0, 50);
Contents.SaveGraphicsState();
Contents.Translate(2.6, 5.0);
ImageSizePos NewSize = Image1.ImageSizePosition(1.75, 1.5, ContentAlignment.MiddleCenter);
Contents.DrawOval(NewSize.DeltaX, NewSize.DeltaY, NewSize.Width, NewSize.Height, PaintOp.ClipPathEor);
Contents.DrawImage(Image1, NewSize.DeltaX, NewSize.DeltaY, NewSize.Width, NewSize.Height);
Contents.RestoreGraphicsState();
return;
}
The
DrawHeart method displays a heart shape by defining the two ends of the center line. The
DrawHeart method of the
PdfContents class is a special case of drawing two symmetric Bezier curves forming a path.
Hide Copy Code
private void DrawHeart()
{
Contents.SaveGraphicsState();
Contents.SetColorNonStroking(Color.HotPink);
Contents.DrawHeart(new LineD(new PointD(4.98, 5.1), new PointD(4.98, 6.0)), PaintOp.CloseFillStroke);
Contents.RestoreGraphicsState();
return;
}
The
DrawChart method is an example of defining a chart and drawing it to the PDF document.
Hide Shrink
Copy Code
private void DrawChart()
{
Contents.SaveGraphicsState();
Chart PieChart = PdfChart.CreateChart(Document, 1.8, 1.5, 300.0);
PdfChart PiePdfChart = new PdfChart(Document, PieChart);
PieChart.AntiAliasing = AntiAliasingStyles.All;
PieChart.BackColor = Color.FromArgb(220, 220, 255);
PieChart.Palette = ChartColorPalette.BrightPastel;
Font DefaultFont = MyPdfChart.CreateFont("Verdana", FontStyle.Regular, 0.05, FontSizeUnit.UserUnit);
Font TitleFont = MyPdfChart.CreateFont("Verdana", FontStyle.Bold, 0.07, FontSizeUnit.UserUnit);
Title Title1 = new Title("Pie Chart Example", Docking.Top, TitleFont, Color.Purple);
PieChart.Titles.Add(Title1);
Legend Legend1 = new Legend();
PieChart.Legends.Add(Legend1);
Legend1.BackColor = Color.FromArgb(230, 230, 255);
Legend1.Docking = Docking.Bottom;
Legend1.Font = DefaultFont;
ChartArea ChartArea1 = new ChartArea();
PieChart.ChartAreas.Add(ChartArea1);
ChartArea1.BackColor = Color.FromArgb(255, 200, 255);
Series Series1 = new Series();
PieChart.Series.Add(Series1);
Series1.ChartType = SeriesChartType.Pie;
Series1.Font = DefaultFont;
Series1.IsValueShownAsLabel = true;
Series1.LabelFormat = "{0} %";
Series1.Points.Add(22.0);
Series1.Points[0].LegendText = "Apple";
Series1.Points.Add(27.0);
Series1.Points[1].LegendText = "Banana";
Series1.Points.Add(33.0);
Series1.Points[2].LegendText = "Orange";
Series1.Points.Add(18.0);
Series1.Points[3].LegendText = "Grape";
Contents.DrawChart(MyPdfChart, 5.6, 5.0);
Contents.RestoreGraphicsState();
return;
}
The
DrawTextBox method is an example of using the
TextBox class. The
TextBox class formats text to fit within a column. The text can be drawn using a verity of font's styles and sizes.
Hide Shrink
Copy Code
private void DrawTextBox()
{
Contents.SaveGraphicsState();
Contents.Translate(1.1, 1.1);
const Double Width = 3.15;
const Double Height = 3.65;
const Double FontSize = 9.0;
TextBox Box = new TextBox(Width, 0.25);
Box.AddText(ArialNormal, FontSize,
"This area is an example of displaying text that is too long to fit within a fixed width " +
"area. The text is displayed justified to right edge. You define a text box with the required " +
"width and first line indent. You add text to this box. The box will divide the text into " +
"lines. Each line is made of segments of text. For each segment, you define font, font " +
"size, drawing style and color. After loading all the text, the program will draw the formatted text.\n");
Box.AddText(TimesNormal, FontSize + 1.0, "Example of multiple fonts: Times New Roman, ");
Box.AddText(Comic, FontSize, "Comic Sans MS, ");
Box.AddText(ArialNormal, FontSize, "Example of regular, ");
Box.AddText(ArialBold, FontSize, "bold, ");
Box.AddText(ArialItalic, FontSize, "italic, ");
Box.AddText(ArialBoldItalic, FontSize, "bold plus italic. ");
Box.AddText(ArialNormal, FontSize - 2.0, "Arial size 7, ");
Box.AddText(ArialNormal, FontSize - 1.0, "size 8, ");
Box.AddText(ArialNormal, FontSize, "size 9, ");
Box.AddText(ArialNormal, FontSize + 1.0, "size 10. ");
Box.AddText(ArialNormal, FontSize, DrawStyle.Underline, "Underline, ");
Box.AddText(ArialNormal, FontSize, DrawStyle.Strikeout, "Strikeout. ");
Box.AddText(ArialNormal, FontSize, "Subscript H");
Box.AddText(ArialNormal, FontSize, DrawStyle.Subscript, "2");
Box.AddText(ArialNormal, FontSize, "O. Superscript A");
Box.AddText(ArialNormal, FontSize, DrawStyle.Superscript, "2");
Box.AddText(ArialNormal, FontSize, "+B");
Box.AddText(ArialNormal, FontSize, DrawStyle.Superscript, "2");
Box.AddText(ArialNormal, FontSize, "=C");
Box.AddText(ArialNormal, FontSize, DrawStyle.Superscript, "2");
Box.AddText(ArialNormal, FontSize, "\n");
Box.AddText(Comic, FontSize, Color.Red, "Some color, ");
Box.AddText(Comic, FontSize, Color.Green, "green, ");
Box.AddText(Comic, FontSize, Color.Blue, "blue, ");
Box.AddText(Comic, FontSize, Color.Orange, "orange, ");
Box.AddText(Comic, FontSize, DrawStyle.Underline, Color.Purple, "and purple.\n");
Box.AddText(ArialNormal, FontSize, "Support for non-Latin letters: ");
Box.AddText(ArialNormal, FontSize, Contents.ReverseString( "עברית"));
Box.AddText(ArialNormal, FontSize, "АБВГДЕ");
Box.AddText(ArialNormal, FontSize, "αβγδεζ");
Box.AddText(ArialNormal, FontSize, "\n");
Double PosY = Height;
Contents.DrawText(0.0, ref PosY, 0.0, 0, 0.015, 0.05, TextBoxJustify.FitToWidth, Box);
Box = new TextBox(Width);
Box.AddText(ArialNormal, FontSize,
"In the examples above this area the text box was set for first line indent of " +
"0.25 inches. This paragraph has zero first line indent and no right justify.");
Contents.DrawText(0.0, ref PosY, 0.0, 0, 0.01, 0.05, TextBoxJustify.Left, Box);
Box = new TextBox(Width - 0.5, -0.5);
Box.AddText(ArialNormal, FontSize,
"This paragraph is set to first line hanging indent of 0.5 inches. " +
"The left margin of this paragraph is 0.5 inches.");
Contents.DrawText(0.5, ref PosY, 0.0, 0, 0.01, 0.05, TextBoxJustify.Left, Box);
Contents.RestoreGraphicsState();
return;
}
The
DrawBookOrderForm method is an example of an order entry form or an invoice. It is an example for data table support. It demonstrate the use of
PdfTable,
PdfTableCell and
PdfTableStyle classes.
Hide Shrink
Copy Code
private void DrawBookOrderForm()
{
const Double Left = 4.35;
const Double Top = 4.65;
const Double Bottom = 1.1;
const Double Right = 7.4;
const Double FontSize = 9.0;
const Double MarginHor = 0.04;
const Double MarginVer = 0.04;
const Double Border = 0.015;
const Double Grid = 0.01;
Double ColWidthPrice = ArialNormal.TextWidth(FontSize, "9999.99") + 2.0 * MarginHor;
Double ColWidthQty = ArialNormal.TextWidth(FontSize, "Qty") + 2.0 * MarginHor;
Double ColWidthDesc = Right - Left - Border - 3 * Grid - 2 * ColWidthPrice - ColWidthQty;
PdfTable Table = new PdfTable(Page, Contents, ArialNormal, FontSize);
Table.TableArea = new PdfRectangle(Left, Bottom, Right, Top);
Table.SetColumnWidth(new Double[] {ColWidthDesc, ColWidthPrice, ColWidthQty, ColWidthPrice});
Table.Borders.SetAllBorders(FrameWidth, GridWidth);
PdfRectangle Margin = new PdfRectangle(MarginHor, MarginVer);
Table.DefaultHeaderStyle.Margin = Margin;
Table.DefaultHeaderStyle.BackgroundColor = Color.FromArgb(255, 196, 255);
Table.DefaultHeaderStyle.Alignment = ContentAlignment.MiddleRight;
Table.Header[0].Style = Table.HeaderStyle;
Table.Header[0].Style.Alignment = ContentAlignment.MiddleLeft;
Table.Header[0].Value = "Description";
Table.Header[1].Value = "Price";
Table.Header[2].Value = "Qty";
Table.Header[3].Value = "Total";
Table.DefaultCellStyle.Margin = Margin;
Table.Cell[0].Style = Table.CellStyle;
Table.Cell[0].Style.MultiLineText = true;
Table.Cell[2].Style = Table.CellStyle;
Table.Cell[2].Style.Alignment = ContentAlignment.BottomRight;
Table.DefaultCellStyle.Format = "#,##0.00";
Table.DefaultCellStyle.Alignment = ContentAlignment.BottomRight;
Contents.DrawText(ArialBold, FontSize, 0.5 * (Left + Right), Top + MarginVer + Table.DefaultCellStyle.FontDescent,
TextJustify.Center, DrawStyle.Normal, Color.Purple, "Example of PdfTable support (new for 1.10.0)");
Double Total = 0;
foreach(Order Book in Order.OrderList)
{
Table.Cell[0].Value = Book.Title + ". By: " + Book.Authors;
Table.Cell[1].Value = Book.Price;
Table.Cell[2].Value = Book.Qty;
Table.Cell[3].Value = Book.Total;
Table.DrawRow();
Total += Book.Total;
}
Table.Close();
Contents.SaveGraphicsState();
Contents.SetLineWidth(FrameWidth);
Contents.SetLineCap(PdfLineCap.Square);
Double[] ColumnPosition = Table.ColumnPosition;
Double TotalDesc = ColumnPosition[3] - MarginHor;
Double TotalValue = ColumnPosition[4] - MarginHor;
Double PosY = Table.RowTopPosition - 2.0 * MarginVer - Table.DefaultCellStyle.FontAscent;
Contents.DrawText(ArialNormal, FontSize, TotalDesc, PosY, TextJustify.Right, "Total before tax");
Contents.DrawText(ArialNormal, FontSize, TotalValue, PosY, TextJustify.Right, Total.ToString("#.00"));
PosY -= Table.DefaultCellStyle.FontLineSpacing;
Contents.DrawText(ArialNormal, FontSize, TotalDesc, PosY, TextJustify.Right, "Tax (13%)");
Double Tax = Math.Round(0.13 * Total, 2, MidpointRounding.AwayFromZero);
Contents.DrawText(ArialNormal, FontSize, TotalValue, PosY, TextJustify.Right, Tax.ToString("#.00"));
PosY -= Table.DefaultCellStyle.FontDescent + 0.5 * MarginVer;
Contents.DrawLine(ColumnPosition[3], PosY, ColumnPosition[4], PosY);
PosY -= Table.DefaultCellStyle.FontAscent + 0.5 * MarginVer;
Contents.DrawText(ArialNormal, FontSize, TotalDesc, PosY, TextJustify.Right, "Total payable");
Total += Tax;
Contents.DrawText(ArialNormal, FontSize, TotalValue, PosY, TextJustify.Right, Total.ToString("#.00"));
PosY -= Table.DefaultCellStyle.FontDescent + MarginVer;
Contents.DrawLine(ColumnPosition[0], Table.RowTopPosition, ColumnPosition[0], PosY);
Contents.DrawLine(ColumnPosition[0], PosY, ColumnPosition[4], PosY);
Contents.DrawLine(ColumnPosition[4], Table.RowTopPosition, ColumnPosition[4], PosY);
Contents.RestoreGraphicsState();
return;
}
4. References
5. Other Open Source Software by This Author
6. History
- 2013/04/01: Version 1.0 Original Version.
- 2013/04/09: Version 1.1 Support for countries with decimal separator other than period.
- 2013/07/21: Version 1.2 The original revision supported image resources with jpeg file format only. Version 1.2 support all image files acceptable to Bitmap class. See ImageFormat class. The program was tested with: Bmp, Gif, Icon, Jpeg, Png and Tiff. See Section 2.3 and Section 3.8 above.
- 2014/02/07: Version 1.3 Fix bug in PdfContents.DrawBezierNoP2(PointD P1, PointD P3).
- 2014/03/01: Version 1.4 Improved support for character substitution. Improved support for image inclusion. Some fixes related to PdfXObject.
- 2014/05/05: Version 1.5 Barcode support without use of fonts. Four barcodes are included: Code-128, Code-39, UPC-A and EAN-13. See Section 2.5 and Section 3.7.
- 2014/07/09: Version 1.6 (1) The CreateFile method resets the PdfDocument to initial condition after file creation. (2) The PdfFont object releases the unmanaged code resources properly.
- 2014/08/25: Version 1.7 Add support for document encryption, web-links and QR Code.
- 2014/09/12: Version 1.8 Add support for bookmarks.
- 2014/10/06: Version 1.9 Add support for charting, PrintDocument and image Metafiles.
- 2014/10/12: Version 1.9.1 Fix to ChartExample. Parse numeric fields in regions with decimal separator other than period.
- 2014/12/02: Version 1.10.0 Add support for data tables. Add source code documentation. Increase maximum number of images per document.
- 2015/01/12: Version 1.11.0 Add support for video, sound and attachment files. Add support for Interleave 2 of 5 barcode.
- 2015/04/13: Version 1.12.0 Add support for reordering pages and enhance data table border lines support.