Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Let me first give you a couple of links to look over when you get a chance:</p> <ol> <li><a href="https://stackoverflow.com/a/7838631/231316">ItextSharp support for HTML and CSS</a></li> <li><a href="https://stackoverflow.com/a/8066442/231316">How to apply font properties on while passing html to pdf using itextsharp</a></li> </ol> <p>These answers go deeper into what's going on and I recommend reading them when you get a chance. Specifically the second one will show you why you need to use <code>pt</code> instead of <code>px</code>.</p> <p>To answer your first question let me show you a different way to use the <code>HTMLWorker</code> class. This class has a static method on it called <code>ParseToList</code> that will convert HTML to a <code>List&lt;IElement&gt;</code>. The objects in that list are all iTextSharp specific versions of your HTML. Normally you would do a <code>foreach</code> on those and just add them to a document but you <em>can</em> modify them before adding which is what you want to do. Below is code that takes a static string and does that:</p> <pre><code>string file1 = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "File1.pdf"); using (FileStream fs = new FileStream(file1, FileMode.Create, FileAccess.Write, FileShare.None)) { using (Document doc = new Document(PageSize.LETTER)) { using (PdfWriter writer = PdfWriter.GetInstance(doc, fs)) { doc.Open(); //Our HTML string html = "&lt;table&gt;&lt;tr&gt;&lt;th&gt;First Name&lt;/th&gt;&lt;th&gt;Last Name&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Chris&lt;/td&gt;&lt;td&gt;Haas&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;"; //ParseToList requires a StreamReader instead of just a string so just wrap it using (StringReader sr = new StringReader(html)) { //Create a style sheet StyleSheet styles = new StyleSheet(); //...styles omitted for brevity //Convert our HTML to iTextSharp elements List&lt;IElement&gt; elements = iTextSharp.text.html.simpleparser.HTMLWorker.ParseToList(sr, styles); //Loop through each element (in this case there's actually just one PdfPTable) foreach (IElement el in elements) { //If the element is a PdfPTable if (el is PdfPTable) { //Cast it PdfPTable tt = (PdfPTable)el; //Change the widths, these are relative width by the way tt.SetWidths(new float[] { 75, 25 }); } //Add the element to the document doc.Add(el); } } doc.Close(); } } } </code></pre> <p>Hopefully you can see that once you get access to the raw <code>PdfPTable</code> you can tweak it as necessary.</p> <p>To answer your second question, if you want to use the normal <code>Paragraph</code> and <code>Chunk</code> objects with a <code>PdfStamper</code> then you need to use a <code>PdfContentByte</code> object. You can get this from your stamper in one of two ways, either by asking for one that sits "above" existing content, <code>stamper.GetOverContent(int)</code> or one that sits "below" existing content, <code>stamper.GetUnderContent(int)</code>. Both versions take a single parameter saying what page to work with. Once you have a <code>PdfContentByte</code> you can create a <code>ColumnText</code> object bound to it and use this object's <code>AddElement()</code> method to add your normal elements. Before doing this (and this answers your third question), you'll want to create at least one "column". When I do this I generally create one that essentially covers the entire page. (This part might sound weird but we're essentially make a single row, single column table cell to add our objects to.)</p> <p>Below is a full working C# 2010 WinForms app targeting iTextSharp 5.1.1.0 that shows off everything above. First it creates a generic PDF on the desktop. Then it creates a second document based off of the first, adds a paragraph and then some HTML. See the comments in the code for any questions.</p> <pre><code>using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using iTextSharp.text; using iTextSharp.text.html.simpleparser; using iTextSharp.text.pdf; using System.IO; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { //The two files that we are creating string file1 = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "File1.pdf"); string file2 = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "File2.pdf"); //Create a base file to write on top of using (FileStream fs = new FileStream(file1, FileMode.Create, FileAccess.Write, FileShare.None)) { using (Document doc = new Document(PageSize.LETTER)) { using (PdfWriter writer = PdfWriter.GetInstance(doc, fs)) { doc.Open(); doc.Add(new Paragraph("Hello world")); doc.Close(); } } } //Bind a reader to our first document PdfReader reader = new PdfReader(file1); //Create our second document using (FileStream fs = new FileStream(file2, FileMode.Create, FileAccess.Write, FileShare.None)) { using (PdfStamper stamper = new PdfStamper(reader, fs)) { StyleSheet styles = new StyleSheet(); //...styles omitted for brevity //Our HTML string html = "&lt;table&gt;&lt;tr&gt;&lt;th&gt;First Name&lt;/th&gt;&lt;th&gt;Last Name&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Chris&lt;/td&gt;&lt;td&gt;Haas&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;"; //ParseToList requires a StreamReader instead of just a string so just wrap it using (StringReader sr = new StringReader(html)) { //Get our raw PdfContentByte object letting us draw "above" existing content PdfContentByte cb = stamper.GetOverContent(1); //Create a new ColumnText object bound to the above PdfContentByte object ColumnText ct = new ColumnText(cb); //Get the dimensions of the first page of our source document iTextSharp.text.Rectangle page1size = reader.GetPageSize(1); //Create a single column object spanning the entire page ct.SetSimpleColumn(0, 0, page1size.Width, page1size.Height); ct.AddElement(new Paragraph("Hello world!")); //Convert our HTML to iTextSharp elements List&lt;IElement&gt; elements = iTextSharp.text.html.simpleparser.HTMLWorker.ParseToList(sr, styles); //Loop through each element (in this case there's actually just one PdfPTable) foreach (IElement el in elements) { //If the element is a PdfPTable if (el is PdfPTable) { //Cast it PdfPTable tt = (PdfPTable)el; //Change the widths, these are relative width by the way tt.SetWidths(new float[] { 75, 25 }); } //Add the element to the ColumnText ct.AddElement(el); } //IMPORTANT, this actually commits our object to the PDF ct.Go(); } } } this.Close(); } } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload