Export to excel with hyperlinks, merged cells and text alignment - javascript

I am using javascript to generate a large table (of around 15000 rows) and export it to excel. I am converting it into a blob and then exporting using the following code.
var tableToExcel = (function() {
var uri = 'data:application/vnd.ms-excel;base64,'
, template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--><meta http-equiv="content-type" content="text/plain; charset=UTF-8"/></head><body><table>{table}</table></body></html>'
, base64 = function(s) { return window.btoa(unescape(encodeURIComponent(s))) }
, format = function(s, c) { return s.replace(/{(\w+)}/g, function(m, p) { return c[p]; }) }
return function(table, name) {
if (!table.nodeType) tableNode = document.getElementById(table)
var ctx = {worksheet: name || 'Worksheet', table: tableNode.innerHTML}
str = base64(format(template, ctx));
var blob = b64toBlob(str, "application/vnd.ms-excel");
var blobUrl = URL.createObjectURL(blob);
window.location = blobUrl;
}
It is working fine. However, I am not able to vertically align the text in the excel sheet to the top. I have tried multiple plugins and could not find anything suitable. The table contains
merged cells
hyperlinks
large amount of data
text alignment
I require a solution which will generate the excel file quickly and will support all features
Tried approaches:
- SheetJS was slow since I iterated over the cells and added hyperlinks to a cell in each row.
- Xlsx does not support hyperlinks.
Please let me know a suitable solution. Thanks in advance!

I was able to achieve this by simply adding css to the td vertical-align: top to the table.
Thanks :)

Related

How Do I Export Data From HTML Webpage Using Javascript To Microsoft Excel Keeping The GridLines Turned On?

I have been researching all afternoon and playing around with various solutions I have found on the internet and Stack OverFlow to try to keep the gridlines turned on when I export data from my HTML webpage but to no avail. I am really trying to avoid using a plug in and something this simple shouldn't require on in my opinion. I'm actually shocked that this is proving as challenging as it is. Anyway...I found this code....
function exportTableToExcel(tableID, filename = ''){
var downloadLink;
var dataType = 'application/vnd.ms-excel';
var tableSelect = document.getElementById(tableID);
var tableHTML = tableSelect.outerHTML.replace(/ /g, '%20');
// Specify file name
filename = filename?filename+'.xls':'excel_data.xls';
// Create download link element
downloadLink = document.createElement("a");
document.body.appendChild(downloadLink);
if(navigator.msSaveOrOpenBlob){
var blob = new Blob(['\ufeff', tableHTML], {
type: dataType
});
navigator.msSaveOrOpenBlob( blob, filename);
}else{
// Create a link to the file
downloadLink.href = 'data:' + dataType + ', ' + tableHTML;
// Setting the file name
downloadLink.download = filename;
//triggering the function
downloadLink.click();
}
}
And coupled with this HTML.....
<table id="tblData" class="table10">
<tr>
<th class="title36">Description</th>
</tr>
</table>
<button onclick="exportTableToExcel('tblData')"</button>
It all works beautifully! Except when I open the file the gridlines are gone and the user would have to go the view tab and turn the gridlines back on every time. Is there a setting I can change somewhere that will allow this?
The second example in this SO works...but I have a problem whereby I need to use a button and not an input button....for styling purposes...and then in doing so because the solution is written as a var and not a function....I had trouble working it out. So I know what I'm trying to do is possible...I just can't quite figure out how to work out doing this as Javascript without a plugin. I'm fairly new at Javascript so thanks in advance for any pointers...perhaps how I can rewrite the second solution as a function?
This is the code that I found that works....
<script type="text/javascript">
var tableToExcel = (function() {
var uri = 'data:application/vnd.ms-excel;base64,'
, template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--><meta http-equiv="content-type" content="text/plain; charset=UTF-8"/></head><body><table>{table}</table></body></html>'
, base64 = function(s) { return window.btoa(unescape(encodeURIComponent(s))) }
, format = function(s, c) { return s.replace(/{(\w+)}/g, function(m, p) { return c[p]; }) }
return function(table, name) {
if (!table.nodeType) table = document.getElementById(table)
var ctx = {worksheet: name || 'Worksheet', table: table.innerHTML}
window.location.href = uri + base64(format(template, ctx))
}
})()
</script>
But I need to rewrite it so that I can call it in like the first function that is referenced at the beginning of my code above. Thanks again for any pointers or thoughts.
After more research I realized the second piece of code was the answer. I simply needed to update my HTML button reference as follows...
<button type="button" onclick="tableToExcel('tblData',)" class="class"><div class="class1"><h3 class="class2">Export To Excel</h3></div></button>

exporting html table with links to csv

I am using the following function to export a table to a csv file for our users to export a copy of their purchases to a format they can use in quickbooks, excel, etc.
The function works great, except that the first column of our table contains urls and these columns appear blank in the export.
I am wondering how i could modify this so when a link is encountered as a field the text of that link would be added to the csv.
Example: an example would add an example to the csv for that field.
function exportTableToCSV($table, filename) {
var $rows = $table.find('tr:has(td),tr:has(th)'),
tmpColDelim = String.fromCharCode(11), // vertical tab character
tmpRowDelim = String.fromCharCode(0), // null character
colDelim = '","',
rowDelim = '"\r\n"',
csv = '"' + $rows.map(function (i, row) {
var $row = $(row), $cols = $row.find('td,th');
return $cols.map(function (j, col) {
var $col = $(col), text = $col.text();
return text.replace(/"/g, '""'); // escape double quotes
}).get().join(tmpColDelim);
}).get().join(tmpRowDelim).split(tmpRowDelim).join(rowDelim).split(tmpColDelim).join(colDelim) + '"',
csvData = 'data:application/csv;charset=utf-8,' + encodeURIComponent(csv);
console.log(csv);
if (window.navigator.msSaveBlob) { // IE 10+
window.navigator.msSaveOrOpenBlob(new Blob([csv],
{type: "text/plain;charset=utf-8;"}),
"csvname.csv")
} else {
$(this).attr({ 'download': filename, 'href': csvData, 'target': '_blank' });
}
}
As far as I can see, your snippet should already support this. It iterates over all rows of the table and for each row over all of its column fields, where jQuery's text() function is applied in order to extract the text. This should return the text between a tags as well.
Example:
console.log($('<td>Test page</td>').text());
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
will return the string Test page.
This fiddle contains the function you provided and a dummy table with some anchor elements. In my opinion it already meets your requirements.
var a = document.createElement('a');
a.href = "http://example.php";
a.append("an example");
document.body.appendChild(a);
console.log(a.textContent);

Modify the script to export only visible rows

Currently I am using below script for export data to excel. It's exporting all the available data in Table. I want to modify in such a way that it can only export visible rows. Also I want to add some more columns/informations to the table to be downloaded.
var tableToExcel = (function() {
var uri = 'data:application/vnd.ms-excel;base64,'
, template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>{table}</table></body></html>'
, base64 = function(s) { return window.btoa(unescape(encodeURIComponent(s))) }
, format = function(s, c) { return s.replace(/{(\w+)}/g, function(m, p) { return c[p]; }) }
return function(table, name,filename) {
if (!table.nodeType) table = document.getElementById("testTable");
var ctx = {worksheet: name || 'Worksheet', table: table.innerHTML}
document.getElementById("dlink").href = uri + base64(format(template, ctx));
document.getElementById("dlink").download = filename;
document.getElementById("dlink").click();
}
});
am using $('[style*="display: none"]').remove(); for removing hidden columns. but it also removes data from table. I want to get this remove from only exported data. and want to add some more information in exported sheet.
Any input/suggestion from any of you will be appreciated.

Superscript in excel sheet while exporting using javascript

I'm exporting a table from a HTML page using the following Javascript code:
<script>
var tableToExcel = (function() {
var uri = 'data:application/vnd.ms-excel;base64,'
, template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>{table}</table></body></html>'
, base64 = function(s) { return window.btoa(unescape(encodeURIComponent(s))) }
, format = function(s, c) { return s.replace(/{(\w+)}/g, function(m, p) { return c[p]; }) }
return function(table, name) {
if (!table.nodeType) table = document.getElementById(table)
var ctx = {worksheet: name || 'Worksheet', table: table.innerHTML}
window.location.href = uri + base64(format(template, ctx))
}
})()
</script>
<body>
<table id="maintable">
some table content
</table>
<input type="button" onClick=tableToExcel(maintable,"tablename") />
</body>
This code converts the table to an excel sheet.
But superscript characters are not moved up but stay as it is.
Example: X2 becomes X2 in excel.
I have tried unicode \u00B2 as well but it doesn't work.
Is it possible to export superscript characters to excel?
If yes, how can i achieve this.
Thanks in advance.
[Edit] I get output like X² if I use unicode ² or ² or ²
It turns out that the above script is unable to convert unicode properly.
The best solution that worked for me is using the html tag sup as follows:
<tr>
<td>X<sup>2</sup></td>
</tr>
Hope this helps.

Export data in CSV, Excel, PDF format in AngularJS

I want to add export table data in CSV, Excel, PDF format functionality in my app.
I am building app using angularjs 1.2.16.
Export data in Excel
I have used
<script src="https://rawgithub.com/eligrey/FileSaver.js/master/FileSaver.js" type="text/javascript"></script>
to export table to XLS format using following code :
var blob = new Blob([document.getElementById('exportable').innerHTML], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"
});
saveAs(blob, "report.xls");
above code is working fine.
Export data in CSV, PDF
In the same way i want to export data in CSV and PDF format.
I have used http://www.directiv.es/ng-csv to export data in CSV but it is not working fine in ubuntu libre office (file is showing corrupted data).
Can anyone tell me how to export table data in CSV,Excel and PDF format in angularjs?
You can export data from AngularJS to XLS, XLSX, CSV, and TAB formats with Alasql JavaScript library with XLSX.js.
Include two libraries into the code:
alasql.min.js
xlsx.core.min.js
To export data to Excel format create a function in the controller code:
function myCtrl($scope) {
$scope.exportData = function () {
alasql('SELECT * INTO XLSX("mydata.xlsx",{headers:true}) FROM ?',[$scope.items]);
};
$scope.items = [{a:1,b:10},{a:2,b:20},{a:3,b:30}];
};
Then create a button (or any other link) in HTML:
<div ng-controller="myCtrl">
<button ng-click="exportData()">Export</button>
</div>
Try this example in jsFiddle.
To save data into CSV format use CSV() function:
alasql("SELECT * INTO CSV('mydata.csv', {headers:true}) FROM ?",[$scope.mydata]);
Or use TXT(), CSV(), TAB(), XLS(), XLSX() functions for proper file formats.
If you're satisfied with a CSV file, then the ngCsv module is the way to go. You don't load elements from the DOM but export an array directly. Here you can see a sample of ngCsv in action.
The html:
<h2>Export {{sample}}</h2>
<div>
<button type="button" ng-csv="getArray" filename="test.csv">Export</button>
</div>
and the js:
angular.module('csv', ['ngCsv']);
function Main($scope) {
$scope.sample = "Sample";
$scope.getArray = [{a: 1, b:2}, {a:3, b:4}];
}
saveAs; To change the registered file extension, for example: "f:\folder\report.html" directory?
var blob = new Blob([document.getElementById('exportable').innerHTML], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8" });
saveAs(blob, "report.xls");
I've worked through several approaches and concluded the following, typesafe (DefinitelyTyped):
exportAsExcel(tableId: string, fileName: string, linkElement: any) {
var uri = 'data:application/vnd.ms-excel;base64,',
template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>{table}</table></body></html>',
base64 = function (s) {
return window.btoa(decodeURI(encodeURIComponent(s)));
},
format = function (s, c) {
return s.replace(/{(\w+)}/g, function (m, p) {
return c[p];
});
};
// get the table data
var table = document.getElementById(tableId);
var ctx = {
worksheet: fileName,
table: table.innerHTML
};
// if browser is IE then save the file as blob, tested on IE10 and IE11
var browser = window.navigator.appVersion;
if ((browser.indexOf('Trident') !== -1 && browser.indexOf('rv:11') !== -1) ||
(browser.indexOf('MSIE 10') !== -1)) {
var builder = new MSBlobBuilder();
builder.append(uri + format(template, ctx));
var blob = builder.getBlob('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
window.navigator.msSaveBlob(blob, fileName + '.xlsx');
} else {
var element = document.getElementById(linkElement);
var a = document.createElement('a');
a.href = uri + base64(format(template, ctx));
a.target = '_blank';
a.setAttribute('download', fileName + '.xlsx');
document.body.appendChild(a);
a.click();
}
toastr.success("Awesome!", "We've created an Excel report for you and you should get it as a download in your browser.");
}
Kudos go to those who contributed of course in the various article.s
we can export data from a table into various format including
Json, Xml, Pdf .....
You can find detailed explanation http://www.prathapkudupublog.com/2015/10/angular-export-to-table.html
Note: This implementation would not run in IE
What do you need?
Angularjs
Jquery.js
Files referenced below
tableExport.js,JqueryBase64.js,html2canvas.js,base64.js,Jspdf.js,sprintf.js
<script type="text/javascript">
var myAppModule = angular.module('myApp', []);
myAppModule.controller('myCtrl', function ($scope) {
$scope.exportData = function () {
$('#customers').tableExport({ type: 'json', escape: 'false' });
};
$scope.items = [
{
"FirstName": "Prathap",
"LastName": "Kudupu",
"Address": "Near Anjana Beach"
},
{
"FirstName": "Deepak",
"LastName": "Dsouza",
"Address": "Near Nariman Point"
}
];
});

Categories