Convert HTML table to PDF(itextsharp) - c#

I have got trouble parsing HTML table to PDF. Table is spreading and it's go out of page. How can I it fix?
I'm using HTMLWorker. It's converting HTML to PDF is good, but that table...
Here is my code(it's in method):
StyleSheet ST = new StyleSheet();
ST.LoadTagStyle(HtmlTags.BODY, HtmlTags.FACE, "Arial Unicode MS");
ST.LoadTagStyle(HtmlTags.BODY, HtmlTags.ENCODING, BaseFont.IDENTITY_H);
HTMLWorker worker = new HTMLWorker(doc);
worker.SetStyleSheet(ST);
worker.StartDocument();
worker.Parse((TextReader)File.OpenText(xmlNode.ChildNodes[i].Attributes["path"].Value.ToString()));
worker.EndDocument();
worker.Close();
How can I tell HTMLWorker so it's create table in PDF is ok? Can I give to worker size of table?
Or maybe should I use other "workers" for example XMLWorkerHelper or XMLWorker. When I use XMLWorker or XMLWorkerHelper I can't set to "workers" my font(I need Cyrillic, and just don't understand how add font). And when I use this "workers" I have the same problem with table.
code with XMLWorker:
//working with XMLWorker
ICSSResolver cssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(true);
cssResolver.AddCss(fileCSS,true);
CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
htmlContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory());
PdfWriterPipeline pdf = new PdfWriterPipeline(doc, writer);
HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);
CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);
XMLWorker worker = new XMLWorker(css, true);
XMLParser p = new XMLParser(worker);
p.Parse(new FileStream(fileHTML, FileMode.Open, FileAccess.Read));
code with XMLWorkerHelper:
string arialuniTff = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), "ARIALUNI.TTF");
FontFactory.Register(arialuniTff);
using (var msCss = new MemoryStream(Encoding.UTF8.GetBytes(fileCSS)))
{
using (FileStream fsHtml = new FileStream(fileHTML,FileMode.Open,FileAccess.Read))
{
iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, fsHtml, msCss, FontFactory.FontImp as IFontProvider);
}
}
What can You advise to me?
Thank you!
Update
I found one article about XMLWorkerHelper with Cyrillic, but my code doesn't work. I can't understand why.
My code:
using (var msCss = new MemoryStream(Encoding.UTF8.GetBytes(fileCSS)))
{
using (FileStream fsHtml = new FileStream(fileHTMLTest,FileMode.Open,FileAccess.Read))
{
XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
fontProvider.Register(arial);
FontFactory.FontImp = fontProvider;
doc.Add(new Paragraph("XMLWorkerHelper"));
doc.Add(new Paragraph("XMLWorkerHelper вот это да!"));
iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, fsHtml, msCss, Encoding.UTF8, fontProvider);
}
}
My HTML code(test):
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type"content="text/html;charset=utf-8"></meta>
<title></title>
</head>
<body>
<p>Привет Мир!</p>
<table border="0">
<tr>
<td><h2 align="center">Акционерное общество «OOO "Ландыш"»</h2></td>
</tr>
<tr>
<td>
<p align="center">Тема:</p>
<p align="center">[THEME]</p>
</td>
</tr>
<tr>
<td>
<div align="right">
<p>Выполнил:</p>
<p>[AUTHOR]</p>
</div>
</td>
</tr>
<tr>
<td><p align="center">[CITY] [YEAR]г.</p></td>
</tr>
</table>
<table border="1">
<tr>
<td>Row 1, Column 1; Столбец 1, Строка 1 </td>
<td>Row 1, Column 2; Столбец 1, Строка 2</td>
</tr>
<tr>
<td>Row 2, Column 1; Столбец 2, Строка 1</td>
<td>Row 2, Column 2; Столбец 2, Строка 2</td>
</tr>
</table>
<img src="img.jpg" alt="picture"></img>
</body>
</html>

Related

Model is null when url.action is called in asp.net

