I don't understand why it is not working.
Here is my code:
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=Panel.pdf");
Response.Cache.SetCacheability(HttpCacheability.NoCache);
StringWriter sw = new StringWriter();
HtmlTextWriter hw = new HtmlTextWriter(sw);
string htmlstr = "<html><body><h1>My First Heading</h1><p>My first paragraph.</p><table border=1><tr><td>1st</td><td>2nd</td></tr><tr><td>3rd</td><td>4th</td></tr></table></body></html>";
Panel panel1 = new Panel();
panel1.Controls.Add(new LiteralControl(htmlstr));
panel1.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();
My PDF is generated but the table is not showing ...
You've got some crazy code there (which appears to be from here). You've got an HTML string but then your dumping it into an ASP.Net control which you're further dumping into another ASP.Net control. Then you're asking ASP.Net to render the control back to HTML. That's three or four lines you can kill off.
Also, you're writing to the raw HTTP response stream and then sending the PDF to the same stream. This is your bigger problem, actually. I strongly suggest never writing to the raw stream until you're absolutely done processing things. You've also changed the HTTP headers which can cause problems if there are ASP.Net errors.
The below code is a rework of what you've got. I switched it over to using statements to ensure that things get cleaned up. If you're using an older unsupported version of iTextSharp you'll want to switch those back.
string htmlstr = "<html><body><h1>My First Heading</h1><p>My first paragraph.</p><table border=1><tr><td>1st</td><td>2nd</td></tr><tr><td>3rd</td><td>4th</td></tr></table></body></html>";
//We'll store our final PDF in this
byte[] bytes;
//Read our HTML as a .Net stream
using (var sr = new StringReader(htmlstr)) {
//Standard PDF setup using a MemoryStream, nothing special
using (var ms = new MemoryStream()) {
using (var pdfDoc = new Document(PageSize.A4, 10f, 10f, 100f, 0f)) {
//Bind a parser to our PDF document
using (var htmlparser = new HTMLWorker(pdfDoc)) {
//Bind the writer to our document and our final stream
using (var w = PdfWriter.GetInstance(pdfDoc, ms)) {
pdfDoc.Open();
//Parse the HTML directly into the document
htmlparser.Parse(sr);
pdfDoc.Close();
//Grab the bytes from the stream before closing it
bytes = ms.ToArray();
}
}
}
}
}
//Assuming that the above worked we can now finally modify the HTTP response
Response.Clear();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=BusinessUnit.pdf");
Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);
//Send the bytes from the PDF
Response.BinaryWrite(bytes);
Response.End();
Related
I am trying to save a panel to pdf using ITextSharp. When I set a breakpoint and debug, the code stops on this line of code, however it does not give an error and just stops.
if (IsPostBack)
{
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=Quote.pdf");
Response.Cache.SetCacheability(HttpCacheability.NoCache);
StringWriter sw = new StringWriter();
HtmlTextWriter hw = new HtmlTextWriter(sw);
**Panel1.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();
}
In the panel I have textboxes, labels and GridView.
You've got a couple of problems. If you're getting a The document has no pages message that means no content was added to the PDF which almost definitely means that there's a problem with the RenderControl method and nothing to do with iTextSharp. Another problem is that you are writing to the Response.OutputStream as well as outputting the literal document by using Response.Write(pdfDoc). You only need to do the former, I'm not actually sure what would happen with the latter.
The The document has no pages message also could mean that iTextSharp couldn't find anything to create content from. So you might have valid HTML but iTextSharp just doesn't know what to do with it. This probably isn't the case but I just had to mention it.
I'm going to break your code up into steps to help debug things. The first two blocks convert the control to HTML and then sanity checks it to make sure we've got something. You should inspect the contents of buf if you have any problems.
The third block creates a PDF from a MemoryStream and then dumps it into a byte array instead of writing directly to the Response.OutputStream. Although there's nothing incorrect with writing to the Response.OutputStream you will often find that you're swallowing errors and in general debugging is much harder. Once this block is done you should inspect bytes to make sure it has something.
The last block does the final push to the browser.
//Convert our control to HTML
string buf;
using (var sw = new StringWriter()) {
using (var hw = new HtmlTextWriter(sw)) {
Panel1.RenderControl(hw);
}
buf = sw.ToString();
}
//Sanity check
if (String.IsNullOrWhiteSpace(buf)) {
throw new ApplicationException("No content found");
}
//Create our PDF and get a byte array
byte[] bytes;
using (var ms = new MemoryStream()) {
using (var pdfDoc = new Document(PageSize.A4, 10f, 10f, 100f, 0f)) {
using (var writer = PdfWriter.GetInstance(pdfDoc, ms)) {
pdfDoc.Open();
using (var htmlparser = new HTMLWorker(pdfDoc)) {
using (var sr = new StringReader(buf)) {
htmlparser.Parse(sr);
}
}
pdfDoc.Close();
}
}
bytes = ms.ToArray();
}
//Output the PDF
Response.Clear();
Response.AddHeader("content-disposition", "attachment;filename=Quote.pdf");
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.BinaryWrite(bytes);
Response.End();
I have a query related to PDF generation from HTML code. I have a table written in HTML code and I want to parse it in a PDF writer using iTextSharp.dll, I have been using the same code with different html content in another section of my website and it is working absolutely fine.
Here is my code below please do comment.
StringBuilder sb = new StringBuilder();
sb.Append("<table width='100%' cellspacing='5' cellpadding='3'>");
//sb.Append("<tr><td colspan=4><img src='logo.png' width='250px' height = '70px'/></td></tr>");
sb.Append("<tr><td></td><td colspan=2 align=center>JK Cement Works, Jharli</td><td></td></tr>");
sb.Append("<tr><td>Duplicate Tickets</td><td></td><td></td><td></td></tr>");
sb.Append("<tr><td>Print DateTime:</td><td>");
sb.Append(printDT.Text.ToString());
sb.Append("</td><td></td><td></td></tr>");
sb.Append("<tr><td></td><td></td><td></td><td></td></tr>");
sb.Append("<tr><td>Transaction Number</td><td>");
sb.Append(tNum.Text.ToString());
sb.Append("</td><td></td><td></td></tr>");
sb.Append("<tr><td>Truck Number</td><td>");
sb.Append(TruckNum.Text.ToString());
sb.Append("</td><td></td><td></td></tr>");
sb.Append("<tr><td>Product Code</td><td>");
sb.Append(pCode.Text.ToString());
sb.Append("</td><td>Product Name</td><td>");
sb.Append(pName.Text.ToString());
sb.Append("</td></tr>");
sb.Append("<tr><td>Supplier Code</td><td>");
sb.Append(sCode.Text.ToString());
sb.Append("</td><td>Supplier Name</td><td>");
sb.Append(sName.Text.ToString());
sb.Append("</td></tr>");
sb.Append("<tr><td>Transporter Code</td><td>");
sb.Append(tCode.Text.ToString());
sb.Append("</td><td>Transporter Name</td><td>");
sb.Append(tName.Text.ToString());
sb.Append("</td></tr>");
sb.Append("<tr><td>Challan Number</td><td>");
sb.Append(challanNum.Text.ToString());
sb.Append("</td><td>Challan DateTime</td><td>");
sb.Append(challanDT.Text.ToString());
sb.Append("</td></tr>");
sb.Append("<tr><td></td><td></td><td></td><td></td></tr>");
sb.Append("<tr><td colspan=2>Delivery Note Number</td><td></td><td></td></tr>");
sb.Append("<tr><td>Shift</td><td>");
sb.Append(shift.Text.ToString());
sb.Append("</td><td></td><td></td></tr>");
sb.Append("<tr><td></td><td></td><td></td><td></td></tr>");
sb.Append("<tr><td>IN DateTime</td><td>");
sb.Append(InDT.Text.ToString());
sb.Append("</td><td>Gross Weight</td><td>");
sb.Append(gWeight.Text.ToString());
sb.Append(" Tons</td></tr>");
sb.Append("<tr><td>Out DateTime</td><td>");
sb.Append(OutDT.Text.ToString());
sb.Append("</td><td>Tare Weight</td><td>");
sb.Append(tWeight.Text.ToString());
sb.Append(" Tons</td></tr>");
sb.Append("<tr><td></td><td></td><td>Net Weight</td><td>");
sb.Append(nWeight.Text.ToString());
sb.Append(" Tons</td></tr></table>");
StringReader sr = new StringReader(sb.ToString());
Document pdfDoc = new Document(PageSize.A4.Rotate(), 10f, 10f, 10f, 0f);
HTMLWorker htmlparser = new HTMLWorker(pdfDoc);
PdfWriter.GetInstance(pdfDoc, Response.OutputStream);
pdfDoc.Open();
htmlparser.Parse(sr);
pdfDoc.Close();
Response.Clear();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=InvoiceSJ.pdf");
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Write(pdfDoc);
Response.End();
You first write the PDF to the Response.OutputStream
Document pdfDoc = new Document(PageSize.A4.Rotate(), 10f, 10f, 10f, 0f);
HTMLWorker htmlparser = new HTMLWorker(pdfDoc);
PdfWriter.GetInstance(pdfDoc, Response.OutputStream);
pdfDoc.Open();
htmlparser.Parse(sr);
pdfDoc.Close();
only to immediately thereafter clear the Response (and so throw the PDF away)
Response.Clear();
and eventually output pdfDoc
Response.Write(pdfDoc);
which does not make sense because the iTextSharp Document class does not hold the PDF document, it merely is a front end class via which you provide content for the PDF. This content is forwarded to a PdfWriter which as soon as possible writes the content in PDF form to its output stream.
Please try, therefore, something along these lines:
[... create StringReader sr ...]
Response.Clear();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=InvoiceSJ.pdf");
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Document pdfDoc = new Document(PageSize.A4.Rotate(), 10f, 10f, 10f, 0f);
HTMLWorker htmlparser = new HTMLWorker(pdfDoc);
PdfWriter.GetInstance(pdfDoc, Response.OutputStream);
pdfDoc.Open();
htmlparser.Parse(sr);
pdfDoc.Close();
Response.End();
Depending on the very browser and version, a Content-Length header might be required. If the above does not work for you yet, therefore, please try writing the PDF to a MemoryStream and get the PDF as a byte[], then initialize the Response, set a Content-Length header with the length of the array and then write that array.
That been said, the HTMLWorker indeed has been deprecated a long time ago; for serious development you should use the XMLWorker instead, just like Amedee commented.
I am converting some html into pdf using itext sharp. First i have filled out some html string into String Writer then using below mentioned code to converty byte array into pdf
Problem is unicode character [arabic in specific] is rendering empty.
My code is
var sw = new StringWriter();
sw = GetHtmlContent();// here i fetch html
byte[] data;
using (var sr = new StringReader(sw.ToString()))
{
using (var ms = new MemoryStream())
{
using (var pdfDoc = new Document())
{
//Bind a parser to our PDF document
using (var htmlparser = new HTMLWorker(pdfDoc))
{
//Bind the writer to our document and our final stream
using (var w = PdfWriter.GetInstance(pdfDoc, ms))
{
pdfDoc.Open();
//Parse the HTML directly into the document
htmlparser.Parse(sr);
pdfDoc.Close();
//Grab the bytes from the stream before closing it
data = ms.ToArray();
}
}
}
}
}
Response.Buffer = false;
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment; filename=Test.pdf");
Response.BinaryWrite(data);
Response.End();
Please help me what's wrong in it
Check below steps to display unicode characters in converting Html to Pdf
Create a HTMLWorker
Register a unicode font and assign it
Create a style sheet and set the encoding to Identity-H
Assign the style sheet to the html parser
Check below code
TextReader reader = new StringReader(html);
Document document = new Document(PageSize.A4, 30, 30, 30, 30);
PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(FileName, FileMode.Create));
HTMLWorker worker = new HTMLWorker(document);
document.Open();
FontFactory.Register("C:\\Windows\\Fonts\\ARIALUNI.TTF", "arial unicode ms");
iTextSharp.text.html.simpleparser.StyleSheet ST = new iTextSharp.text.html.simpleparser.StyleSheet();
ST.LoadTagStyle("body", "encoding", "Identity-H");
worker.Style = ST;
worker.StartDocument();
Check below link for more understanding....
Display Unicode characters in converting Html to Pdf
Hindi, Turkish, and special characters are also display during converting from HTML to PDF using this method. Check below demo image.
I am trying to save a panel to pdf using ITextSharp. When I set a breakpoint and debug, the code stops on this line of code, however it does not give an error and just stops.
if (IsPostBack)
{
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=Quote.pdf");
Response.Cache.SetCacheability(HttpCacheability.NoCache);
StringWriter sw = new StringWriter();
HtmlTextWriter hw = new HtmlTextWriter(sw);
**Panel1.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();
}
In the panel I have textboxes, labels and GridView.
You've got a couple of problems. If you're getting a The document has no pages message that means no content was added to the PDF which almost definitely means that there's a problem with the RenderControl method and nothing to do with iTextSharp. Another problem is that you are writing to the Response.OutputStream as well as outputting the literal document by using Response.Write(pdfDoc). You only need to do the former, I'm not actually sure what would happen with the latter.
The The document has no pages message also could mean that iTextSharp couldn't find anything to create content from. So you might have valid HTML but iTextSharp just doesn't know what to do with it. This probably isn't the case but I just had to mention it.
I'm going to break your code up into steps to help debug things. The first two blocks convert the control to HTML and then sanity checks it to make sure we've got something. You should inspect the contents of buf if you have any problems.
The third block creates a PDF from a MemoryStream and then dumps it into a byte array instead of writing directly to the Response.OutputStream. Although there's nothing incorrect with writing to the Response.OutputStream you will often find that you're swallowing errors and in general debugging is much harder. Once this block is done you should inspect bytes to make sure it has something.
The last block does the final push to the browser.
//Convert our control to HTML
string buf;
using (var sw = new StringWriter()) {
using (var hw = new HtmlTextWriter(sw)) {
Panel1.RenderControl(hw);
}
buf = sw.ToString();
}
//Sanity check
if (String.IsNullOrWhiteSpace(buf)) {
throw new ApplicationException("No content found");
}
//Create our PDF and get a byte array
byte[] bytes;
using (var ms = new MemoryStream()) {
using (var pdfDoc = new Document(PageSize.A4, 10f, 10f, 100f, 0f)) {
using (var writer = PdfWriter.GetInstance(pdfDoc, ms)) {
pdfDoc.Open();
using (var htmlparser = new HTMLWorker(pdfDoc)) {
using (var sr = new StringReader(buf)) {
htmlparser.Parse(sr);
}
}
pdfDoc.Close();
}
}
bytes = ms.ToArray();
}
//Output the PDF
Response.Clear();
Response.AddHeader("content-disposition", "attachment;filename=Quote.pdf");
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.BinaryWrite(bytes);
Response.End();
i am trying to export my HTML page to PDF using iTextSharp lib. firstly i am trying to print table which is in my Aspx page.PDF is created successfully but there nothing in PDF.
i am using this code below :
protected void btnExportToPdf_Click(object sender, EventArgs e)
{
btnExportToPdf.Visible = false;
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);
exportTable.RenderControl(hw);
//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(); }
Now I'm not too seasoned, but the problem to me looks like you are never actually writing the strings to the file. I see a few different string objects you initialize, and I see you adding the HTML to it, but I never see you actually write them to the PDF. This is my usual process for parsing HTML to PDF, maybe you can look at it, and see what you are missing.
System.Text.StringBuilder store = new System.Text.StringBuilder();
string line;
while ((line = htmlReader.ReadLine()) != null)
{
store.Append(line + Environment.NewLine);
}
string html = store.ToString();
FileStream stream = new FileStream(newFileName, FileMode.Create, FileAccess.Write);
Document document = new Document(PageSize.LETTER, 15, 15, 35, 25);
PdfWriter writer = PdfWriter.GetInstance(document, stream);
document.Open();
System.Collections.Generic.List<IElement> htmlarraylist = new List<IElement>(HTMLWorker.ParseToList(new StringReader(html), new StyleSheet()));
foreach (IElement element in htmlarraylist)
{
document.Add(element);
}
document.Close();
That was what jumped out to me at least, was the fact that it doesn't look like you actually write the generated text to the PDF. I hope this helps.