Description:-
Most often, when working with columns you will want
to add multiple columns for text layout, similar to a newspaper. ITextSharp has
a MultiColumnText object which makes this pretty simple. All you need to tell
it is where the leftmost column should start from along the X-axis, where that
rightmost column should end, what space you would like
between the columns and how many columns you want. The following adds 2 columns
to a page, and then adds a paragraph 8 times:
string pdfpath = Server.MapPath("PDFs"); string imagepath = Server.MapPath("Columns"); Document doc = newDocument(); try { PdfWriter.GetInstance(doc, newFileStream(pdfpath + "/Columns.pdf", FileMode.Create)); doc.Open(); Paragraph heading = newParagraph("Page Heading", newFont(Font.HELVETICA, 28f, Font.BOLD)); heading.SpacingAfter = 18f; doc.Add(heading); string text = @"Loremipsum dolor sit amet, consectetueradipiscingelit. Suspendisseblanditblanditturpis.Nam in lectusut dolor consectetuerbibendum.Morbinequeipsum, laoreet id; dignissimet, viverra id, mauris. Nullamauriselit, consectetuer sit amet, accumsaneget, congue ac, libero. Vivamussuscipit.Nuncdignissimconsectetuerlectus.Fusceelit nisi; commodonon, facilisisquis, hendreriteu, dolor? Suspendisseeleifend nisi ut magna.Phasellus id lectus! Vivamuslaoreetenimet dolor. Integer arcumauris, ultriciesvel, portaquis, venenatis at, libero.Donecnibhest, adipiscing et, ullamcorper vitae, placerat at, diam. Integer ac turpisvel ligula rutrumauctor! Morbiegestaserat sit amet diam. Ututipsum? Aliquam non sem. Nullarisuseros, mollisquis, blanditut; luctuseget, urna.Vestibulumvestibulumdapibuserat.Proinegestasleo a metus?"; MultiColumnText columns = newMultiColumnText(); //float left, float right, float gutterwidth, int numcolumns columns.AddRegularColumns(36f, doc.PageSize.Width - 36f, 24f, 2); Paragraphpara = newParagraph(text, newFont(Font.HELVETICA, 8f)); para.SpacingAfter = 9f; para.Alignment = Element.ALIGN_JUSTIFIED; for (int i = 0; i < 8; i++) { columns.AddElement(para); } doc.Add(columns); } catch (Exception ex) { //Log(ex.Message); } finally { doc.Close(); }
The result shows how the text just flowed from one column to
another once the first column was filled.
AddRegularColumns() will set each column at exactly the same width.
AddSimpleColumn() allows you to specify the width of individual columns, which
means that you can work with irregularly sized columns:
columns.AddSimpleColumn(36f, 170f); columns.AddSimpleColumn(194f, doc.PageSize.Width - 36f);
The code above replaces the AddRegularColumn() call
in the preceding block and creates two separate column objects. The first
starts at the left margin (36 points in from the left edge) and is 2 inches
wide (170 - 36 = 144 points). The second column starts 24 points (1/3 of an
inch) further over and butts up against the right hand margin.
Adding other elements such as images and tables is
straightforward:
string pdfpath = Server.MapPath("PDFs"); string pdfpath = Server.MapPath("PDFs"); string imagepath = Server.MapPath("Images"); Document doc = new Document(); try { PdfWriter.GetInstance(doc, new FileStream(pdfpath + "/Columns1.pdf", FileMode.Create)); doc.Open(); Paragraph heading = new Paragraph("Page Heading", newFont(Font.HELVETICA, 28f, Font.BOLD)); heading.SpacingAfter = 18f; doc.Add(heading); string text = @"Loremipsum dolor sit amet, consectetueradipiscingelit. Suspendisseblanditblanditturpis.Nam in lectusut dolor consectetuerbibendum.Morbinequeipsum, laoreet id; dignissimet, viverra id, mauris. Nullamauriselit, consectetuer sit amet, accumsaneget, congue ac, libero. Vivamussuscipit.Nuncdignissimconsectetuerlectus.Fusceelit nisi; commodonon, facilisisquis, hendreriteu, dolor? Suspendisseeleifend nisi ut magna.Phasellus id lectus! Vivamuslaoreetenimet dolor. Integer arcumauris, ultriciesvel, portaquis, venenatis at, libero.Donecnibhest, adipiscing et, ullamcorper vitae, placerat at, diam. Integer ac turpisvel ligula rutrumauctor! Morbiegestaserat sit amet diam. Ututipsum? Aliquam non sem. Nullarisuseros, mollisquis, blanditut; luctuseget, urna.Vestibulumvestibulumdapibuserat.Proinegestasleo a metus?"; MultiColumnText columns = new MultiColumnText(); columns.AddSimpleColumn(36f, 336f); columns.AddSimpleColumn(360f, doc.PageSize.Width - 36f); Paragraphpara = new Paragraph(text, new Font(Font.HELVETICA, 8f)); para.SpacingAfter = 9f; para.Alignment = Element.ALIGN_JUSTIFIED; PdfPTable table = new PdfPTable(3); float[] widths = new float[] { 1f, 1f, 1f }; table.TotalWidth = 300f; table.LockedWidth = true; table.SetWidths(widths); PdfPCell cell = new PdfPCell(newPhrase("Header spanning 3 columns")); cell.Colspan = 3; cell.HorizontalAlignment = 0; table.AddCell(cell); table.AddCell("Col 1 Row 1"); table.AddCell("Col 2 Row 1"); table.AddCell("Col 3 Row 1"); table.AddCell("Col 1 Row 2"); table.AddCell("Col 2 Row 2"); table.AddCell("Col 3 Row 2"); iTextSharp.text.Image jpg = iTextSharp.text.Image.GetInstance(imagepath + "/Jellyfish.jpg"); jpg.ScaleToFit(300f, 300f); jpg.SpacingAfter = 12f; jpg.SpacingBefore = 12f; columns.AddElement(para); columns.AddElement(table); columns.AddElement(jpg); columns.AddElement(para); columns.AddElement(para); columns.AddElement(para); columns.AddElement(para); doc.Add(columns); } catch (Exception ex) { //Log(ex.Message); } finally { doc.Close(); }
The example above takes a table and images
from previous tutorials, and adds them together with the paragraph to the
columns. the first column is 300 points wide, and the second one takes up the
remainder of the page width.
MultiColumnText is great for creating columns
without too much code, but it lacks an element of control. ColumnText provides
much more, but requires more code. The following sample shows ColumnText being
used to create irregular columns, in that the first one has chunk taken from
the top left corner to accommodate an image which is shown here in the
resulting PDF:
string pdfpath = Server.MapPath("PDFs"); string imagepath = Server.MapPath("Images"); FontFactory.RegisterDirectory("C:\\WINDOWS\\Fonts"); Document doc = new Document(); Font font1 = new Font(FontFactory.GetFont("adobe garamond pro", 36f, Color.GRAY)); Font font2 = new Font(Font.TIMES_ROMAN, 9f); doc.SetMargins(45f, 45f, 60f, 60f); try { FileStream output = new FileStream(pdfpath + "/IrregularColumns.pdf", FileMode.Create); PdfWriter writer = PdfWriter.GetInstance(doc, output); doc.Open(); PdfContentBytecb = writer.DirectContent; ColumnTextct = new ColumnText(cb); ct.Alignment = Element.ALIGN_JUSTIFIED; Paragraph heading = new Paragraph("Chapter 1", font1); heading.Leading = 40f; doc.Add(heading); iTextSharp.text.Image L = iTextSharp.text.Image.GetInstance(imagepath + "/ajax-loader(1).gif"); L.SetAbsolutePosition(doc.Left, doc.Top - 180); doc.Add(L); ct.AddText(new Phrase("oremipsum dolor sit amet, consectetueradipiscingelit. Suspendisseblanditblanditturpis.Nam in lectusut dolor consectetuerbibendum.Morbinequeipsum, laoreet id; dignissimet, viverra id, mauris. Nullamauriselit, consectetuer sit amet, accumsaneget, congue ac, libero. Vivamussuscipit.Nuncdignissimconsectetuerlectus.Fusceelit nisi; commodonon, facilisisquis, hendreriteu, dolor? Suspendisseeleifend nisi ut magna.Phasellus id lectus! Vivamuslaoreetenimet dolor. Integer arcumauris, ultriciesvel, portaquis, venenatis at, libero.Donecnibhest, adipiscing et, ullamcorper vitae, placerat at, diam. Integer ac turpisvel ligula rutrumauctor! Morbiegestaserat sit amet diam. Ututipsum? Aliquam non sem. Nullarisuseros, mollisquis, blanditut; luctuseget, urna.Vestibulumvestibulumdapibuserat.Proinegestasleo a metus?\n\n", font2)); ct.AddText(new Phrase("Vivamusenim nisi, mollis in, sodalesvel, convallis a, augue? Proin non enim.Nullamelementumeuismoderat.Aliquammalesuadaeleifend quam! Nullafacilisi.Aeneanutturpis ac esttempormalesuada. Maecenas scelerisqueorci sit ametauguelaoreet tempus. Duisinterdumestuteros. Fusce dictum dignissimelit.Morbi at dolor.Fusce magna.Nullatellusturpis, mattisut, eleifend a, adipiscing vitae, mauris.Pellentesquemattislobortis mi.\n\n", font2)); ct.AddText(new Phrase("Nullam sit ametmetusscelerisquediamhendreritporttitor. Aeneanpellentesque, lorem a consectetuerconsectetuer, nuncmetushendrerit quam, mattisultricesloremtelluslaciniamassa. Aliquam sit ametodio. Proinmauris.Integer dictum quam a quam accumsanlacinia.Pellentesquepulvinarfeugiateros.Suspendisserhoncus.Sedconsectetuerleoeu nisi. Suspendissemassa! Sedsuscipit lacus sit ametelit! Aliquamsollicitudincondimentumturpis.Nuncutaugue! Maecenas eueros.Morbi in urnaconsectetueripsumvehiculatristique.\n\n", font2)); ct.AddText(new Phrase("Donecimperdietpurusvel ligula. Vestibulumtempor, odioutscelerisqueeleifend, nullasapienlaoreet dui; velaliquamarculiberoeu ante.Curabiturrutrumtristique mi. Sedlobortisiaculisarcu.Suspendissemauris.Aliquammetus lacus, elementumquis, mollis non, consequatnec, tortor.\n", font2)); ct.AddText(new Phrase("Quisque id diam. Utegestasleo a elit. Nulla in metus.Aliquamiaculisturpis non augue.Donec a nunc?Phaselluseueros.Nam luctus.Duiseu mi. Utmollis.Nullafacilisi.Loremipsumdolor sitamet, consectetueradipiscingelit. Class aptenttacitisociosquadlitoratorquent per conubia nostra, per inceptoshimenaeos.Aeneanpede.Nullafacilisi.Vestibulummattisadipiscingnulla.Praesentorci ante, mattis in, cursuseget, posueresed, mauris.\n\n", font2)); ct.AddText(new Phrase("Nullafacilisi. Nuncaccumsanrisusaliquet quam. Nam pellentesque! Aeneanporttitor.Aeneancongueullamcorpervelit.Phasellussuscipitplacerattellus.Vivamusdiamodio, tempus quis, suscipit a, dictum eu; lectus.Sedvelnisl.Utinterdumurnaeunibh.Praesentvehicula, orci id venenatisultrices, maurisurnamollis lacus, etblanditodio magna at enim. Pellentesqueloremfelis, ultricesquis, gravidased, pharetra vitae, quam.Maurisliberoipsum, pharetra a, faucibusaliquet, pellentesque in, mauris.Cras magna neque, interdumvel, variusnec; vulputate at, erat. Quisque vitae urna.Suspendissepotenti.Nullaluctuspurus at turpis! Vestibulum vitae dui.Nullamodio.\n\n", font2)); ct.AddText(new Phrase("Vestibulum ante ipsumprimis in faucibusorciluctus et ultricesposuerecubiliaCurae; Sedeget mi at semiaculishendrerit. Nullafacilisi.Etiamsedelit.In viverradapibussapien.Aliquam nisi justo, ornarenon, ultricies vitae, aliquam sit amet, risus! Cum sociisnatoquepenatibusetmagnis dis parturient montes, nasceturridiculus mus. Phasellusrisus. Vestibulumpretiumaugue non mi. Sed magna.In hachabitasseplateadictumst.Quisquemassa. Etiamviverradiampharetra ante.Phasellusfringillavelitutodio! Nam necnulla.\n\n", font2)); ct.AddText(new Phrase("Integer augue. Morbiorci.Sedquisnibh.Nullam ac magna id leofaucibusornare. Vestibulumegetlectus sit ametnuncfacilisisbibendum. Donecadipiscingconvallis mi. Cumsociisnatoquepenatibus et magnis dis parturient montes, nasceturridiculus mus. Vivamusenim. Mauris ligula lorem, pellentesquequis, semper sed, tristique sit amet, justo.Suspendissepotenti.Proin vitae enim.Morbi et nisi sit ametsapienve.\n\n", font2)); float gutter = 15f; float colwidth = (doc.Right - doc.Left - gutter) / 2; float[] left = { doc.Left + 90f , doc.Top - 80f, doc.Left + 90f, doc.Top - 170f, doc.Left, doc.Top - 170f, doc.Left ,doc.Bottom }; float[] right = { doc.Left + colwidth, doc.Top - 80f, doc.Left + colwidth, doc.Bottom }; float[] left2 = { doc.Right - colwidth, doc.Top - 80f, doc.Right - colwidth, doc.Bottom }; float[] right2 = {doc.Right, doc.Top - 80f, doc.Right, doc.Bottom }; int status = 0; int i = 0; //Checks the value of status to determine if there is more text //If there is, status is 2, which is the value of NO_MORE_COLUMN while (ColumnText.HasMoreText(status)) { if (i == 0) { //Writing the first column ct.SetColumns(left, right); i++; } else { //write the second column ct.SetColumns(left2, right2); } //Needs to be here to prevent app from hanging ct.YLine = doc.Top - 80f; //Commit the content of the ColumnText to the document //ColumnText.Go() returns NO_MORE_TEXT (1) and/or NO_MORE_COLUMN (2) //In other words, it fills the column until it has either run out of column, or text, or both status = ct.Go(); } } catch (Exception ex) { //Log(ex.Message); } finally { doc.Close(); }
ColumnText requires that you need a PDFContentByte
object. This is nearly always the case when you want to place stuff at fixed
positions. The code above starts by defining a document object, and then
creating some fonts to work with, as well as setting the margins of the
document (which needs to be done before the document is opened to take effect).
A PdfWriter object is created so that the PDFContentByte object can be
instantiated from its DirectContent property. Then a ColumnText object is
created using the PDFContentByte. A heading is added, followed by the illustrated
capital "L", which starts the Chapter. This is followed by a number
of Phrases, set out as paragraphs.
So, now the ColumnText object has its text content,
but nowhere to put it yet, so the two columns are created. The first array of
floats defines the irregular shape of the left hand side fo the first column
which has to the top corner chopped out of it to make way for the image. The
second array defines the straight right hand edge. The third and fourth arrays
take care of the regularly shaped second column. Two int variables are created
to hold the value of the status of the column with regard to whether there is
any more text to be added (status), and then the number of the column that is
currently being worked on (i).
ColumnText.HasMoreText(status) is a convenience
method that takes an int as a parameter. It examines the value of the parameter
to see if there is any more text to be added and returns true if there is. The
value that returns false is 1. It is initialised at 0 to start, so HasMoreText
returns true. Since i is also 0, the code executes to add the first column,
then the YLine is set to the top of the column. This must be done, otherwise
the application will just spin until the execution timeout occurs. Finally, the
ColumnText.Go() method is called. This actually commits the contents of the
ColumnText to the document, and also returns a value to the variable status. It
returns either NO_MORE_TEXT, which is 1, and/or NO_MORE_COLUMN (2). If
NO_MORE_TEXT is returned, everything has been written, otherwise the second
column is created and the text added to that. Once ColumnText.HasMoreText
returns false, the page is written.
Building on this, if the amount of text spans more
than one page, the routine can be rewritten to call Document.NewPage(), and if
Go() is called after each Phrase is added to the ColumnText object, it is
possible to obtain the current Y position on the page to establish how much
room there is left. this enables you to manage widows and orphans - single
lines of text that are belong to a paragraph that appear at the end of the
preceding page or column (orphans) or appear at the top of a new page or column
(widows). It is also possible to pass the parameter "false" into
Go(), which does not commit the text to the column, but still allows you to
obtain the position as if it was to allow you much finer control over layout.
Thanks for comments.....