My model have List products which get from database.
When index view loaded, i get the variable from input of user, then model get varible, and return view OutputTableAsync. After view loaded, i click link "Export Excel", in debug mode, List products is null.
My view:
<body>
#if (Model != null)
{
var products = Model.products.Products;
Export Excel
<table border="1" style="width: 100%">
<thead>
<tr>
<th>Model</th>
<th>Price</th>
<th>Link</th>
<th>ImageUrl</th>
</tr>
</thead>
<tbody>
#foreach (var product in Model.products.SortProduct())
{
<tr id="i">
<td align="center">#product.Model</td>
<td align="center">#product.FormatPrice()</td>
<td align="center">#product.Link</td>
<td align="center"><img src="#product.ImageUrl" style="width : 200px; height:200px ;" id="#product.ImageUrl" /></td>
</tr>
}
</tbody>
</table>
}
</body>
ExportToExcel method in controller:
public void ExportToExcel(List<Product> products)
{
ExcelPackage pck = new ExcelPackage();
ExcelWorksheet ws = pck.Workbook.Worksheets.Add("Products");
ws.Cells["A1"].Value = "Model";
ws.Cells["B1"].Value = "Price";
ws.Cells["C1"].Value = "Link";
ws.Cells["D1"].Value = "ImageLink";
int rowstart = 2;
foreach(var item in products)
{
ws.Cells[string.Format("A{0}", rowstart)].Value = item.Model;
ws.Cells[string.Format("B{0}", rowstart)].Value = item.Price;
ws.Cells[string.Format("C{0}", rowstart)].Value = item.Link;
ws.Cells[string.Format("D{0}", rowstart)].Value = item.ImageUrl;
rowstart++;
}
ws.Cells["A:AZ"].AutoFitColumns();
Response.Clear();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment: filename=" + "ExcelFile.xlsx");
Response.BinaryWrite(pck.GetAsByteArray());
Response.End();
}
According to accepted answer here you can not pass complex type through Url.Action
I would pass serialized version of object in this situation.

Opening a file in a new tab of the web browser

