iTextSharp set header in onendpage for just first page in document - c#

How do you set the header to be on the first page of the document only.
As follows sets it on every page.
private class PDFAddHeaderTopOnly : PdfPageEventHelper
{
public PDFAddHeaderTopOnly(string html)
{
this.html = html;
}
public override void OnEndPage(PdfWriter writer, Document document)
{
base.OnEndPage(writer, document);
ColumnText ct = new ColumnText(writer.DirectContent);
XMLWorkerHelper.GetInstance().ParseXHtml(new ColumnTextElementHandler(ct), new StringReader(html));
ct.SetSimpleColumn(document.Left, document.Top, document.Right, document.GetTop(-PDFMarginTop), 0, Element.ALIGN_MIDDLE);
ct.Go();
}
string html = null;
}

In general
If you want to do something only on the first page, simply do it as the first action after opening the document and don't try to squeeze it into the page event framework which is designed for repetitive tasks.
In your case
Most likely you use your PDFAddHeaderTopOnly class like this:
string html = ...;
using (Document document = new Document()) {
PdfWriter writer = PdfWriter.GetInstance(document, stream);
writer.PageEvent = new PDFAddHeaderTopOnly(html);
document.Open();
[Add some content to document]
}
If you only want the header on the first page, do something like this instead:
using (Document document = new Document()) {
PdfWriter writer = PdfWriter.GetInstance(document, stream);
document.Open();
// Draw first-page-only header
ColumnText ct = new ColumnText(writer.DirectContent);
XMLWorkerHelper.GetInstance().ParseXHtml(new ColumnTextElementHandler(ct), new StringReader(html));
ct.SetSimpleColumn(document.Left, document.Top, document.Right, document.GetTop(-PDFMarginTop), 0, Element.ALIGN_MIDDLE);
ct.Go();
// Draw document content
[Add some content to document]
}

Related

Parser results in "The document has no pages"

Trying to generate a PDF with HTML/CSS by using ITextSharp v5. The error I get is "Document has no pages". Is my parser set up wrong? How do I get the parsed HTML added to my document?
public void ConvertHtmlToPdf(string xHtml, string css)
{
using (var stream = new FileStream("App_Data/pdfs/testt.pdf", FileMode.Create))
{
using (var document = new Document(PageSize.A4, 10f, 10f, 10f, 0f))
{
var writer = PdfWriter.GetInstance(document, stream);
document.Open();
// instantiate custom tag processor and add to `HtmlPipelineContext`.
var tagProcessorFactory = Tags.GetHtmlTagProcessorFactory();
var htmlPipelineContext = new HtmlPipelineContext(null);
htmlPipelineContext.SetTagFactory(tagProcessorFactory);
var pdfWriterPipeline = new PdfWriterPipeline(document, writer);
var htmlPipeline = new HtmlPipeline(htmlPipelineContext, pdfWriterPipeline);
// get an ICssResolver and add the custom CSS
var cssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(true);
cssResolver.AddCss(css, "utf-8", true);
var cssResolverPipeline = new CssResolverPipeline(
cssResolver, htmlPipeline
);
var worker = new XMLWorker(cssResolverPipeline, true);
var parser = new XMLParser(worker);
using (var stringReader = new StringReader(xHtml))
{
parser.Parse(stringReader);
}
document.Close();
writer.Close();
}
}
}
The document is empty as no data is written to it from Worker classes.
Immediately after opening the document, always add an empty chunk to document so that you can avoid this exception.
document.add(new Chunk(''));
To Convert HTML to PDF, you can check this example
How to convert HTML to PDF using iText

ItextSharp PDF Header Footer Repetition Issue

