Working With iTextSharp

March 16, 2018 | Author: Inox1978 | Category: Hyperlink, Portable Document Format, Typefaces, Html Element, Technology


Comments



Description

Create PDFs in ASP.NET / C# Michéle Johl Getting started with iTextSharp The .NET framework does not contain any native way to work with PDF files. So, if you want to generate or work with PDF files as part of your ASP.NET web application, you will have to rely on one of the many third party components that are available. Google will help you to find one that fits your budget, as well as a range of open-source free components. One of the free components is iTextSharp, which is a port of a well known Java utility, iText. The main problem with iTextSharp is that it lacks documentation. There are some basic tutorials available, but most programmers have to resort to trying to wrestle with the documentation provided for the Java version - iText - to get going with the component, or you may want to purchase the book iText In Action. However, this only provides guidance in Java. Many of the code samples are transferable to C# without a lot of modification, but if you are relatively new to C#, you may frequently become frustrated with undocumented or inexplicable differences in classes and method names between the two versions. As a final resort, you can always use Reflector to pick the dll apart and examine its innards. So, as part of a series of How To articles, here's how to get started using iTextSharp with code samples in C#. First thing to do is to download the component from here. You will be presented with a .zip file containing itextsharp.dll. Unzip this, and save it somewhere on your machine. Now create a new Web Site from within Visual Studio or Visual Web Developer. Make sure that you have added the Bin folder from the options in the Add ASP.NET Folder option. Right-click on the Bin folder and select Add Reference. The dialogue box should appear. Choose the Browse tab, and locate the dll you saved earlier. Then select it and click "OK". That's it. The dll will be copied to your Bin directory, and is now available to the web site or project. I have also added a folder called PDFs in which I plan to store my generated files. To avoid typing full references to the dll, it is best to add a couple of using statements to the default ones in your code-behind: using iTextSharp.text; using iTextSharp.text.pdf; You will also want to reference System.IO, as you will be creating, opening and closing files, and classes in this namespace are required. The principal object within iTextSharp is the Document object. You need to create an instance of this to be able to work with your PDF in memory. So, the first thing to do is to instantiate one: var doc1 = new Document(); This creates a PDF document object in memory with the default settings. The size of the document by default is A4 (which measures 210mm x 297mm, or 8.26 inches x 11.69 inches). Margins are set at half an inch all round. The next thing to do is to commit the document to disk. The iTextSharp.text.pdf.PdfWriter class is required for this: //use a variable to let my code fit across the page... string path = Server.MapPath("PDFs"); PdfWriter.GetInstance(doc1, new FileStream(path + "/Doc1.pdf", FileMode.Create)); Now to begin actually working with the document, open it, and add a new paragraph, then close it: doc1.Open(); doc1.Add(new Paragraph("My first PDF")); doc1.Close(); That's it! If you refresh the PDFs folder in your web site, you will see that a new item - Doc1.pdf has been added, and opening it will reveal your success. It may be, however, that you don't want to always create a PDF with the default size and margins, so iTextSharp provides ways for you to customise these settings. There are 2 further constructors to the Document object: public Document(iTextSharp.text.Rectangle pageSize); public Document(iTextSharp.text.Rectangle pageSize, float, float, float, float); The first one can be used like this: var doc = new Document(PageSize.A5); The PageSize class contains a number of Rectangle objects representing the most common paper sizes from A0 to A10, B0 to B10, LEGAL, LEDGER, LETTER, POSTCARD, TABLOID and so on. If you want to apply a custom size that isn't available within the PageSize class, you define your own Rectangle object, set its properties and pass that into the constructor as an argument: var doc = new Document(new Rectangle(100f, 300f)); PdfWriter.GetInstance(doc, new FileStream(path + "/Doc2.pdf", FileMode.Create)); doc.Open(); doc.Add(new Paragraph("This is a custom size")); doc.Close(); In this case, a PDF document was created with the width being 100 points, and the height set at 300 points. There are 72 points to an inch, so this particular document isn't very large. It's in fact 1.39 inches x 4.17 inches. (You will probably find that as well as iTextSharp.dll, a calculator will be very handy....). The second constructor which takes a Rectangle object and a series of 4 float values allows you to set your custom margins through the floats. Again, these values are measured in points. The default half inch margins are 36 points. If you use the PageSize class constructor, or a Rectangle directly, you can also set the background colour of the document. This can be done using RGB colour values, or CMYK (Cyan - a kind of blue, Magenta - a pinkish red, Yellow and "Key", or black). It used to be that if you wanted to prepare a PDF for printing by a professional lithographic printer, you had to ensure that all colours were CMYK, but with greater adoption of digital printing by printing companies, RGB is becoming more acceptable. Certainly, for display on the web, RGB is preferred. To set the background colour, we use the BackgroundColorproperty of the Rectangle object: Both of the above result in a rather fetching pinkish colour for the document. 0). 124). .r. 64. 90.BackgroundColor = new Color(191. r.BackgroundColor = new CMYKColor(25. 25. Working with Fonts . CreateFont() method. the free PDF utility that lets you work with PDF files within ASP. which includes all fonts found in the Windows default font directory. colour. Symbol. Helvetica Bold.ITALIC. BaseFont. int totalfonts = FontFactory. Helvetica Italic. embedding.CreateFont(BaseFont. while Times Roman has an equivalent in Times New Roman.TIMES_ROMAN.GetFont() returns a valid and new Font object that you can work with directly. Times Roman Italic. a new Font object is created. Helvetica Bold and Italic. and the third is to instantiate a new Font object. StringBuilder sb = new StringBuilder(). Times Roman Bold and Italic. On Win XP Pro. This method has 14 (count 'em!) overloads that allow you to specify anything from font family. The default font is Helvetica.GetInstance(doc. that's usually C:/WINDOWS/Fonts. iTextSharp has built-in support for the 14 Type 1 fonts: Courier. style. the second is to use the FontFactory.pdf".Open(). 12pt. There are three principal ways to set the font to work with: one is to use the BaseFont. Color.Add(new Paragraph("This is a Red Font Test using Times Roman". black in the style typically known as Normal.Close().again. But we will get BaseFont. Helvetica translates more or less to Windows Arial font. Each time that you call FontFactory. PdfWriter. or if you plan to get the PDF printed professionally. foreach (string fontname in FontFactory. doc.GetFont() method. This can be useful if you want to find the exact name of each font. ZapfDingBats®.Create)). doc. and only sets up the definition of a font. doc. Helvetica. Font times = new Font(bfTimes. A new Font object is created using the BaseFont object. this decreases the overall size of the document. new Font() allows for propogation of font styles from one font to the next. times)). Courier Italic.RegisteredFonts collection holds them. If you want a list of all the registered fonts. size. Courier Bold. Times Roman Bold. FontFactory. Now the font is put to use in a paragraph: string path = Server.GetFont() method . It also offers 14 overloaded constructors which gives you a lot more options to work with.MapPath("PDFs").GetFont() method. This method will work directly with all fonts registered by iTextSharp. I recommend that you do so now.RED). using iTextSharp's constants for these values. For that reason.NET.CreateFont() is a lot more limited. It also specifies false for embedding the font within the PDF document. new FileStream(path + "/Font. this article looks at working with fonts in PDF documents that you create. 12.RegisterDirectory("C:\\WINDOWS\\Fonts"). BaseFont bfTimes = BaseFont.Following on from my introduction to iTextSharp. and further setting the font size in points. false). encoding and caching in pretty much any combination you like.RegisteredFonts) { . And the result (if all goes well) is as follows: Now to the FontFactory. FileMode. Courier Bold and Italic. but should be set to true if you are using fonts that are unlikely to be on the user's system. Times Roman. The above lines create a BaseFont object and uses the built-in constant values to set the font family and encoding. Document doc = new Document().CP1252. Font. If you haven't read the first article in this series.GetFont().CreateFont() out of the way first. the style and the colour . the FontFactory. you are most likely going to use the FontFactory. BaseFont. string fontpath = Server.ITALIC.".ttf". Font font = new Font(customfont.Append(fontname + "\n"). Color.GetFont( "palatino linotype italique". 7).EMBEDDED. Font.GetFont("nina fett"). .Add(new Paragraph("All Fonts:\n" + sb. Registering Fonts You may have a situation where you cannot install a font you want to use in the default font directory on the web server. new Color(125.CP1252. but you can pass in an int representing one of the values.ToString())). Font. 15)). which ilustrates some of the different overloads available. while others use the SetColor() method and pass in RGB values or create a new Color object passing in RGB values.Add(new Paragraph(s. font)). Code Complete and the Object Browser will reveal the full panoply of options. 88. Generally. x.EMBEDDED)."). BaseFont customfont = BaseFont. Font palatino = FontFactory.GetFont("Arial".EMBEDDED).CreateFont(fontpath + "myspecial.GREEN ). As you can see.CP1252. 12).sb.GetFont("Arial". as your expensive font is unlikely to exist on users' operating systems. BaseFont. 16. 28.MapPath(". x. doc. BaseFont. string s = "My expensive custom font. BaseFont. some of them use the iTextSharp Color object to set the colour using a constant. Font x = FontFactory.GetFont("Verdana". You may notice that the above example is embedded in the PDF file (BaseFont. Here's a variety of ways to use the GetFont() method: Font arial = FontFactory.Size = 10.BOLDITALIC. x. BaseFont. 10. 200). 50. so you have to register it explicitly with iTextSharp. Color.SetColor(100. } doc.GRAY). or use the SetStyle() method passing in a string. Font verdana = FontFactory. There are also varying numbers of parameters passed. they use a constant value for the font style. Font smallfont = FontFactory.SetStyle("Italic"). Intellisense. Adding Text with Chunks. Phrases and Paragraphs . -1. As with the Label. Chunks have no concept of how to force a new line when the length exceeds the available width in the document. The following snippet shows how to set the text of a Chunk. The chunk has a number of methods to allow you to do this. FileMode.MapPath("PDFs"). which shows the text having been written to the document but it looks a mess. and setTextRise(). Document doc = new Document(r).Working with Fonts Chunks A Chunk is the smallest significant piece of text that you can work with. It's ASP. doc. Before going on. all they should be used for is to change or set the style of a word or phrase inline.Create)). FontFactory. 300).NET to generate PDFs. i++) { doc.GetInstance(doc. such as setUnderLine(). you need to be careful how you use Chunks.GetFont("dax-black")).pdf".NET provide containers for varying ampounts of textual content. Chunk chunk = new Chunk("Setting the Font". Phrase and Paragraph classes.we will come back to it] The result can be seen below. ").getting started with iTextSharp iTextSharp . iTextSharp offers the Chunk. chunk. iTextSharp from within ASP.NewLine.5f.Open(). new FileStream(path + "/Blocks. or even Chunk. Really. Chunk c1 = new Chunk("A chunk represents an isolated string.SetUnderline(0. setBackGround(). PdfWriter. i < 4. if you would like to read earlier articles.5f). then write it to the PDF document 3 times: string path = Server.NET equivalent is the <asp:Label>. } [Keep an eye on the following paragraph . for (int i = 1. Just as HTML and ASP.This is the third in a series of articles that looks at using the open source component. Rectangle r = new Rectangle(400.NEWLINE as part of the string you give a chunk.Add(c1). they are: Create PDFs in ASP. as well as a number of constructors that permit you to set the font and its styles.NET . You can of course force a newline using "\n" or Environment. . The object that you will use most often is a Paragraph. Document doc = new Document(r). Rectangle r = new Rectangle(400. It has a number of sentences and some formatted inline text. } Paragraphs What we have seen so far is the very basic building blocks for text in PDFs.MapPath("PDFs"). The paragraph earlier in the Chunk section of this article is as good as any to experiment with. i++) { phrase. Since the default font-size was applied by iTextSharp (12pt). but they also force a new line for each paragraph (just as in any word processing application). The following snippet shows how the earlier chunk is added to a phrase 3 times. so they autommatically fit text within the horizontal boundaries of the document. and the result. try { .Add(c1). You can set the leading or font as part of initiating a new phrase. or "leading") is 1. and will force a newline when the length of its contents exceed the vertical margins of the document. Paragraphs derive from Phrase. as well as pass it a string or chunk to set its content through the phrase's various overloaded constructors. for (int i = 1. which is a sequence of Phrases and Chunks held together. the code below will result in a leading of 16pt. The space between each line (actually the measurement taken between the baselines of each line. A phrase is an array of chunks. so we can use that to build a paragraph from chunks and phrases: string path = Server. Phrase phrase = new Phrase().5 times the font size.Phrases The Phrase is the next container in the hierarchy. i < 4. 300). Chunks have no concept of how to force a new line when the length exceeds the available width in the document. p2. Font brown = new Font(Font.Color = Color.pdf". Chunk c7 = new Chunk("Chunk". Chunk c2 = new Chunk(@"\n". Font.Empty). doc. the result. 9f. p2. or even ".Replace(Environment. Phrase p2 = new Phrase(). georgia). georgia). 175)). Chunk c8 = new Chunk(". 145. text = text.Add(p). 9f). Chunk c4 = new Chunk("Environment". } finally { doc. 21)). new Color(43. Chunk c3 = new Chunk("\" or ". 9f. p2. Paragraph p = new Paragraph().COURIER.Add(c8).Add(p1).COURIER.PdfWriter. georgia. String. } catch (IOException ioex) { throw (ioex). Font lightblue = new Font(Font. courier).".Open(). p2.GRAY. which shows the text having been written to the document but it looks a mess.NEWLINE". all they should be used for is to change or set the style of a word or phrase inline. p. p2. Font. new Color(163. p2. 10f).Replace(" ". String.Add(c6). } First. p. Chunk c5 = new Chunk(". doc.Add(c4).GetFont("georgia".NewLine".Add(c2).NORMAL. p2.Empty). 21.Add(c7). georgia). then some notes about the code: . p2.GetInstance(doc. Really.Add(c5).Add(p2). Font georgia = FontFactory. Chunk c9 = new Chunk(" as part of the string you give a chunk. FileMode. Chunk c1 = new Chunk("You can of course force a newline using \"". string text = @"The result can be seen below. Chunk c6 = new Chunk(".NewLine. brown).Add(c9).Add(c1).COURIER. Chunk beginning = new Chunk(text.Close(). lightblue). new FileStream(path + "/Blocks2. lightblue). Font courier = new Font(Font.Add(c3). courier). } catch (DocumentException dex) { throw (dex). Phrase p1 = new Phrase(beginning). georgia). p2. ". georgia).Create)).NORMAL. "Center". So. which is @-quoted. "Justify".It didn't take long to start adding Exception handling to the code.NORMAL before the size. in that I passed in the value Font.. or a verbatim string literal.setSpacingAfter //adds the specified amount of space after the paragraph .setSpacingBefore //adds a specified amount of space above the paragraph Paragraph. The following shows the earlier example with p. When testing the code to generate the PDF file.setAlignment() method. and prevents the sort of mistake I experienced happening again.. This accepts a string.Close(). and "Right" being valid values. so that at least the document object is released. needs to have all the whitespace and newlines removed from it. you should always use try. Other than that. Of course.IndentationRight //allows you to add space to the right hand side Paragraph.setAlignment("Justify"). That explicitly tells the compiler that the value is to be treated as a float. There is another source of exceptions that I found to be rather sneaky. and I have to shut down VS to release its hold on the document object. each individually styled string is applied to its own Chunk object. The Paragraph class has a number of other useful methods and properties for styling including: Paragraph.FirstLineIndent //allows you to apply a float value to indent the first line Paragraph. otherwise it will appear with them preserved in the resulting PDF. This had the effect of setting the font size to 0. An exception is thrown when trying to call doc. and then added to a Phrase to ensure that lines are wrapped in the PDF. which is the value that the constant is set to. The first block of text. using the Paragraph. Finally both phrases are added to the single Paragraph object. exception handling starts to make its appearance.IndentationLeft //allows you to add space to the left hand side Paragraph. It is also possible to set the alignment of the paragraph text. with "Left". I inadvertently transposed two arguments in the constructor for the font I called lightblue. You will also notice that the font size values are now passed in with the f suffix following them. and with iTextSharp Document objects. there is also a DocumentException object to manage. catch when performing IO operations. Lists with iTextSharp . Web. here's how to generate a List: string path = Server.Add(paragraph). Ordered and unordered lists will be covered. this article turns its attention to lists.List. If you are coding your PDF generation within an ASP." is used as a prefix for some objects.Having already looked at how to create a PDF document with iTextSharp.UNORDERED).text. new FileStream(path + "/Lists. Lists can be UNORDERED or ORDERED (numbered).Message).Add("Five").text.NET .text.ListItem objects.text. so you can shortcut the namespace by providing an alias to it: using it = iTextSharp.Close(). } catch (IOException ioex) { Response. doc.WebControls. That means that attempting to simply add ListItem li = new ListItem(). it. list.Document(). if you haven't already done so.Add(new it. the way that a List or ListItem is referenced in the above code needs explaining. and to pass in a bool to indicate whether it is an ordered. Create PDFs in ASP. Now you can use the alias instead. try { PdfWriter.List object.DocumentException dex) { Response.Add("Three").Create)). list.Open(). The way to resolve this is to fully reference the ListItem class you are attempting to use by adding its namespace: iTextSharp. You may want to review earlier articles in this series.NET code-behind file.Working with Fonts iTextSharp .the first thing is to create a new List object. list. you will probably be working with the default set of namespaces that Visual Stuido references when the aspx. Phrases and Paragraphs Lists are generated from the iTextSharp. to your code will result in a warning of ambiguity.text. so each item in the list is rendered on a new line.Add("Four").Paragraph().Document doc = new it. As with their html <ul> and <ol> counterparts. paragraph.List list = new it. All that extra typing can get very boring.MapPath("PDFs"). string text = "Lists".cs file is created. } catch (it. it is an ArrayList of ListItem objects.List(it.Message). The code .Add("Two"). A List is a collection of iTextSharp. list. As you can see.Write(ioex. One of those namespaces is System.Add(list). doc. set fonts and their styles and add text.pdf". Actually. ListItem inherits from Paragraph (which inherits from Phrase.Write(dex. which inherits from ArrayList). which also includes a ListItem class. FileMode. } If you are not familiar with the concept.ListItem li = new iTextSharp.UI. it. or numbered list or not. } finally { doc. it.Add(text).Adding Text with Chunks.ListItem().Paragraph paragraph = new it. Diving straight into code.getting started with iTextSharp iTextSharp . The default is false.ListItem("One")). list. doc. "it.GetInstance(doc. Back to what the code actually does . Secondly. in that it occupies a new line. list.doesn't do much more except add 5 items to the list.IndentationLeft = 30f. followed by the List being added to the document. The second and subsequent items are added directly to the List object as strings. Finally. and setting its string value. 10f). each item acts like a Paragraph as promised. for example. it. the actual symbol is changed to the more traditional bullet point using the setListSymbol() method.List. and none of the usual indentation that you would get if you were using Microsoft Word. you can use the RomanList class: . iTextSharp provides ways to format the List so that it looks a lot better. The result looks a little more pleasing: If you like your ordered lists with Roman numerals.List list = new it. This results in the space between the symbol and the item itself being increased. You will also note that the default settings provide a boring list with hyphens as symbols for each ListItem. the List is indented 30 points from the left margin of the document.UNORDERED. The result is this: As you can see. list. a Paragraph is created and added to the document. The first is added by creating a new ListItem object. Finally. which sets the symbolIndent value at 10 points. A second argument (float) is passed in to the List constructor.SetListSymbol("\u2022").List(it. ZapfDingbatsList(49.Add("Three"). romanlist.Add("Five").Add("Four").Add("Four"). zlist. Since the List.Add("Two"). instead of a float. zlist.Add(romanlist). the symbolIdent value passed into the constructor is an int this time. and two further classes: ZapfDingbatsList and ZapfDingbatsNumberList offer more symbol formatting opportunities as they make use of the ZapfDingBats font. romanlist.Add("One"). The following code creates a RomanList first. and iTextSharp indents the RomanList relative to the ordered list to which it belongs: . romanlist. The RomanList is added to the ordered list.Add("One").Add(zlist). 20). A separate GreekList class supplies list symbols as Greek letters. 15). zlist.Add() method accepts an object. romanlist.RomanList romanlist = new RomanList(true. all you need to do is to pass in a valid List() object.Add("Three").Add("Two").IndentationLeft = 30f. doc. doc. romanlist. The first argument is a bool that tells iTextSharp whether you want lowercase symbols or not. then an ordered list. The Greek and Roman lists should never be used for lists that contain more than 24 and 26 items respectively. and the ZapfDingBatsNumberList can only cope with a maximum of 10 items before the numbering runs out and becomes 0. For some odd reason. zlist.Add("Five"). Lists can also be nested. zlist. ZapfDingbatsList zlist = new it. romanlist. list. 20). romanlist. list. List list = new List(List.Add("Roman List").Add("Four"). list.Add(romanlist).Add("Three").Add("Five"). romanlist.IndentationLeft = 10f. romanlist.Add("Two"). 20f). list.Add("Four").ORDERED.RomanList romanlist = new RomanList(true.Add("Five"). romanlist. doc. list.Add("One").Add(list).Add("Two"). romanlist. . romanlist.IndentationLeft = 20f.SetListSymbol("\u2022"). list. doc.Add(paragraph).Add("Three"). list. list. list.Add("One"). Links and Bookmarks . } catch (DocumentException dex) { Response. anchor. } finally { doc. this particular contribution will introduce the basics of linking and bookmarking PDF documents created via iTextSharp.GetFont("Arial". Internal links within an HTML document are specified by adding a NAME attribute to an <a> tag. doc. Create PDFs in ASP. which when clicked will open a browser at this site. 12.getting started with iTextSharp iTextSharp . iTextSharp adopts the same model: . 0.Close(). and internally within the document.Reference = "http://www.MapPath("PDFs").GetInstance(doc.Write(ioex. as this should help users identify an Anchor as providing some functionality: string path = Server.mikesdotnetting.Message). Where they diverge from the HTML <a> element is that by default. new FileStream(path + "/Anchors.Create)). FileMode.com". Font link = FontFactory.com". if you haven't already done so. try { PdfWriter. Following earlier articles in my iTextSharp series. I suggest applying underlining and a blue colour to the font.pdf".mikesdotnetting.Adding Text with Chunks.NET . Phrases and Paragraphs Lists with iTextSharp Links iTextSharp Anchor objects are very similar to their HTML counterparts. new Color(0. For that reason. they do not adopt any special styling within a PDF. link). } catch (IOException ioex) { Response. Font. doc.Working with Fonts iTextSharp .UNDERLINE. Anchor anchor = new Anchor("www.Open().Add(anchor).Message). You may want to review earlier articles in this series. Document doc = new Document().Write(dex. in that they permit you to create hyperlinks both externally from the document. } The code sample above creates an external link. 255)).Interactivity within PDF documents is enabled though Anchors (links) and Bookmarks. Name = "target". When rendered to the PDF. The Chunk. p4. p1. p5. doc. Paragraph p5 = new Paragraph(). The first paragraph contains the text "Click to go to Target". your PDF Viewer application displays a tree-view of the structure of the document. Paragraph p1 = new Paragraph().Add(p2). iTextSharp provides the functionality to generate this tree-view through its Chapter and Section classes. with a Name attribute set to match the Reference value in the Anchor in the first paragraph. again with a string defining the location of the target. Paragraph p3 = new Paragraph(). the PDF will immediately reposition itself so that "This is the Target" will be at the top of whatever PDF viewer you are using. the word "here" is underlined and in blue. Paragraph p2 = new Paragraph(). just as with the HTML version. and clicking on it brings "Local Goto Destination" to the top of the screen. doc.Add(p1). .Add(new Chunk("Click ")). p2. This one has its SetLocalDestination() method invoked. The result is that if you click on the "Click to go to the Target" text.Reference = "#target". p4.SetLocalGoto("GOTO")). A number of empty lines are added followed by another chunk.Add(p5). and SetLocalDestination() methods of the Chunk class. Bookmarks Often when you open a PDF file. The second paragraph adds some empty lines and the final paragraph contains a new Anchor.Anchor click = new Anchor("Click to go to Target").Add(new Chunk("\n\n\n\n\n\n\n\n\n")).Add(new Chunk("\n\n\n\n\n\n\n\n")).SetLocalDestination("GOTO")).Add(click). p4. Paragraph p4 = new Paragraph().Add(p4). An alternative to using Anchors to set internal bookmark targets is to use the SetLocalGoto(). The first chunk is added using the font that's set up to convey to users that the text should act as a hyperlink.Add(new Chunk("here". It's matches the one set in the SetLocalGoto() method earlier.SetLocalGoto() method accepts a string.Add(new Chunk("Local Goto Destination"). with each branch or leaf acting as a link to the corresponding chapter or section. link). p4. doc. click. and its reference is set to "#target".Add(target). target.Add(new Chunk(" to find local goto")). doc. which acts a a label for the target. Anchor target = new Anchor("This is the Target"). p3.Add(p3). doc. Section subsection3 = section3.1". the title of the Section to appear on the page and in the Bookmars. Section section4 = chapter2.2". Sections cannot be added alone. which will always begin on a new page. "Sub Subsection 1. but closed for Chapter 2. Section subsubsection = subsection2.AddSection("Section 2. Initially.AddSection(20f.AddSection(20f. doc. chapter1.AddSection(20f.BookmarkOpen = true. and the indentation depth for the entry in the Bookmarks tree.2". In this case. 1). Section section3 = chapter2.1". 2). a Section object is added to the Chapter.2. 2). The second argument is the number of the Chapter .1). The rest of the code that adds Chapters and Sections should be straightforward. chapter1. Section subsection2 = section2. 3). 2).2. "Subsection 1. Finally.Add(chapter2). The final lines of code show that the actual entry in the Bookmarks can be changed from the title on the page by setting the BookMarkTitle property to another string value. If you need to create a document such as a manual on a regular basis. doc. Chapters and Sections are pretty memory hungry. Chapter chapter2 = new Chapter(new Paragraph("This is Chapter 2"). Then the outline view for the tree is set as open for Chapter 1. 3). this might be a taks best scheduled for quieter times on your web server. with 3 arguments: a float specifying the left indentation in points.1. Section section2 = chapter1.Add(chapter1). Section 1. "Section 1.1 is set to appear as a second-level entry on the tree.The top-level object is a Chapter.2". but must be added to Chapter objects.AddSection("Section 2. a Chapter object is created with a Paragraph passed in as the first argument.AddSection(20f.AddSection("Subsection 2.1". Subsection1 is added to Section 2 and has been told to appear as a third-level entry in the tree. or parent Section objects: Chapter chapter1 = new Chapter(new Paragraph("This is Chapter 1"). Section subsection1 = section2. Section section1 = chapter1.1". chapter2. Nest. .BookmarkTitle = "Changed Title". 2).2.1". 3). both Chapters are added to the document.in this case 1. "Subsection 1. 4). The image above helps to explain the preceding code. so they should be used judiciously.2. "Section 1.BookmarkOpen = false.AddSection(20f. Introducing Tables . Colspan = 3. doc.SpacingBefore = 20f.AddCell("Col 3 Row 1"). table. table.Adding Text with Chunks. The following effort queries a database.SpacingAfter = 30f. //0=Left. It also shows some other options that can be used for styling and presenting the table: PdfPTable table = new PdfPTable(2). All possible values are shown as a comment. table. At its most simplest. Cells can be added in a number of ways. table. and presents the resulting data in a table. which means that the cell will occupy the full width of the table. table.Working with Fonts iTextSharp .AddCell("Col 1 Row 1"). The Colspan is set to 3.Links and Bookmarks Working with tables using iTextSharp is not that difficult. //leave a gap before and after the table table.LockedWidth = true. Following that. 2f }.getting started with iTextSharp iTextSharp .NET applications to provide the structure for documents such as orders and invoices. There is more than one class in iTextSharp that can be used to create tables. just as in HTML. This overview is not an exhaustive examination of tables. The first cell is set as a PdfPCell object. two rows of cells are added using the AddCell() method and the table is finally committed to the currently open document.AddCell("Col 3 Row 2"). table. and builds on the previous articles in this iTextSharp series: Create PDFs in ASP. cell. which can take a Phrase object in one of its 7 constructors. table. //fix the absolute width of the table table.AddCell("Col 1 Row 2").the integer 3 being passed into the constructor. The PdfPTable object is instantiated as a three column table . but provides an introduction to working with them through iTextSharp. //actual width of table in points table. so for the avoidance of doubt.SetWidths(widths). PdfPCell cell = new PdfPCell(new Phrase("Header spanning 3 columns")). table.Add(table).Tables will probably be one of the most used elements in PDFs generated from ASP. here is how to create a table and add it to a document: PdfPTable table = new PdfPTable(3).AddCell("Col 2 Row 1").AddCell("Col 2 Row 2"). The horizontal position of the text within the cell is set using one of three possible values. 2=Right table.TotalWidth = 216f. . 1=Centre. Phrases and Paragraphs Lists with iTextSharp iTextSharp . cell.1/3 and 2/3 float[] widths = new float[] { 1f. table.HorizontalAlignment = 0. especially as many of the property names are so similar or identical to their counterparts within CSS and HTML. which is designed specifically for use within PDF documents. //relative col widths in proportions .HorizontalAlignment = 1.AddCell(cell).NET . I will be using the PdfPTable class. table.Message).ToString()).".ToString()). To set it a one fifth and 4 fifths. try { conn.\\SQLEXPRESS. ProductName FROM Products".Add(table). You can slo set the absolute widths by passing in values that together total the table width.ExecuteReader()) { while (rdr. cell. using (SqlConnection conn = new SqlConnection(connect)) { string query = "SELECT ProductID. SqlCommand cmd = new SqlCommand(query. } } } catch(Exception ex) { Response.Database=Northwind. using (SqlDataReader rdr = cmd.Border = 0. As it is read.AddCell(rdr[0].AddCell(rdr[1]. } The table is initally created with 2 columns.Colspan = 2. you would pass in 1f and 4f respectively. and fixed.Trusted_Connection=True. 116f }. A gap is created before and after the table by setting the SpacingBefore and SpacingAfter properties. which is treated as a header by setting the colspan to equal the number of columns in the table. cell. cell. for example: float[] widths = new float[] { 100f. Then the database is queried and the data returned in a SqlDataReader. table. the data is consigned to cells which are added to the table: .AddCell(cell). } doc. Then the width of the table is set in points. conn). The width of the columns themselves are set relatively at one third and two thirds of the total table width. as the default behaviour is to pin subsequent tables to the previous one. as in MS Word.Write(ex.HorizontalAlignment = 1. where a quick tap of the Enter key has the same spacing effect. string connect = "Server=.Open().Read()) { table. The border is removed from the first cell.PdfPCell cell = new PdfPCell(new Phrase("Products")). using the same value as that used for aligning the table in the document. This is useful if you have more than one table following on from another. and the text in the cell is centre-aligned. Color.BorderWidthBottom = 3f. cell.NORMAL. cell. but what actually happens is that a single column.HELVETICA. 150.TOP_BORDER.PaddingTop = 4f. The following code creates a four column table.AddCell("Cell 1"). and vertically by three rows.PaddingBottom = 10f. table.BorderColor = new Color(255. cell. .Add(table). cell. Font. doc.PaddingLeft = 20f.242. We have seen on a number of occasions how a cell can stretch horizontally through the use of the Colspan property.) PdfPTable table = new PdfPTable(3).BackgroundColor = new Color(0.The following snippet illustrates some of the options for formatting cells. with the bottom right cell stretching horizontally across three columns. cell. but there is no equivalent in iTextSharp. that's the final appearance.BorderWidthTop = 3f. But what about vertically? In HTML you would use the Rowspan property.BOTTOM_BORDER | Rectangle. The cell that the table is nested within has its padding removed so that the table occupies all of the available space within it. cell. three row table is nested within the bottom left cell. cell. of course.AddCell("Cell 3").AddCell(cell). PdfPCell cell = new PdfPCell(new Phrase("Cell 2".Border = Rectangle. table. new Font(Font. So the answer is nested tables. cell. the creators of iTextSharp have followed the CSS names for properties as much as possible to make working with styling syntax as easy as possible (if you know your CSS.0). Well. 0).. table. As you will see.YELLOW))). 8f.. AddCell("Cell 4"). and I will cover additional functionality in future articles. table.PdfPTable table = new PdfPTable(4).AddCell("Not Rotated"). table. table. table. table. PdfPCell middle = new PdfPCell(new Paragraph("Rotated")).Rotation = 90.AddCell(bottom). doc. PdfPCell left = new PdfPCell(new Paragraph("Rotated")). table. bottom.LockedWidth = true. table.TotalWidth = 400f. The default direction that the content is rotated is anti-clockwise. table.AddCell("Cell 3"). table. middle.Add(table). The result is below: There is an awful lot more to working with tables in iTextSharp.Add(table). PdfPTable table = new PdfPTable(3). PdfPCell nesthousing = new PdfPCell(nested). PdfPCell header = new PdfPCell(new Phrase("Header")).AddCell(nesthousing). The Rotation property must be set to multiples of 90. table.AddCell("Nested Row 1").AddCell("Cell 2"). PdfPTable nested = new PdfPTable(1).Padding = 0f. left.AddCell("Nested Row 2").AddCell(middle). table. table.AddCell("Nested Row 3"). in this look at tables. Intellisense or the Object Browser within Visual Studio reveals a lot of methods and properties that are worth experimenting with to see their results. nesthousing.Colspan = 3. . PdfPCell bottom = new PdfPCell(new Phrase("bottom")). but 270 would have had the same effect.AddCell(left). nested.AddCell(header).LockedWidth = true.TotalWidth = 144f. header. The middle cell is set to 90. table.Colspan = 4. In the meantime. we see how the text content of a cell can be rotated (which is rather natty). nested.HorizontalAlignment = 0. or an error occurs.AddCell("Cell 1").Rotation = -90. doc. table. nested. table. Finally. Drawing shapes and Graphics . PageSize. try { PdfWriter writer = PdfWriter. cb. however.Height / 2). all content added to the PDF documents in previous articles have relied on Simple iText. .. cb. which is still halfway across the document.Stroke(). Now that we have a working PdfContentByte object. cb.Introducing Tables iTextSharp . string pdfpath = Server. which takes care of positioning content within the flow of a document.MoveTo(doc. Actually. y coordinates specified in the parameters passed in.Width / 2. The first line moves to the x. The next line draws a line from this point to the position specified in the LineTo() method. doc.The previous iTextSharp article looked at bringing images into a PDF file and working with them. Sometimes.Height/2).Stroke().LineTo(doc.Open().Working with Images Up till now.LineTo(doc. we can use it to start drawing: cb.GetInstance(doc. . PdfContentByte cb = writer.NET . in that we now need to use a PdfContentByte() object explicitly.PageSize. Document doc = new Document().Width / 2. This also means that instead of just invoking the GetInstance method of the PdfWriter. at a position halfway up the document to the righthand edge at the same height .PageSize. It also looks after creating new pages to accept overflow text etc.MapPath("PDFs").Working with Fonts iTextSharp . The second line is drawn from the lefthand edge.PageSize. Working with graphics needs a slightly different approach. it doesn't "draw" it.so we end up with the top two quarters of the document outlined.PageSize. This is obtained from the PdfWriter object's DirectContent. doc.Width. iTextSharp includes a lot of functionality that covers simple drawing to quite complex shapes. This article gets you started.Height). but at the top of it. new FileStream(pdfpath + "/Graphics. we actually need to instantiate a PdfWriter object. you may want to draw shapes and lines within the PDF and not rely on images.pdf". Phrases and Paragraphs Lists with iTextSharp iTextSharp . but really only describes our intention.getting started with iTextSharp iTextSharp .PageSize. Previous articles are listed below: Create PDFs in ASP. doc. doc. doc.Create)).Adding Text with Chunks. cb. cb. which in this case is halfway across the document.MoveTo(0..DirectContent.Links and Bookmarks iTextSharp .PageSize. and halfway up (or the center point). FileMode. The line is only actually committed to the document when Stroke() is called.Height / 2). and Fill represents its internals bounded by the Stroke. 300). there is a quicker way of delivering a square (or rectangle) using one of the convenience shapes provided by iTextSharp. cb. 200). 100f. 600f). We didn't need to explicitly specify the coordinates for the final side of the square. If you have worked with any graphics packages. placing a square in the top right quarter of the document: cb. cb.SetColorFill(new CMYKColor(0f.LineTo(410. each one illustrating the results of different methods other than Stroke().Fill(). cb.Rectangle(doc. cb. 200). cb. . 600f. 700f). cb. 0f)). cb.LineTo(200f. 0f)). 0f. cb. we can add a square to the top left quarter: cb. However. //Path closed and stroked cb.ClosePathStroke().FillStroke(). 100f). the Stroke colour and the Fill colour are set. 300). stroked.Using the same methodology. used to consign them to the document. //Filled. Four more squares are added to the page. cb.LineTo(410. 200). cb.LineTo(100f. but path not closed cb. cb. The next bit shows that is action. cb. 0f.Stroke().Width-200f. 300). I have used CMYK as the colour space. 1f.MoveTo(70. ClosePath() automatically provides a line from the current position that we are at to the original coordinates. 200). cb.MoveTo(310.LineTo(290. but not stroked or closed cb. 300). //Filled. cb.LineTo(70. cb.LineTo(170.LineTo(310. cb. cb. But first.LineTo(290. 600f). 0f.MoveTo(190.ClosePath(). 300).PageSize.LineTo(200f.Stroke(). 200). 700f). you will probably know that Stroke is the outline of an object. cb. 200). 300).LineTo(190. such as PhotoShop or FireWorks.MoveTo(100f.SetColorStroke(new CMYKColor(1f.LineTo(170. cb. setting the Stroke colour to Cyan and the Fill colour to Yellow: cb. 100.Circle(120f. cb. then an ellipse is added to fit neatly within it to illustrate how the positioning works through the parameters supplied to the constructor: // x. I found you have to guess at the actual values required by the two methods concerning the use of CMYK colour I have used so far. cb. 0). 300). here's an example of using another preset shape. 250f. I found out CMYKColor is built on the ExtendedColor class.LineTo(530.SetCMYKColorFill(0. Neither was intuitive. so 256 is the equivalent of 1. I also discovered that there is nothing to prevent you entering values above 255. so I deployed the ResetCMYKColorFill() method in the hope that it did something. I can provide any value I want. 0). that's the results I got when I tried it. 255. Warm Red is referenced as C: 0%. 200). When using a Rectangle object to represent a square or rectangle instead of drawing it. //Path closed.ClosePathFillStroke(). cb. so long as it is a valid float. 100f). 0f. I thought maybe this method was working on percentages as I would expect with CMYK. For example. the first two parameters represent the x and y coordinates of the bottom right hand corner.Fill(). 200). followed by a value representing the radius. Here's my red circle with a mauve border (2 points in width) in the first square: Moving on. All it did was reset to the default colour of black. 300). and don't accidentally type in an extra zero. height cb. In fact. stroked and filled cb.MoveTo(430. 0. cb. a rectangle is drawn. enough of the digression. cb. cb. 0 to represent Warm Red. but the x and y coordinates that are passed in represent the center point of the shape. Anyway. so I originally supplied the value 0.Rectangle(100f.or at least. 50f). 0f. CMYK colours are represented as a series of percentages. The constructor for CMYKColor() requires four floats. given that generally. so for 100% blue (Cyan) i could just have validly provided 3000f. Nope. and 510 is the equivalent of 255 . The SetCMYKColorFill() method used just above accepts ints. Providing values that represent the percentages works fine. Y: 100%. All I got was a washy pinky colour. 255. and that the center point is at 120 x. rather than floats. To build on the oddity of this approach. 300f.cb. To add a circle to the square so that it fits nicely. M: 100%. and can accept ints up to 255 . it is relatively easy to determine that the width and height is 100 points. 0f. 255. and that something was being affected by the previous setting of the Fill colour. and got my desired result. y of bottom left corner. But I have provided values of 1f and 0f. Eventually. the ellipse. it seems that iTextSharp subtracts 255 from whatever you supply. Other preset shapes include the Circle. width. but workable if you stick to the usual CMYK percentages. The final two parameters are the width and height. Rather irritatingly. the following code will do: cb. Strange. 250 y. If you do. 200f. 100.SetLineWidth(2f). K: 100%. I thought perhaps there was a bug in there somewhere. //Bottom left and top right coordinates . I applied the values you see above.SetCMYKColorStroke(255. cb. The values are treated as being relative to eachother. Looking at the first of the 4 squares above.Stroke().LineTo(430.LineTo(530.which is reminiscent of the RGB colour values and really confusing unless you know. First. cb. 20f). I've placed a cross at the center of the circle: //Bottom left coordinates followed by width. cb. 200f. 520f).Stroke().LineTo(360f. If the differences between the first and third parameter. height and radius of corners cb. cb. cb. 520f). you end up with a circle. the values passed in are the x and y coordinates for the bottom left hand corner. cb. cb.LineTo(350f.Stroke(). cb. followed by the width and height. 520f.LineTo(120f.RoundRectangle(100f. Here's an example of a right-angled triangle with the right angle shown: cb. 300f). cb. 450f).MoveTo(350f. cb.Circle(120f. 518f).MoveTo(350f. and finally the radius of the rounded corners.MoveTo(120f. 460f). 522f). 200f.LineTo(122f. the rounded rectangle. 450f). cb. cb. 450f).ClosePathStroke().Stroke().MoveTo(118f. When one of these are drawn.Stroke(). cb. just by drawing the three lines they require. Triangles are relatively simple to do. cb. 460f). cb. 400f.LineTo(360f. and the second and fourth parameter are the same.LineTo(500f. 500f. cb.Stroke(). cb. . 20f).Ellipse(100f. I have also added a circle in the corner with the same radius as the corner itself to show how the radius of the corner works.Stroke(). cb. cb. 600f). The next example shows another preset shape.cb. 200f. MoveTo(450f. //start point (x.MoveTo(200f. 150f). cb. usually with little "handles" on the end of them which you can move to bend the curve. Control Point 2. cb. 10). and the distance between the start and end point themselves. and this starts to exert its influence on the curve along with the ultimate destination at a relatively early point in its journey. They work by specifying a start point. then bends away towards the second control point at (450. //Start Point cb.Stroke(). and the angle is altered: cb. 30f). 70f. before arriving at the end point.y) cb. 150f).LineTo(150f. The first control point is specified in reference to the start point. that starts at (200. It looks like this: I'm not really sure that shows a lot.Circle(450f. you will have seen these control points. which is reflected in the way the line is "pulled" towards it. cb. 70f). 1f).Stroke(). cb. 10f).y) . The curve heads towards the first control point at (150. cb. The second control point has a longer handle. 1f). end point (x. End Point cb. If you have ever used a Vector graphics package. This effect is probably best illustrated by changing the second control point so that it is further away. 350f.GREEN). so I will add in some "handles" that show the control points: cb. The curve will begin at the start point.LineTo(350f. control point 2 (x. 450f. and are rarely hit by the path. 30). so the curve only begins to move towards it.y).Curves and Arcs Bezier curves are important in Vector Graphics. 30f. cb.Stroke(). 70).MoveTo(200f.Circle(150f. The first control point has a relatively short handle. and the second one is related to the end point.Stroke(). 150). cb.MoveTo(200f.Stroke(). and the end point and its control point. Here's an example of a curve. where they are based on mathematical equations rather than each individual point being specified along the path of the curve. cb. 30f. //control point 1 (x. and head towards the end point in the direction of the 1st control point.CurveTo(150f. cb. and ends at (350.y). 10f).SetColorStroke(Color. cb. 10f). //Control Point 1. like Photoshop or Fireworks. an end point. How far it gets near the control point will depend on the distance between the start point and its control point. 70f. The control points are used for directional purposes. and two control points. LineTo(350f. The angle at which the arc is started is 270°. cb. 130). Top Right(x. 100f. cb. the green line moves much further towards the second control point before finishing up at the end point. //Bottom Left(x. Now you can see that the increased length of the second "handle" has exerted its influence right from the start point.LIGHT_GRAY).y).Stroke(). 100f.LineTo(535f. The default direction that an ellipse is drawn is counter-clockwise. while the new one is shown in green. and is at a slightly more obtuse angle. 100f). 95f). 70) and a top right corner at (550.CurveTo(150f. which allows me to draw the arrow as a dashed line. . cb. An Arc is part of an ellipse.Stroke(). cb. 100f). cb. the SetLineDash() method is shown for the first time in this series of articles. 90f). cb. cb. 550f.cb.y). which has been used in this instance to create the curved arrow illustrating the movement of the original and new second control points. Extent cb. cb. cb. cb.Stroke(). 550f. cb. 150f).Stroke(). and only 90° of it are drawn.MoveTo(550f. 3f). There are a couple of other points to note about the code for the second curve.MoveTo(550f. Start Angle. cb.SetLineDash(0f).LineTo(552f. 100f).SetColorStroke(Color. 270f.Stroke(). the ellipse will fit into a rectangle that has a bottom left corner at (350. 88f). Secondly.Arc(350f. cb.MoveTo(550f. cb. 150f). 350f. 1f). In this case.Circle(550f. One is the Arc object.SetLineDash(3f. 130f. cb. The original curve is shown in black. cb. 70f. in that the green line starts just slightly beneath the original black one. 30f. Since the new second control point is further away from the end point.Stroke(). Working with images . Create)).GetInstance() method. } catch (Exception ex) { Response.GetInstance(imagepath + "/mikesdotnetting. } catch (IOException ioex) { Response. Create PDFs in ASP. bmp.Image).Introducing Tables iTextSharp supports all the main image types: jpg.Drawing.Close().Write(ex. Note .FromStream() method shows the use of namespace aliasing again . } finally { doc.Working with Fonts iTextSharp .MapPath("PDFs").Drawing.The seventh article in my iTextSharp series looks at working with images. There are a number of ways to create images with iTextSharp using the Image. png and wmf. string imagepath = Server.NET . Probably the most used option will be to pass a filesystem path and file name into the method: string pdfpath = Server. try { PdfWriter. Phrases and Paragraphs Lists with iTextSharp iTextSharp .Image object (as opposed to an iTextSharp.MapPath("Images"). new FileStream(pdfpath + "/Images.Message).Open(). } catch (DocumentException dex) { Response.Add(gif).Adding Text with Chunks. } Alternative constructors that you may use include passing a URL or a System.text. doc.Write(ioex.Links and Bookmarks iTextSharp .the following snippet that System. This article builds on the previous six which are listed below. gif. FileMode. doc. Document doc = new Document(). tif. doc.Write(dex.Image.getting started with iTextSharp iTextSharp . Image gif = Image.Message).Add(new Paragraph("GIF")).gif").pdf".GetInstance(doc.Message). That part is fine.Png). Image tif = Image.ScalePercent(24f). doc.ImageFormat.97 inches (72 points by 213. doc. Generally.17 inches wide by12.Image.Add(jpg).Open)) { Image png = Image.GetInstance(sd. By default. So at the default 72 dpi.png". } It's difficult to tell from the images I have provided so far. images are embedded at 72 dpi (Dots Per Inch) which coincidentally.(sd.FromStream(fs). I have a large tif file that I want to use as a logo on an A4 letterhead. If this file was being prepared for printing. Now. Now I want to place the .Add(new Paragraph("TIF Scaled to 300dpi")). and the depth to 2. you can scale the image to 24%. it will measure 4. string url = "http://localhost:1805/PDF/Images/mikesdotnetting.tif").FromStream(fs)).Add(new Paragraph("PNG")). 72/300 * 100 = 24%.GetInstance(new Uri(url)).36 inches deep. We can do that using the code above. What you are actually trying to do is squeeze 300 pixels into the space that 72 normally occupies. doc. the final job would be a bit nasty. Image jpg = Image. Increasing the resolution to 300 dpi will reduce the width to 1 inch.Add(png).Add(new Paragraph("JPG")). but the resolution of the resulting images in the PDF file is not that great. FileMode. matches the number of points in an inch.GetInstance(imagepath + "/mikesdotnetting. tif. It measures 300 x 890 pixels.Add(tif). using (FileStream fs = new FileStream(imagepath + "/mikesdotnetting. To achieve this. as was highlighted in the article Lists with iTextSharp to avoid clashes with the two different types of Image object: doc.jpg". The image stays the same in terms of file size but occupies less space in the document. doc. commercial printers require that colour images for printing have a resolution of 300 dpi. doc.Image.6 points). PageSize. doc.Add(tif).108 = 487 points along the X-axis. doc. into a rectangle measuring 250 points square. SetAbsolutePosition() accepts 2 floats as parameters.jpg").ToString())).36f .(213. . or 842 . Image jpg = Image.ScalePercent(24f).Height . and I just remove the margin (36 points) and the width of the image (72 points) for the X-axis co-ordinate.ToString())).Add(new Paragraph("Scaled Width: " + jpg.300 dpi image in a particular position on the page. And fortunately. The SetAbsolutePosition() method will do this.Add(new Paragraph("Scaled Height " + jpg.ToString())).Add(new Paragraph("Original Width: " + jpg. An A4 document is 595 points wide and 842 pixels high with a 36 point margin all around by default.tif").ScaledWidth. Image tif = Image. The first represents the co-ordinate along the X-axis.YELLOW. This image will butt right up to the right-hand margin.ScaledHeight. Got my company logo in :-) Another scenario that might need to be catered for is to fit a user-supplied image into a fixed size box somewhere on a form. I can use the Document. jpg.216.Add(jpg).Width. doc. doc.GetInstance(imagepath + "/verticallogo.PageSize object to do the work for me. tif.36f .6f).GetInstance(imagepath + "/Sunset.72f.Border = Rectangle.ToString())). Cripes. which starts at the left hand edge of the document and finishes at the right hand edge of the document.BorderColor = Color.BorderWidth = 5f. The second represents the Y-axis co-ordinate which starts from the bottom of the document and goes to the top.PageSize.SetAbsolutePosition(doc. but I need to get a calculator out. I have in mind the top right hand corner. jpg.Add(new Paragraph("Original Height " + jpg.Height. and the margin and height of the image from the total height of the document for the Y-axis co-ordinate. doc.BOX.4 points from the bottom. I've pinched the Sunset image that I found in the Sample Images folder in My Pictures that comes as part of the default install of WindowsXP to illustrate how to use the ScaleToFit() method to achieve this.Width gives me the width in points of the document. doc.PageSize. I don't have to. jpg. doc. doc. The image is 72 points wide (1 inch) + the margin at 36 points (total 108 points) from the right hand edge of the document.Width . The actual co-ordinate that needs to be passed in is the bottom left of the image position. The Y-axis co-ordinate is the height of the image + the margin away from the top of the document. maintaining its aspect ratio. I don't really want to have to remember all the various sizes of different documents and do these calculations every time I want to set the absolute position of an element.ScaleToFit(250f.6 + 36) = 592. tif. The following code takes an image of 800 x 600 and forces it to resize. or 595 . jpg. 250f). Suspendisse blandit blandit turpis. adipiscing et. which is 5 points wide.WHITE. laoreet id. doc. Ut ut ipsum? Aliquam non sem. jpg. 250f). I have also taken the opportunity to add a yellow border to the embedded image. . hendrerit eu.Add(paragraph).IndentationLeft = 9f. Donec nibh est. Nulla risus eros. Integer ac turpis vel ligula rutrum auctor! Morbi egestas erat sit amet diam.Width / jpg. jpg. ullamcorper vitae. placerat at.ALIGN_RIGHT. jpg.TEXTWRAP | Image.SpacingAfter = 9f. Nam in lectus ut dolor consectetuer bibendum. in that text added to the document will run over the top of it.Alignment = Image. congue ac.TEXTWRAP instead. libero. jpg.jpg"). mollis quis. mauris.Alignment = Element. Paragraph paragraph = new Paragraph(@"Lorem ipsum dolor sit amet. Proin egestas leo a metus?"). jpg.ScaleToFit(250f. dignissim et. Nunc dignissim consectetuer lectus.ALIGN_JUSTIFIED. accumsan eget. luctus eget.Add(new Paragraph("Resolution: " + Resolution)).BorderWidthTop = 36f. Image jpg = Image. Vestibulum vestibulum dapibus erat. paragraph. Phasellus id lectus! Vivamus laoreet enim et dolor.BorderColorTop = Color. diam.Add(jpg). Fusce elit nisi. and then shown the original dimensions. Vivamus suscipit. urna. Unless you want to achieve this kind of watermark effect. Integer arcu mauris. viverra id. consectetuer sit amet. And here's the result: If you use SetAbsolutePosition() you end up with the same effect as if you had set the Alignment property of the image to Image.ScaledWidth * 72f. you need to use Image. libero. followed by the scaled dimensions. ultricies vel.UNDERLYING. Morbi neque ipsum. doc. facilisis quis. Nulla mauris elit.float Resolution = jpg. blandit ut. porta quis. doc. jpg. and the resulting resolution of the image. dolor? Suspendisse eleifend nisi ut magna. venenatis at. commodo non. consectetuer adipiscing elit.GetInstance(imagepath + "/Sunset. I'll be pleased to hear from them. The following are equally valid and equivalent: jpg.PI / 2. The fact is that whatever I set the value to for SpacingBefore. I have no idea why this should be. you can either read this article on Radians and work out that a quarter turn (90°) is Pi / 2. One way to do this is to set the Rotation property. jpg. Left and Right padding can be added using the IndentationLeft and IndentationRight properties. and that's a good question. or simply set the RotationDegrees property instead. I added a white border to the image to align it with the top of the text. it seemed to have no effect whatsover in this instance. Rotation by default is anticlockwise. which takes a float. and a bit of padding to the left and bottom of the image to stop the text running right up to its edge. The float value represents an angle measured in Radians. you may be comfortable with this.Rotation = (float)Math. If you did more Mathematics than I did at school.RotationDegrees = 90f. but if you are like me and ask "What??". One final thing with images . You may ask why I didn't use SapcingBefore instead of adding a white border.you can rotate them if you need to. . but if anyone does.In this instance. while SpacingBefore and SpacingAfter is used to pad the top and bottom.
Copyright © 2024 DOKUMEN.SITE Inc.