I have a view which shows a list of xml files in a directory. Also i have a button which would display the content of the file name selected in the browser. Currently its showing the content in a the same tab. But i want to display it in a new tab of the browser..
for example if i select two file names from the list, then it should open different tab for both the files..
Please find the code below.
public ActionResult ViewFile(string[] Name)
{
byte[] ImageData = null;
for (int i = 0; i < Name.Length; i++)
{
string filepath = holdpath + #"\" + Name[i];
string result;
using (StreamReader streamReader = new StreamReader(filepath))
{
result = streamReader.ReadToEnd();
}
using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream())
{
Document document = new Document(PageSize.A4, 10, 10, 10, 10);
PdfWriter writer = PdfWriter.GetInstance(document, memoryStream);
document.Open();
Paragraph paragraph = new Paragraph();
paragraph.Add(result);
document.Add(paragraph);
document.Close();
ImageData = memoryStream.ToArray();
}
}
Response.AppendHeader("Content-Disposition", "inline; filename=MyFile.pdf");
return File(ImageData, "application/pdf");
}
Please note that i am using itextsharp because the file also needs to be downloaded as pdf if required
I have added the View here
#model IEnumerable<FileInfo>
#{
ViewBag.Title = "files";
}
<h2>Held files</h2>
#using (Html.BeginForm())
{
<div style="border:solid;width:100%;overflow-x:auto;">
<table align="center" style="width:100%">
<thead>
<tr>
<th>File Name</th>
<th>Action</th>
</tr>
</thead>
<tbody>
#foreach (FileInfo file in Model)
{
<tr>
<td>
<input type="checkbox" name="Name" value="#file.Name" />
#file.Name
</td>
<td>
#Html.ActionLink("View", "ViewFile", "HoldFiles", new { Name = file.Name },
new { #class = "btn btn-primary btn-sm", target = "_blank" })
</td>
</tr>
}
</tbody>
</table>
</div>
}
In your view, put target="_blank" on your anchor element.
For example:
Open in new tab
or if using razor:
#Html.ActionLink("Text", "ActionMethodName", "ControllerName", new { id = Model.Id }, new { #class = "btn btn-primary btn-sm", target = "_blank" })

how to display 10 first rows from excel sheet with asp.net mvc 5

I need to display just 10 first rows from my excel sheet, i can only display all the excel data using "#Foreach".
please find the controller and the view below.
this is how i extract data from excel:
string path2 = "D:/Project/SesameIncident.xlsx";
Excel.Application application2 = new Excel.Application();
Excel.Workbook workbook2 = application2.Workbooks.Open(path2);
Excel.Worksheet worksheet2 = workbook2.ActiveSheet;
Excel.Range range2 = worksheet2.UsedRange;
List<SesameIn> ListSesame = new List<SesameIn>();
for (int row = 2; row <= range2.Rows.Count; row++)
{
SesameIn Se = new SesameIn();
Se.AssignedGroup= (((Excel.Range)range2.Cells[row, 1]).Text);
Se.Open = (((Excel.Range)range2.Cells[row, 2]).Text);
Se.Assigned = (((Excel.Range)range2.Cells[row, 3]).Text);
Se.PendingCustomer = (((Excel.Range)range2.Cells[row, 4]).Text);
Se.ClosedComplete = (((Excel.Range)range2.Cells[row, 5]).Text);
Se.Resolved = (((Excel.Range)range2.Cells[row, 6]).Text);
Se.Total = (((Excel.Range)range2.Cells[row, 7]).Text);
ListSesame.Add(Se);
}
ViewBag.ListSesames = ListSesame;
and this is the view code :
<div class="item">
<h1><img src="~/Web/PendingCustomer.png" /> Sesame Pending Tickets </h1>
<table class="table table-striped">
<thead>
<th>Number</th>
<th>Assigned To</th>
<th>Opened</th>
<th>Priortity</th>
<th>Assigned Group</th>
</thead>
<tbody>
#foreach (var In in ViewBag.ListSesameIncidents)
{
<tr>
#if (#In.Status == "Pending Customer")
{
<td>#In.Number</td>
<td>#In.AssignedTo</td>
<td>#In.Opened</td>
<td>#In.Priority </td>
<td>#In.Status</td>
<td>#In.AssignedGroup</td>
}
</tr>
}
</tbody>
</table>
<br />
<div class="carousel-caption">
</div>
</div>
I would suggest use Linq extension methods and filter the Data.
ViewBag.ListSesames = ListSesam
.Where(x=>x.Status == "Pending Customer") // Look for pending customers
.Take(10); // Take top 10
You can use linq .Take(10) to show the first 10 items.

Export Asp.Panel to PDF?

I want to export Asp.Panel content(text, GridViews) with CSS to PDF from C#.NET. I am using iTextSharp and RenderControl with Asp.Panel, but CSS is not rendered in PDF.
How can I solve this problem(with iTextSharp(if is possible) or in another way) ?
This code generate PDF file:
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
StringReader sr;
string fileName = "C://pdf/GridView.pdf";
var doc = new Document(PageSize.A3, 45, 5, 5, 5);
var pdf = fileName;
PdfWriter writer = PdfWriter.GetInstance(doc, new FileStream(pdf, FileMode.Create));
doc.Open();
HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
htmlContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory());
ICSSResolver cssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(false);
cssResolver.AddCssFile(Server.MapPath("Content/PDFs.css"), true);
IPipeline pipeline = new CssResolverPipeline(cssResolver, new HtmlPipeline(htmlContext, new PdfWriterPipeline(doc, writer)));
XMLWorker worker = new XMLWorker(pipeline, true);
XMLParser xmlParse = new XMLParser(true, worker);
this.pnlTabs.RenderControl(htw);
sr = new StringReader(sw.ToString());
xmlParse.Parse(sr);
xmlParse.Flush();
doc.Close();
This is the ASP Panel I want to send to PDF:
<asp:Panel ID="pnlTabs" runat="server" CssClass="TeamTabs">
<div class="repHeader">
<div class="row">
<div style="padding:12px;border-bottom:1px solid #ddd;margin-bottom:1px;overflow:hidden;">
<div class="col4">
<p> <font size="4.5"> <b>Client Scorecard</b> </font> <br>
Run Date: 11/1/2013 4:20:01 AM <br>
For Dates: 9/12013 - 10/31/2013 <br>
Oct 2013 - Filed to Service Complete: 31.18 <br>
Oct 2013 - State Average: 34.45
</p>
</div>
</div>
<p style="text-align: center; margin-top:1px"> <font size="3.5"> <b> BECKER POLIAKOFF (CORAL GABLES) </b>
</font> </p>
</div>
</div>
<div class="row" style="padding-bottom:36px;">
<div class="col9 col-first">
<asp:GridView ID="gvDashRep_Left_first" runat="server" ></asp:GridView>
<asp:GridView ID="gvDashRep_Left_second" runat="server" ></asp:GridView>
<asp:GridView ID="gvDashRep_Left_third" runat="server" ></asp:GridView>
</div>
<div class="col3">
<asp:GridView ID="gvDashRep_Right_first" runat="server" ></asp:GridView>
<asp:GridView ID="gvDashRep_Right_second" runat="server" ></asp:GridView>
<asp:GridView ID="gvDashRep_Right_third" runat="server" ></asp:GridView>
</div>
<p style="text-align: center; margin-top:1px"> <font size="2.5"> *For B/W, items with an asterisk indicate that higer number for Octomber 2013 is considered better. </font> </p>
<div class="col12 col-first">
<asp:GridView ID="gvComments" runat="server" ></asp:GridView>
</div>
</div>
</asp:Panel>
CSS File
div.row { min-height: 1%; width: 966px; margin: 0 auto; overflow: hidden; }
div.col3 {width:219px; float: left; margin-left: 30px;}
There is an additional download (XMLWorker) if you want to export to pdf using ITextSharp with css. You can get the XMLWorker from here
To set this up to apply your css you need to do something like the following
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
StringReader sr;
string fileName = Server.MapPath("PATH TO PDF");
var doc = new Document(PageSize.A3, 45, 5, 5, 5);
var pdf = fileName;
PdfWriter writer = PdfWriter.GetInstance(doc, new FileStream(pdf, FileMode.Create));
doc.Open();
HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
htmlContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory());
ICSSResolver cssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(false);
cssResolver.AddCssFile(Server.MapPath("PATH TO CSS"), true);
IPipeline pipeline = new CssResolverPipeline(cssResolver, new HtmlPipeline(htmlContext, new PdfWriterPipeline(doc, writer)));
XMLWorker worker = new XMLWorker(pipeline, true);
XMLParser xmlParse = new XMLParser(true, worker);
control.RenderControl(htw);
sr = new StringReader(sw.ToString());
xmlParse.Parse(sr);
xmlParse.Flush();
Replace the PATH TO PDF (loacation to save the file) and PATH TO CSS (location were your css file is) with the relevant file paths. When I had to do this the css file had to be a external file (.css).