I have used Itextsharp from Nuget Package and parsed HTML to PDF and passed Bytes to frontend of website and showing the PDF on iframe.
Firstly i had two separate HTML for the PDF,i.e., one for the header and other one for the body. When i used to parse the HTML to PDF, the issue which came across was the repetition of header. Header is works fine on the first page but on the second page header and body overlap each other. I tried a lot by overriding OnStartPage and OnEndPage function but nothing worked.
Secondly I tried header through C# code and body through HTML but that also seems not be not working and having the same issue.
I think the main issue is with page break(correct me if i am wrong). If any of you from the community can help me out please go forward. I am sharing the code and really appreciate all the help.
Please let me know if any code is missing. I need header on every page that need to be consistent but with dynamic content.
using System;
using System.Collections.Generic;
using iTextSharp.text.html.simpleparser;
namespace WebApi.Controllers
{
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.tool.xml;
using iTextSharp.tool.xml.css;
using iTextSharp.tool.xml.html;
using iTextSharp.tool.xml.parser;
using iTextSharp.tool.xml.pipeline.css;
using iTextSharp.tool.xml.pipeline.end;
using iTextSharp.tool.xml.pipeline.html;
using System.IO;
using System.Text;
using System.Web.Mvc;
public class PDFGenerateController : Controller
{
[NonAction]
public byte[] Index(IModel iModel)
{
// get HTML for body
var html = GetHtml(iModel, false);
byte[] bytes;
Document pdfDocument = new Document(PageSize.A4);
using (MemoryStream memoryStream = new MemoryStream())
{
PdfWriter writer = PdfWriter.GetInstance(pdfDocument, memoryStream);
AddImageToHeader pageEventHandler = new AddImageToHeader(GetHtml(processedData, true)); // get html for header right side
IHeaderFooter iHeaderFooter = new IHeaderFooter(GetHtml(processedData, true)); // get html for header right side
writer.PageEvent = iHeaderFooter;
writer.PageEvent = pageEventHandler;
writer.PageEvent = new HeaderFooterAdd(iModel);
writer.CloseStream = false;
pdfDocument.Open();
HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
htmlContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory());
ICSSResolver cssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(false);
cssResolver.AddCssFile("C:/pdf.css", true);
IPipeline pipeline = new CssResolverPipeline(cssResolver, new HtmlPipeline(htmlContext,
new PdfWriterPipeline(pdfDocument, writer)));
XMLWorker worker = new XMLWorker(pipeline, true);
XMLParser xmlParser = new XMLParser(worker);
xmlParser.Parse(new MemoryStream(Encoding.UTF8.GetBytes(html)));
pdfDocument.Close();
bytes = memoryStream.GetBuffer();
memoryStream.Close();
}
return bytes;
}
public class iHeaderFooter : PdfPageEventHelper
{
private readonly string _html;
public iHeaderFooter(string html)
{
_html = html;
}
public override void OnStartPage(PdfWriter writer, Document document)
{
var cssResolver = new StyleAttrCSSResolver();
XMLWorkerFontProvider fontProvider =
new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
htmlContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory());
PdfWriterPipeline pdf = new PdfWriterPipeline(document, writer);
HtmlPipeline html1 = new HtmlPipeline(htmlContext, pdf);
CssResolverPipeline css = new CssResolverPipeline(cssResolver, html1);
XMLWorker worker = new XMLWorker(css, true);
XMLParser p = new XMLParser(worker);
p.Parse(new StringReader(_html));
//for page break but didn't worked out
/*using (TextReader htmlViewReader = new StringReader(_html))
{
using (var htmlWorker = new HeaderFooterAdd.HTMLWorkerExtended(document))
{
htmlWorker.Open();
htmlWorker.Parse(htmlViewReader);
}
}*/
base.OnStartPage(writer, document);
}
}
}
// Add logo image to header left side
public class AddImageToHeader : PdfPageEventHelper
{
private readonly string _html;
public AddImageToHeader(string html)
{
_html = html;
}
public override void OnStartPage(PdfWriter writer, Document document)
{
iTextSharp.text.Image imghead = iTextSharp.text.Image.GetInstance("C:/logo.png");
imghead.ScaleAbsolute(189f, 79f);
imghead.SetAbsolutePosition(30, 0);
PdfContentByte cbhead = writer.DirectContent;
PdfTemplate tp = cbhead.CreateTemplate(320, 100);
tp.AddImage(imghead);
cbhead.AddTemplate(tp, 0, 830 - 95);
base.OnStartPage(writer, document);
}
}
public class HeaderFooterAdd : PdfPageEventHelper
{
//C# Header
public override void OnEndPage(PdfWriter writer, Document document)
{
PdfPTable tbHeader = new PdfPTable(2);
tbHeader.TotalWidth = document.PageSize.Width - document.LeftMargin - document.RightMargin;
tbHeader.DefaultCell.Border = Rectangle.NO_BORDER;
tbHeader.DefaultCell.BorderWidth = 0;
tbHeader.DefaultCell.Top = 100;
tbHeader.DefaultCell.Bottom = 100;
tbHeader.AddCell(new Paragraph());
Phrase datePhrase = new Phrase(new Chunk($"{"Label"}: {"Text"}\n", FontFactory.GetFont(FontFactory.TIMES, 10, Font.NORMAL, BaseColor.BLACK)));
PdfPCell _cell = new PdfPCell(datePhrase);
_cell.HorizontalAlignment = Element.ALIGN_RIGHT;
_cell.BorderWidthBottom = 0f;
_cell.BorderWidthLeft = 0f;
_cell.BorderWidthTop = 0f;
_cell.BorderWidthRight = 0f;
_cell.PaddingTop = 45f;
_cell.ExtraParagraphSpace = 2f;
tbHeader.AddCell(_cell);
tbHeader.AddCell(new Paragraph());
tbHeader.WriteSelectedRows(0, -1, document.Left,
writer.PageSize.GetTop(document.TopMargin) + 40,
writer.DirectContent);
}
//for page break but didn't worked out
/*public class HTMLWorkerExtended : HTMLWorker
{
public HTMLWorkerExtended(IDocListener document) :
base(document)
{
}
public override void StartElement(string tag,
IDictionary<string, string> str)
{
if (tag.Equals("newpage"))
document.Add(Chunk.NEXTPAGE);
else
base.StartElement(tag, str);
}
}*/
}

