first of all I've been dealing with this problem for the past 2 days and I thought I may finally ask it since I've not found any working solution. First let me introduce the problem then I'll explain what I've tried.
As the title introduces, I'm trying to convert HTML to PDF using iTextSharp, the HTML includes gridview as well.
using (StringWriter sw = new StringWriter())
{
using (HtmlTextWriter hw = new HtmlTextWriter(sw))
{
System.Text.Encoding Enc = System.Text.Encoding.GetEncoding("UTF-8");
iTextSharp.text.pdf.BaseFont STF_Helvetica_Turkish = iTextSharp.text.pdf.BaseFont.CreateFont("Helvetica", "CP1254", iTextSharp.text.pdf.BaseFont.NOT_EMBEDDED);
iTextSharp.text.Font fontNormal = new iTextSharp.text.Font(STF_Helvetica_Turkish, 12, iTextSharp.text.Font.NORMAL);
StringReader sr = new StringReader(sw.ToString());
string contentHtml = PrintElem();
contentHtml = contentHtml.Replace("Ş", "S");
contentHtml = contentHtml.Replace("İ", "I");
contentHtml = contentHtml.Replace("ı", "i");
contentHtml = contentHtml.Replace("Ğ", "G");
contentHtml = contentHtml.Replace("Ü", "U");
contentHtml = contentHtml.Replace("ğ", "g");
contentHtml = contentHtml.Replace("ş", "s");
StringReader srHtml = new StringReader(contentHtml);
Stream denemeStream = GenerateStreamFromString(srHtml.ToString());
iTextSharp.text.Document pdfDoc = new iTextSharp.text.Document(iTextSharp.text.PageSize.A4, 10f, 10f, 10f, 0f);
MemoryStream ms = new MemoryStream();
iTextSharp.text.pdf.PdfWriter writer = iTextSharp.text.pdf.PdfWriter.GetInstance(pdfDoc, ms);
pdfDoc.Open();
using (var msCss = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(PrintElem().ToString())))
{
using (var msHtml = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(PrintElem().ToString())))
{
//iTextSharp.tool.xml.XMLWorkerFontProvider fontProvider = new iTextSharp.tool.xml.XMLWorkerFontProvider();
//Parse the HTML
iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer, pdfDoc, msHtml, (Stream)null);
}
}
//iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer, pdfDoc, denemeStream,null,Encoding.UTF8);
pdfDoc.Close();
MemoryStream ret = new MemoryStream(ms.ToArray());
return ret;
}
}
As you can see last solution I tried was to change all turkish characters to english ones yet the pdf output still did not display them.
So far I've tried changing encoding to everything offered on the internet. I tried to add the font yet I've failed to do it as you can see I'm not using that overloaded function of ParseXHtml (if you know how to add this fontNormal to the parsing I'll gladly try that out as well).
the PrintElem function returns the following HTML content (or similar ones that contain turkish characters inside)
<html>
<head>
<h3 align='center'>ABG SİGORTA ALACAK/VERECEK MUTABAKAT EKSTRESİ</h3>
<style>#ContentPlaceHolder1_vaultsListGridview{width: 100%;} td:nth-child(3) {text-align: right;}td:nth-child(4) {text-align: right;}.netWorthClass{text-align: right;}</style>
</head>
<body >
<br/>
<div>Kasa Adı = 1</div>
<div>Devir = 56 TL</div>
<br/>
<div>
\r\n\t
<table class=\"table table-hover table-striped\" cellspacing=\"0\" rules=\"all\" border=\"1\" id=\"ContentPlaceHolder1_vaultsListGridview\" style=\"border-collapse:collapse;\">
\r\n\t\t
<thead>
\r\n\t\t\t
<tr>
\r\n\t\t\t\t
<th scope=\"col\">Tarih</th>
<th scope=\"col\">Açıklama</th>
<th scope=\"col\">Giren</th>
<th scope=\"col\">Çıkan</th>
\r\n\t\t\t
</tr>
\r\n\t\t
</thead>
<tbody>
\r\n\t\t\t
<tr>
\r\n\t\t\t\t
<td>\r\n <span id=\"ContentPlaceHolder1_vaultsListGridview_fullDateLabel_0\">26/05/2017</span>\r\n </td>
<td>\r\n <span id=\"ContentPlaceHolder1_vaultsListGridview_detailLabel_0\">MART AYI KALAN VE NİSAYIN AYI SSK ÖDEMESİ</span>\r\n </td>
<td>\r\n 0\r\n </td>
<td>\r\n 1,295.00\r\n </td>
\r\n\t\t\t
</tr>
<tr>
\r\n\t\t\t\t
<td>\r\n <span id=\"ContentPlaceHolder1_vaultsListGridview_fullDateLabel_1\">31/05/2017</span>\r\n </td>
<td>\r\n <span id=\"ContentPlaceHolder1_vaultsListGridview_detailLabel_1\">NİSAN AYI KOMİSYON</span>\r\n </td>
<td>\r\n 1,351.00\r\n </td>
<td>\r\n 0\r\n </td>
\r\n\t\t\t
</tr>
\r\n\t\t
</tbody>
\r\n\t
</table>
\r\n
</div>
<br/>
<div class='netWorthClass'>Giren Miktar = 1351 TL</div>
<div class='netWorthClass'>Çıkan Miktar = 1295 TL</div>
<br/>
</body>
</html>
I've taken the above html part from debugger sorry for the mess, but you see the problematic characters above.
I'll gladly try out everything you may offer. Thanks in advance.
Related
var str1 = "Sarah";
var str2 = "Tom";
var strTable = "<table style='width:100%'><tr><th>"+ str1 +"</th><th>"+ str2 +"</th> <th>Age</th> </tr> <tr> <td>Jill</td><td>Smith</td><td>50</td></tr></table>";
$scope.rTable= strTable;
I am trying to pass HTML code in $Scope.rTable but instead of rendering the table it shows the HTML code as it is in the output.
i.e.
<table style='width:100%'><tr><th>Sarah</th><th>Tom</th> <th>Age</th> </tr> <tr> <td>Jill</td><td>Smith</td><td>50</td></tr></table>
I want it like:
Its a improper way to code.
The code should be like
In Controller
$scope.str1 = "Sarah";
$scope.str2 = "Tom";
In HTML
Considering your controller name as DemoController
<body ng-controller="DemoController">
<table style='width:100%'>
<tr><th> {{str1}} </th>
<th> {{str2}} </th>
<th>Age</th>
</tr>
</table>
</body>
And if your data is huge its recommended to use an Array of Object with ng-repeat. you can read it here -> https://docs.angularjs.org/api/ng/directive/ngRepeat
Use ng-bind-html and $sce.
Controller
app.controller('MainCtrl', function($scope, $sce) {
var str1 = "Sarah";
var str2 = "Tom";
var strTable = "<table style='width:100%'><tr><th>" + str1 + "</th><th>" + str2 + "</th> <th>Age</th> </tr> <tr> <td>Jill</td><td>Smith</td><td>50</td></tr></table>";
$scope.rTable = $sce.trustAsHtml(strTable);
});
HTML
<body ng-controller="MainCtrl">
<div ng-bind-html="rTable"></div>
</body>
Im using MVC4 Razor and I just want to ask how to create a List of string and use it in a field seperated by comma? Cause I tried something and it shows an error Cannon implicitly convert type void to object Ill show you my set of codes
declared this on my header:
List<string> elements = new List<string>();
Then I want this List<string> elements to get populated inside a foreach loop
<tbody>
#for (var i = 0; i < Model.Cards.Count; ++i)
{
var counter = i + 1;
<tr>
<td valign="middle">
<p class="small">#counter</p>
</td>
<td valign="middle">
<p class="small">#Model.Cards[i].Number.Substring(0,5)</p>
</td>
#elements.Add(Model.Cards[i].Number.Substring(0,5))
</tr>
}
</tbody>
And use it in a Label
<div> Card Number <p> #String.Join(", ", elements.ToArray()) </p></div>
If you flow #Stephen Muecke, suggestion it's best. But if you flow your process the your code look like:
#{
List<string> elements = new List<string>();
}
<tbody>
#for (var i = 0; i < Model.Cards.Count; ++i)
{
var counter = i + 1;
var cardNumber=Model.Cards[i].Number.Substring(0,5);
elements.Add(cardNumber);
<tr>
<td valign="middle">
<p class="small">#counter</p>
</td>
<td valign="middle">
<p class="small">#cardNumber</p>
</td>
</tr>
}
</tbody>
#{
var str=string.Join(", ", elements.ToArray());
}
<div> Card Number <p> #str </p></div>
I have a jsp that has multiple <table> in a page. I want only one particular table to be of fixed height and have a scrollable <tbody> and fixed <thead>.
For that I have written a custom CSS as a class so that I can use it in that paricular table. But its not working.
Here is the CSS:
.scroll-tbody{
display: block;
height: 460px;
overflow-y: auto;
}
And here is the JSP snippet:
<table class="table table-hover table-condensed">
<thead>
<tr>
<td><b>    Name</b></td>
<td><b>Phone</b></td>
<td><b>Total Exp.</b></td>
<td><b>Location</b></td>
<td><b>Profile Type</b></td>
<td><b>Domain</b></td>
<td><b>Assigned To</b></td>
<td><b>Status</b></td>
<td><b>Date</b></td>
</tr>
</thead>
<tbody class="scroll-tbody"> <!-- HERE IS THE CUSTOM CSS FOR SCROLLING -->
<%
if(fullList.size()>0)
{
Iterator itr = fullList.iterator();
while(itr.hasNext())
{
FileService fs = new FileService();
File prf = (File)itr.next();
String prfData = prf.getAbsolutePath() + "#";
prfData += fs.readData(prf.getAbsolutePath(),"","profiledata");
prfData = prfData.replace("\\","/");
String[] data = prfData.split("#");
String name = data[1].replace("_"," ");
String phone = data[2];
String totExp = data[3];
String location = data[5];
String prfType = data[6];
String domain = data[7];
String assignedTo = data[8];
String status = data[9];
String prfDate = data[12];
prfData = prfData.replace("'","\\'");
prfData = prfData.replace("\"","\\'");
prfData = prfData.replace("\r\n","^");
System.out.println("---->JSP Data: "+prfData+"\n");
session.setAttribute("dataToEdit",prfData);%>
<tr>
<td><a data-toggle="modal" data-target="#editProfileModal" onClick="getData('<%=prfData%>')"><i class="fa fa-fw fa-file"></i><font size="2"><%=name%></font></a></td>
<td><font size="2"><%=phone%></font></td>
<td><font size="2"><%=totExp%></font></td>
<td><font size="2"><%=location%></font></td>
<td><font size="2"><%=prfType%></font></td>
<td><font size="2"><%=domain%></font></td>
<td><font size="2"><%=assignedTo%></font></td>
<td><font size="2"><%=status%></font></td>
<td><font size="2"><%=prfDate%></font></td>
</tr>
<% }
} %>
</tbody>
</table>
I dont want to write the CSS like: table{...} thead{...} tbody{...} as it will impact all the tables present in that page.
Am I missing something?
Thanks in advance.
I have a snippet of html containing the first part of a post code and the region it is in. An example of two rows:
<tr height="17">
<td class="xl66" height="17">Channel Islands</td>
<td class="xl66">GY - (Guernsey)</td>
</tr>
<tr height="17">
<td class="xl66" height="17">Channel Islands</td>
<td class="xl66">JE - (Jersey)</td>
</tr>
How/what can I use to extract the region and the part of the postcode minus the name of the location.
From the example data, I would like to retrieve ('Channel Islands', 'GY'), ('Channel Islands', 'JE') so I can enter them into a database.
USING GAWK
Using gawk scripting language can prove worthwhile
create a file name gawkscript and add the following:
#Test to see if the line matches the region, if it does, use regex to get your region
$0~/<td class="xl66" height="17">Channel Islands<\/td>/{printf gensub(/ *<td.*>(.+)<\/td>/,"\\1,",$0)};
#Test to see if the line matches the cose, if it does, use regex to get your code
$0~/<td class="xl66">(.+)<\/td>/{print gensub(/ *<td.*>(.+) *- \(.+\)<\/td>/,"\\1",$0)}
using your shell you can run the script
gawk -f gawkscript my_html_file
Since this is html codes we are dealing with, I would use a powerful html webscraping module in python call BeautifulSoup
USING PYTHON
Assuming you know some python
import re #import regex
from bs4 import BeautifulSoup #import beautifulsoup
soup=BeautifulSoup(
#add your html string
"""<tr height="17">
<td class="xl66" height="17">Channel Islands</td>
<td class="xl66">GY - (Guernsey)</td>
</tr>
<tr height="17">
<td class="xl66" height="17">Channel Islands</td>
<td class="xl66">JE - (Jersey)</td>
</tr>""")
#find all tr tags in your html string
find_all_tr=soup.find_all("tr")
for i in find_all_tr: #loop through all tr tags
all_td=BeautifulSoup(str(i)).find_all("td") #find all td tags
for j in all_td:
#check to see if your td tages matches 'td class="xl66" height="17"' and print
if re.search('<td class="xl66" height="17"',str(j)):
print(j.text.strip(),end=" ")
#check to see if your td tag matches ONLY <td class="xl66" and use regex to obtain your country code
elif re.search('<td class="xl66">',str(j)):
print(","+re.sub(".*-","",j.text.strip()))
NOTE: I use strip() function here because html to eliminate the unwanted newline characters in html codes when extracting information
You can use regex
/<td.*?>(.*?)<\/td.*?>\s+<td.*?>(.*?)\s-.*?<\/td>/gi
Regex explanation here
I can make your work with the help of javascript as i have less knowledge in regex.
Here the JS code :
var array = [];
var table = document.getElementById('myTable');
var rowLength = table.rows.length;
for (i = 0; i < rowLength; i++) {
var collect = [];
var col = table.rows.item(i).cells;
var colLength = col.length;
for (var j = 0; j < colLength; j++) {
var value = col.item(j).innerHTML;
collect.push(value);
}
array.push(collect);
}
Here is the working link
http://plnkr.co/edit/8e67Il0u5dmr6NZX3FWJ?p=preview
Hope it helps you :)
Without knowing server-side specifics like languages (PHP/ASP) and database (MySQL/NoSQL), I cannot show you how to handle the code in the back-end.
That being said, the code below shows you how to handle and prepare the data client-side and make an asynchronous (POST) request via JavaScript to your server.
Related Information:
Here is a well documented guide for the -- FormData( ) object
Here is a well documented guide for the -- XMLHttpRequest( ) object
Screenshot:
//HTML (index.html)
<!DOCTYPE html>
<html>
<head>
<script src="index.js"></script>
<link rel="stylesheet" href="index.css">
</head>
<body>
<button onclick="submitTable();">Click Me</button>
<table>
<thead>
<tr>
<th>Region</th>
<th>Postcode</th>
</tr>
</thead>
<tbody>
<tr class="data-row">
<td>Channel Islands</td>
<td>GY - (Guernsey)</td>
</tr>
<tr class="data-row">
<td>Channel Islands</td>
<td>JE - (Jersey)</td>
</tr>
</tbody>
</table>
</body>
</html>
//JS (index.js)
function submitTable(){
//OBJECT INITIALIZATION
if (window.XMLHttpRequest){
var request = new XMLHttpRequest(); // IE7+, Firefox, Chrome, Opera, Safari
}
else{
var request = new ActiveXObject("Microsoft.XMLHTTP"); // IE 6 and older
}
var formData = new FormData();
//LOOP THROUGH DATA and APPEND to FormData(object)
var dataRows = document.getElementsByClassName("data-row");
for(var i=0; i < dataRows.length; i++){
var data = dataRows[i].children;
for(var x=0; x < data.length; x++){
if(x === 1){
var postcode = data[x].innerHTML.substr(0, 2);
formData.append("postcode", data[x].innerHTML);
}
else{
formData.append("region", data[x].innerHTML);
}
}
}
//OPEN
request.open("POST", "/path/to/post/the/data");
//SEND
request.send(formData);
//RESPONSE
request.onreadystatechange = function(){
if(request.readyState == 4){
console.log(request.response);
}
}
}
//CSS (index.css)
table, th, td {
border: 1px solid black;
}
I am trying to generate pdf from HTML table using jspdf.In this case the pdf is generated but the format is not suitable to original.
This is my code.
html code is
<div class="invoice" id="customers">
<table ng-repeat="aim in input" id="example">
<tr>
<th class="inv-left"><div align="left"><img src="./images/logo.png" alt=""></div></th>
<th class="inv-right"><div align="right"><br>
101 Convention Center<br>
dr #700, Las Vegas, <br>
NV - 89019
</div></th>
</tr>
<tr >
<th><div cg-busy="{promise:viewPromise}" align="left">
<b>Invoiced to</b><br>
{{aim.user.username}}<br>
{{aim.vendor.address}}
</div></th>
<th class="inv-right">
<div align="right"><b>INVOICE</b><br>
Invoice ID: {{aim.invoiceId}}<br>
Invoice Date: {{aim.invoiceDate.date| dateFormat | date:'MM-dd-yyyy'}}<br>
Due Date: {{aim.dueDate.date| dateFormat | date:'MM-dd-yyyy'}}
</div></th>
</tr>
<div class="invoice-content clearfix" cg-busy="{promise:viewPromise}" >
<tr>
<td class="inv-thours">Total Hours</td>
<td align="center">{{aim.totalHours}}</td>
</tr>
<tr>
<td class="inv-rate">Rate</td>
<td align="center">{{aim.billRate}}</td>
</tr>
<tr>
<td class="inv-rate">Amount</td>
<td align="center">{{(aim.totalHours) * (aim.billRate)}}</td>
</tr>
<tr>
<td class="inv-thours">totalExpenses</td>
<td align="center">{{aim.totalExpenses}}</td>
</tr>
<tr>
<td class="inv-thours">Total Amount</td>
<td align="center">{{aim.amount}}</td>
</tr>
<tr>
<td>
</td>
<td ng-if="aim.status === 'UNCONFIRMED'">
<div align="right" style="margin-right:10px;"><input type="submit" value="Confirm" data-ng-click="confirmStatus(aim)"> |
<button onclick="goBack()">Cancel</button></div>
</td>
<td ng-if="aim.status === 'CONFIRMED'">
<div align="right" style="margin-right:10px;">
<button onclick="goBack()">BACK</button></div>
</td>
<td ng-if="!(aim.status === 'UNCONFIRMED') && !(aim.status === 'CONFIRMED')">
<button onclick="javascript:demoFromHTML();">PDF</button>
</td>
</tr>
</table>
<script type="text/javascript" src="http://mrrio.github.io/jsPDF/dist/jspdf.debug.js"></script>
<script>
function demoFromHTML() {
var pdf = new jsPDF('p', 'pt', 'letter');
var imgData = '.............';
pdf.setFontSize(40);
pdf.addImage(imgData, 'PNG', 12, 30, 130, 40);
pdf.cellInitialize();
pdf.setFontSize(10);
$.each($('#customers tr'), function (i, row) {
$.each($(row).find("th"), function (j, cell) {
var txt = $(cell).text();
var width = (j == 4) ? 300 : 300; //make with column smaller
pdf.cell(10, 30, width, 70, txt, i);
});
$.each($(row).find("td"), function (j, cell) {
var txt = $(cell).text().trim() || " ";
var width = (j == 4) ? 200 : 300; //make with column smaller
pdf.cell(10, 50, width, 30, txt, i);
});
});
pdf.save('sample-file.pdf');
}
I whant to generate pdf to this formate
http://i.stack.imgur.com/nrR7l.png
but generate pdf formate is
http://i.stack.imgur.com/DGSxE.png
please help me to this problem.
Thank you.
I think CSS is missing in your generated PDF, and found this,
github issue link
diegocr commented on 25 Sep 2014
I'm afraid the fromHTML plugin is kinda limited when it comes to support css styles. Also, we have an addSVG plugin to deal with SVG elements, but the fromHTML does not uses it. So, no, the issue isn't Angular, you may could use the new addHTML (#270) but i dunno if that will deal with SVG. (html2canvas, that is)