How to increase the table height from the code behind file in ASP.Net while using StringWriter?

I am generating one PDF from the Code Behind File using StringWriter and HtmlTextWriter.
The Coding is given below:
System.IO.StringWriter sw = new System.IO.StringWriter();
HtmlTextWriter hw = new HtmlTextWriter(sw);
GridView gv = new GridView();
gv.BorderStyle = BorderStyle.None;
gv.DataSource = dt2;
gv.DataBind();
gv.RenderControl(hw);
string str = sw.ToString();
string str1 = "<table width='100%' border='1'><tr><td><img src='" + Server.MapPath("App_Themes/Ribo/ribologo.bmp") + "' alt='' width=75px height=75px /></td><td align='center' colspan='8' font size='3'><h2><b>MATERIAL RECEIPT CUM INSPECTION REPORT(MRIR)</b></h2</td></tr>";
str1 += "<tr><td font size='3'>MRIR NO</td><td font size='3'>Date</td><td align='center' font size='3'>JOB DESCRIPTION</td><td font size='3'>SUPPLIER NAME</td><td font size='3'>DC NO</td><td font size='3'>DATE</td><td font size='3'>LWB NO/DATE</td><td font size='3'>INVOICE NO</td><td font size='3'>DATE</td></tr>";
str1 += "<tr><td font size='3'>" + txtMRVNumber.Text + "</td><td font size='3'></td><td font size='3'></td><td font size='3'>" + TDSSVendor.Text + "</td><td font size='3'>" + txtDCNumber.Text + "</td><td font size='3'></td><td font size='3'>" + txtLWBNo.Text + "</td><td font size='3'>" + txtInvoiceNo.Text + "</td><td font size='3'></td></tr>";
str1 += "<tr><td rowspan='2' font size='3'>DESCRIPTION</td><td font size='3' colspan='2' align='center'>SIZE(mm)</td><td colspan='6'></td></tr>";
str1 += "<tr><td font size='3' colspan='2'>" + sw + "</td><td colspan='6'></td></tr></table>";
if (str.StartsWith("<div>"))
{
str = str1;
}
System.IO.StringReader sr = new System.IO.StringReader(str);
iTextSharp.text.Document pdfDoc = new iTextSharp.text.Document(iTextSharp.text.PageSize.A3.Rotate(), 40f, 10f, 40f, 2f);
iTextSharp.text.html.simpleparser.HTMLWorker htmlparser = new iTextSharp.text.html.simpleparser.HTMLWorker(pdfDoc);
iTextSharp.text.pdf.PdfWriter.GetInstance(pdfDoc, Response.OutputStream);
Here, I generated my desired PDF. But the table is displaying at the top of the PDF. So I want to display at the centre of the PDF as well as I want to increase the height of the Table. How to do this?
I tried like the below:
string str1 = "<table **height='100%'** width='100%' border='1'><tr>.....
But it displays as the same. How to increase the height of the table? I need all your suggestions please.
That alone is not going to do it. You can wrap the generated .pdf in another table (1 row, 1 column), and place that table in the sole TD of the new table, then just vertical align (valign='middle') the enclosing TD.
This is the only way I know how to do what you are asking, although I do not know if it will work for you:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Untitled Page</title>
<!-- Put this on your presentation page -->
<style type="text/css">
html, body {
margin: 0;
padding: 0;
height: 100%;
border: none;
}
</style>
</head>
<body>
<table style="height: 100%" width="100%" align="center">
<tr>
<td valign="middle" align="center">
<table>
<tr>
<td valign="middle">
<!-- Embed your .pdf here -->
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
from the taking the height of the table u can set parameter of below Document class constructor.
Dim doc As Document = New Document(PageSize.A4, 1, 0, 0, 30)
Hope this will helps you...

Categories