Cannot access a non-static member of outer type 'System.Web.UI.Page' via nested type 'PrintToPdf._events'

I have been trying to add an image to all pages using iTextSharp.
According to this web page I need to look into the PdfPageEventHelper of iTextSharp.
It provides a method called OnEndPage that allows such things.
Basically, treat the image as being in the header or footer of the document, and use absolute positioning to put it where you want, instead of just in the flow of the page content.
The below code response with error :
Cannot access a non-static member of outer type 'System.Web.UI.Page'
via nested type 'PrintToPdf._events'
On :
PdfPCell cell2 = new PdfPCell(Image.GetInstance(Server.MapPath(imagepath)));
Is there any way to insert the image in the same way in all pages?
Can you help me ?
Thank you in advance.
class _events : PdfPageEventHelper
{
public override void OnEndPage(PdfWriter writer, Document document)
{
PdfPTable table = new PdfPTable(1);
table.TotalWidth = document.PageSize.Width - document.LeftMargin - document.RightMargin;
PdfPTable table2 = new PdfPTable(2);
string imagepath = #"Img\Logo.jpg";
PdfPCell cell2 = new PdfPCell(Image.GetInstance(Server.MapPath(imagepath)));
cell2.Colspan = 2;
table2.AddCell(cell2);
PdfPCell cell = new PdfPCell(table2);
table.AddCell(cell);
table.WriteSelectedRows(0, -1, document.LeftMargin, document.PageSize.Height - 36, writer.DirectContent);
}
}
private void PdfFiles()
{
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=test.pdf");
Response.Cache.SetCacheability(HttpCacheability.NoCache);
StringWriter sw = new StringWriter();
HtmlTextWriter hw = new HtmlTextWriter(sw);
pnPrint.RenderControl(hw);
StringReader sr = new StringReader(sw.ToString());
string imagepath = #"Img\Logo.jpg";
Document pdfDoc = new Document(PageSize.A4, 20f, 20f, 10f, 20f);
try
{
_events e = new _events();
PdfWriter pw = PdfWriter.GetInstance(pdfDoc, new FileStream("test.pdf", FileMode.Create));
pw.PageEvent = e;
HTMLWorker htmlparser = new HTMLWorker(pdfDoc);
PdfWriter.GetInstance(pdfDoc, Response.OutputStream);
pdfDoc.Open();
for (int i = 0; i < 5; i++)
{
Image image = Image.GetInstance(Server.MapPath(imagepath));
image.Alignment = Image.ALIGN_LEFT;
pdfDoc.Add(image);
htmlparser.Parse(sr);
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
pdfDoc.Close();
Response.End();
}
}
Edit #1
protected class MyEvent : PdfPageEventHelper
{
Image image;
public override void OnOpenDocument(PdfWriter writer, Document document)
{
image = Image.GetInstance(#"C:\\intepub\\wwwroot\\img\\Logo.jpg");
image.SetAbsolutePosition(12, 300);
}
public override void OnEndPage(PdfWriter writer, Document document)
{
writer.DirectContent.AddImage(image);
}
}
// step 1
Document pdfDoc = new Document(PageSize.A4, 20f, 20f, 10f, 20f);
// step 2
PdfWriter writer = PdfWriter.GetInstance(pdfDoc, Response.OutputStream);
MyEvent e = new MyEvent();
writer.PageEvent = e;
// step 3
pdfDoc.Open();
// step 4
pdfDoc.Add(new Paragraph("Hello World!"));
// step 5
pdfDoc.Close();

Creating multiple page pdf using iTextSharp

I am trying to create pdf with multiple pages using iTextSharp
Document document = new Document(PageSize.A4, 2, 2, 10, 10);
private PdfContentByte _pcb;
try
{
PdfWriter writer = PdfWriter.GetInstance(document, output);
document.Open();
document.NewPage();
_pcb = writer.DirectContent;
_pcb.BeginText();
_pcb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, text, x, y, 0);
_pcb.EndText();
writer.Flush();
}
catch(e)
{
}
finally
{
document.Close();
}
This is working fine for me. When I am trying to add a new page on the same document, it is replacing the existing written text with new page and no new page is getting added. Below is the code which is not working.
_pcb.EndText();
writer.Flush();
document.NewPage();
_pcb = writer.DirectContent;
_pcb.BeginText();
_pcb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, text, x, y, 0);
_pcb.EndText();
writer.Flush();
Below is my attempt to clean-up and unify your code. Generally avoid try-catch until you actually have to, you'll often miss some very important errors. (For instance, you're not actually setting the font and size which is required but maybe you just omitted that code.) Also, unless you are writing a very large PDF there's really no reason to flush the buffers, leave that to the OS to do for you when necessary.
When I run the code below I get two pages with text on both pages, does it work for you? (Targeting iTextSharp 5.2.0.0)
var output = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Output.pdf");
var bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1250, BaseFont.NOT_EMBEDDED);
using (FileStream fs = new FileStream(output, FileMode.Create, FileAccess.Write, FileShare.None)) {
using (Document doc = new Document(PageSize.A4, 2, 2, 10, 10)) {
PdfContentByte _pcb;
using (PdfWriter writer = PdfWriter.GetInstance(doc, fs)) {
//Open document for writing
doc.Open();
//Insert page
doc.NewPage();
//Alias to DirectContent
_pcb = writer.DirectContent;
//Set the font and size
_pcb.SetFontAndSize(bf, 12);
//Show some text
_pcb.BeginText();
_pcb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, "Page 1", 40, 600, 0);
_pcb.EndText();
//Insert a new page
doc.NewPage();
//Re-set font and size
_pcb.SetFontAndSize(bf, 12);
//Show more text on page 2
_pcb.BeginText();
_pcb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, "Page 2", 100, 400, 0);
_pcb.EndText();
doc.Close();
}
}
}
Why do you use the DirectContent? If you just want to create a PDF from scratch, just add content to the Document.
try
{
iTextSharp.text.Document doc = new iTextSharp.text.Document();
PdfWriter.GetInstance(doc, new FileStream("HelloWorld.pdf", FileMode.Create));
doc.Open();
doc.Add(new Paragraph("Hello World!"));
doc.NewPage();
doc.Add(new Paragraph("Hello World on a new page!"));
}
catch (Exception ex)
{
}
finally
{
doc.Close();
}
Below Code is working
string str = "Page1Page1Page1Page1Page1Page1Page1Page1Page1Page1";
string str2 = "Page2Page2Page2Page2Page2Page2Page2Page2Page2Page2";
Document pdfDoc = new Document(PageSize.A4, 10f, 10f, 10f, 0f);
PdfWriter.GetInstance(pdfDoc, Response.OutputStream);
pdfDoc.Open();
using (var htmlWorker = new HTMLWokExtend(pdfDoc))
{
using (var sr = new StringReader(str))
{
htmlWorker.Parse(sr);
}
}
pdfDoc.NewPage();
using (var htmlWorker = new HTMLWokExtend(pdfDoc))
{
using (var sr = new StringReader(str2))
{
htmlWorker.Parse(sr);
}
}
pdfDoc.Close();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;" +
"filename=Proforma_Invoice.pdf");
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Write(pdfDoc);
Response.End();
You can populate string from HTML body using below function
private string populatebody()
{
string body="";
using (StreamReader reader = new StreamReader(Server.MapPath("~/Dir/Page.html")))
{
body = reader.ReadToEnd();
}
body = body.Replace("{Content in htmlpage}", "Your Content");
return body
}
And then return this body to string in upper code.
You can manipulate with this code as per your requirement.
Below is HTMLWokExtend Class:
public class HTMLWokExtend : HTMLWorker
{
LineSeparator line = new LineSeparator(1f, 90f, BaseColor.GRAY, Element.ALIGN_CENTER, -12);
public HTMLWokExtend(IDocListener document) : base(document)
{
}
public override void StartElement(string tag, IDictionary<string, string> str)
{
if (tag.Equals("hrline"))
document.Add(new Chunk(line));
else
base.StartElement(tag, str);
}
}

iTextSharp HTMLWorker ParseHTML Tablestyle and PDFStamper

Hi I have succesfully used a HTMLWorker to convert a gridview using asp.NET / C#.
(1) I have applied some limited style to the resulting table but cannot see how to apply tablestyle for instance grid lines or apply other formatting style such as a large column width for example for a particular column.
(2) I would actually like to put this text onto a pre-existing template which contains a logo etc. I've used PDF Stamper before for this but cannot see how I can use both PDFStamper and HTMLWorker at once. HTMLWorker needs a Document which implements iDocListener ... but that doesnt seem compatible with usign a PDFStamper. I guess what I am looking for is a way to create a PDFStamper, write title etc, then add the parsed HTML from the grid. The other problem is that the parsed content doesnt interact with the other stuff on the page. For instance below I add a title chunk to the page. Rather than starting below it, the parsed HTML writes over the top. How do I place / interact the parsed HTML content with the rest of what is on the PDF document ?
Thanks in advance
Rob
Here';s the code I have already
Document pdfDoc = new Document(PageSize.A4, 10f, 10f, 30f, 0f);
HTMLWorker htmlWorker = new HTMLWorker(pdfDoc);
StyleSheet styles = new StyleSheet();
styles.LoadTagStyle("th", "size", "12px");
styles.LoadTagStyle("th", "face", "helvetica");
styles.LoadTagStyle("span", "size", "10px");
styles.LoadTagStyle("span", "face", "helvetica");
styles.LoadTagStyle("td", "size", "10px");
styles.LoadTagStyle("td", "face", "helvetica");
htmlWorker.SetStyleSheet(styles);
PdfWriter.GetInstance(pdfDoc, HttpContext.Current.Response.OutputStream);
pdfDoc.Open();
//Title - but this gets obsured by data, doesnt move it down
Font font = new Font(Font.FontFamily.HELVETICA, 14, Font.BOLD);
Chunk chunk = new Chunk(title, font);
pdfDoc.Add(chunk);
//Body
htmlWorker.Parse(sr);
Let me first give you a couple of links to look over when you get a chance:
ItextSharp support for HTML and CSS
How to apply font properties on while passing html to pdf using itextsharp
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 pt instead of px.
To answer your first question let me show you a different way to use the HTMLWorker class. This class has a static method on it called ParseToList that will convert HTML to a List<IElement>. The objects in that list are all iTextSharp specific versions of your HTML. Normally you would do a foreach on those and just add them to a document but you can modify them before adding which is what you want to do. Below is code that takes a static string and does that:
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 = "<table><tr><th>First Name</th><th>Last Name</th></tr><tr><td>Chris</td><td>Haas</td></tr></table>";
//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<IElement> 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();
}
}
}
Hopefully you can see that once you get access to the raw PdfPTable you can tweak it as necessary.
To answer your second question, if you want to use the normal Paragraph and Chunk objects with a PdfStamper then you need to use a PdfContentByte object. You can get this from your stamper in one of two ways, either by asking for one that sits "above" existing content, stamper.GetOverContent(int) or one that sits "below" existing content, stamper.GetUnderContent(int). Both versions take a single parameter saying what page to work with. Once you have a PdfContentByte you can create a ColumnText object bound to it and use this object's AddElement() 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.)
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.
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 = "<table><tr><th>First Name</th><th>Last Name</th></tr><tr><td>Chris</td><td>Haas</td></tr></table>";
//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<IElement> 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();
}
}
}
protected void LinkPdf_Click(object sender, EventArgs e)
{
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=TestPage.pdf");
Response.Cache.SetCacheability(HttpCacheability.NoCache);
StringWriter sw = new StringWriter();
HtmlTextWriter hw = new HtmlTextWriter(sw);
this.Page.RenderControl(hw);
StringReader sr = new StringReader(sw.ToString());
Document pdfDoc = new Document(PageSize.A4, 10f, 10f, 100f, 0f);
HTMLWorker htmlparser = new HTMLWorker(pdfDoc);
PdfWriter.GetInstance(pdfDoc, Response.OutputStream);
pdfDoc.Open();
htmlparser.Parse(sr);
pdfDoc.Close();
Response.Write(pdfDoc);
Response.End();
}

Categories

Resources