I am using angularjs and am trying to create a system of downloading a vcard created in javascript. In order for the vcard to work on mobile, the data needs to be downloaded through an a tag. The problem is everytime I set the href="data:text/vcard, "+ string it saves the vCard but removes the newlines. vCards only work with newlines
Is there any way to keep the newline characters while saving data?
$scope.saveVcard = function(){
var user = $scope.member;
var out_string = 'BEGIN:VCARD\nVERSION:2.1\n\rN:' + user.last_name + ';' + user.first_name + ';;;\n\r'; //name
out_string += 'FN:' + user.first_name + ' ' + user.last_name + '\n\r';//FN
if (user.phone){
out_string += 'TEL;CELL:' + user.phone + '\n\r';} //Phone
if (user.email){
out_string += 'EMAIL;PREF;INTERNET:' + user.email + '\n\r';}//Email
if (user.prof_pic){
out_string += 'PHOTO;PNG:'+user.prof_pic + '\n\r';}//picture
out_string += 'END:VCARD';
var a = document.createElement('a');
a.href = 'data:text/vcard,' + out_string;
a.target = '_blank';
a.download = 'contact.vcf';
console.log(a.href);
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
Aha, I figured it out, simply use the function encodeURIComponent().
var a = document.createElement('a');
a.href = 'data:text/vcard,' + encodeURIComponent(out_string);
a.target = '_blank';
a.download = 'contact.vcf';
console.log(a.href);
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
Related
I am trying to generate a vCard .vcf file and download it on click. It works perfectly for all browsers except Safari. On safari, it downloads example.com instead of the proper file. I read a lot about the Safari download attribute issue, but it seems this is not the problem in my case. Any help would be highly appreciated.
This is my crappy code :)
let vCard = document.querySelector('.vcard')
let vcard_start ="BEGIN:VCARD\nVERSION:3.0\n"
let vcard_end = "END:VCARD"
let fullName = document.querySelector('#fullname').innerText
//let firstName = document.querySelector('#firstname').innerText
//let lastName = document.querySelector('#lastname').innerText
let title = document.querySelector('#title').innerText
let email = document.querySelector('#email').innerText
let phone = document.querySelector('#phone').innerText
let address = document.querySelector('#address').innerText
let vcard_download = document.querySelector('#vcard-download')
let currentURL = window.location.href
let attPhoto = document.querySelector('#att_image')
let attPhotoSRC = attPhoto.querySelector('img').src
let splitName = fullName.split(' ')
//let vCardPhoto =
//const space = split(/\r?\n/);
let vcardReady
let newName
if(splitName.length>=3){
newName = splitName[2] + ';' + splitName[0] + ' ' + splitName[1]
}else{
newName = splitName[1] + ';' + splitName[0]
}
function download(filename, text) {
var element = document.createElement('a');
element.setAttribute('href','data:text/vcard;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
let base64_image_encoded;
window.addEventListener('load',function(){
// Start file download.
vcard_download.addEventListener("click", function(){
const tmp = base64_image_encoded.split(",");
// Generate download of vCard file with some content
vcardReady = vcard_start+
"FN:"+fullName+ "\n" +
"N:" + newName + "\n" +
"EMAIL:" + email + "\n" +
"ORG:Carella, Byrne, Cecchi, Brody & Agnello, P.C\n" +
"ROLE:" + title + "\n" +
"TEL;TYPE=WORK;VOICE:" + phone + "\n" +
"URL:" + currentURL + "\n" +
"PHOTO;TYPE=JPEG;ENCODING=BASE64:"+ tmp[1] + "\n" +
"NOTE;CHARSET=us-ascii;ENCODING=QUOTED-PRINTABLE:" + "\n" +
vcard_end;
var text = vcardReady;
var filename = fullName+'.vcf';
download(filename, text);
});
toDataURL(attPhotoSRC, function (dataUrl) {
base64_image_encoded = dataUrl;
});
});
function toDataURL(src, callback, outputFormat) {
let image = new Image();
image.crossOrigin = 'Anonymous';
image.onload = function () {
let canvas = document.createElement('canvas');
let ctx = canvas.getContext('2d');
let dataURL;
canvas.height = this.naturalHeight;
canvas.width = this.naturalWidth;
ctx.drawImage(this, 0, 0);
dataURL = canvas.toDataURL(outputFormat);
callback(dataURL);
};
image.src = src;
if (image.complete || image.complete === undefined) {
image.src = "data:image/gif;base64, R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
image.src = src;
}
return image;
}
I have seen this issue when there was a newline character in the filename for Safari. Removing that newline did the trick for me
i want to save chart html to word file as image
but word file can download but chart image is just X image it means doesn't have data
could you give me solution
function ExportToDoc(filename = "") {
html2canvas(document.getElementById("pyramid")).then((canvas) => {
canvas.toBlob((blob) => {
if (blob) {
myBlob = blob;
}
});
});
var HtmlHead =
"<html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:w='urn:schemas-microsoft-com:office:word' xmlns='http://www.w3.org/TR/REC-html40'><head><meta charset='utf-8'><title>Export HTML To Doc</title></head><body>";
var EndHtml = "</body></html>";
//complete html
// var html = HtmlHead + document.getElementById("pyramid").innerHTML + EndHtml;
var html =
HtmlHead +
"<img src='" +
URL.createObjectURL(
new Blob(new Uint8Array(myBlob), { type: "image/png" })
) +
"'/>" +
EndHtml;
// "<div id='export'><img class='hide' src='" + URLObj.createObjectURL() +"'/></div>"
//specify the type
var blob = new Blob(["\ufeff", html], {
type: "application/msword",
});
// Specify link url
var url =
"data:application/vnd.ms-word;charset=utf-8," + encodeURIComponent(html);
// Specify file name
filename = filename ? filename + ".doc" : "document.doc";
// Create download link element
var downloadLink = document.createElement("a");
document.body.appendChild(downloadLink);
if (navigator.msSaveOrOpenBlob) {
navigator.msSaveOrOpenBlob(blob, filename);
} else {
downloadLink.href = url;
downloadLink.download = filename;
downloadLink.click();
}
document.body.removeChild(downloadLink);
}
enter image description here
for HTML
<Chart
id="pyramid"
...
</Chart>
chart is working well
function ExportToDoc(filename = "") {
var img = new Image();
html2canvas(document.getElementById("pyramid")).then((canvas) => {
img.src = canvas.toDataURL();
var HtmlHead =
"<html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:w='urn:schemas-microsoft-com:office:word' xmlns='http://www.w3.org/TR/REC-html40'><head><meta charset='utf-8'><title>Export HTML To Doc</title></head><body>";
var EndHtml = "</body></html>";
var html =
HtmlHead + "<img class='hide' src='" + img.src + "'/>" + EndHtml;
var blob = new Blob(["\ufeff", html], {
type: "application/msword",
});
var url =
"data:application/vnd.ms-word;charset=utf-8," +
encodeURIComponent(html);
filename = filename ? filename + ".doc" : "Document.doc";
var downloadLink = document.createElement("a");
document.body.appendChild(downloadLink);
if (navigator.msSaveOrOpenBlob) {
navigator.msSaveOrOpenBlob(blob, filename);
} else {
downloadLink.href = url;
downloadLink.download = filename;
downloadLink.click();
}
document.body.removeChild(downloadLink);
});
}
I solved it by myself.
Also upgraded:
function htmlToFile(element, file = "hwp") {
var img = new Image();
html2canvas(document.getElementById("pyramid")).then((canvas) => {
img.src = canvas.toDataURL();
var header = "<html><head><meta charset='utf-8'></head><body>";
var footer = "</body></html>";
var sourceHTML =
header + "<img class='hide' src='" + img.src + "'/>" + footer;
var source =
"data:application/vnd.ms-word;charset=utf-8," +
encodeURIComponent(sourceHTML);
var fileDownload = document.createElement("a");
document.body.appendChild(fileDownload);
fileDownload.href = source;
fileDownload.download = "Document." + file;
fileDownload.click();
document.body.removeChild(fileDownload);
});
}
Hi I am generating a CSV file based on some filtered data in my angular web app.
The input I am sending to my csvString is:
Torup Bakkegård (Middelfartvej 105); Coop Brøndby; (Holkebjergvej 54);
The output is always ruined once i open the excel file:
TorupBakkegård(Middelfartvej105) CoopBrøndby(Holkebjergvej54)
However when I open it with notepad it's fine, so it's just MS Excel(using the latest version) that seems to ruin it.
TorupBakkegård(Middelfartvej105);CoopBrøndby(Holkebjergvej54);
I tried with several encodings, it seems excel simply does not care
Here is the code javascript:
vm.downloadExcel = function (bookings) {
var csvRows = [];
var csvHeading = "Afhentningsadresse;Modtager";
csvRows.push(csvHeading + "\n");
for (var i = 0; i < bookings.length; i++) {
var csvRow = "";
csvRow += bookings[i].pickupAddress + ";";
csvRow += bookings[i].customerAddress + ";";
csvRows.push(csvRow + "\n");
}
var csvString = csvRows.join("%0A");
var a = document.createElement('a');
a.href = 'data:application/csv;charset=Windows-1252,' + csvString;
a.target = '_blank';
a.download = 'myFile.csv';
console.log(a.href);
document.body.appendChild(a);
a.click();
After a bit of research we figured out that we didn't mention the BOM.
The BOM is responsible for the encoding in the actual file.
So after changing:
a.href = 'data:application/csv;charset=Windows-1252,' + csvString;
With:
a.href = 'data:text/csv;charset=utf-8,%EF%BB%BF' + encodeURI(csvString);
Everything works just fine.
Credits goes to: Gergő Nagy, for answering:
Javascript to csv export encoding issue
please help me my probs,am using kendo ui grid in my webapp & trying to grid data export into EXcel and CSV format. Code Works good in Chrome and files are downloading, but in Fire Fox its open a new window show the grid details in url and says bad request,
//code is
$("#exportcsv").click(function (e) {
debugger
var dataSource = $("#grid").data("kendoGrid").dataSource;
var filteredDataSource = new kendo.data.DataSource({
data: dataSource.data(),
filter: dataSource.filter()
});
filteredDataSource.read();
var data = filteredDataSource.view();
//start with the desired column headers here
var result = "\"ID\",\"EID\",\"Name\",\"Company Name\",\"Salary\",\"DID\",\"Date Of Join\"";
//each column will need to be called using the field name in the data source
for (var i = 0; i < data.length; i++) {
result += "\n";
result += "\"" + data[i].id + "\",";
result += "\"" + data[i].EID + "\",";
result += "\"" + data[i].EName + "\",";
result += "\"" + data[i].CName + "\",";
result += "\"" + data[i].Salary + "\",";
result += "\"" + data[i].DID + "\",";
result += "\"" + data[i].DOJ + "\",";
}
if (window.navigator.msSaveBlob) {
//Internet Explorer
window.navigator.msSaveBlob(new Blob([result]), 'ExportedKendoGrid.csv');
}
else if (window.webkitURL != null) {
//Google Chrome and Mozilla Firefox
var a = document.createElement('a');
result = encodeURIComponent(result);
a.href = 'data:application/csv;charset=UTF-8,' + result;
a.download = 'ExportedKendoGrid.csv';
a.click();
}
else {
//Everything Else
window.open(result);
}
e.preventDefault();
});
//below code is not working in firefox browser else if
(window.webkitURL != null) {
//Google Chrome and Mozilla Firefox
var a = document.createElement('a');
result = encodeURIComponent(result);
a.href = 'data:application/csv;charset=UTF-8,' + result;
a.download = 'ExportedKendoGrid.csv';
a.click();
}
I currently have a block of code that exports tables in my HTML body to one excel file.
$(document).ready(function() {
$("#btnExport").click(function(e) {
//getting values of current time for generating the file name
var dt = new Date();
var day = dt.getDate();
var month = dt.getMonth() + 1;
var year = dt.getFullYear();
var hour = dt.getHours();
var mins = dt.getMinutes();
var postfix = day + "." + month + "." + year + "_" + hour + "." + mins;
//creating a temporary HTML link element (they support setting file names)
var a = document.createElement('a');
//getting data from our div that contains the HTML table
var data_type = 'data:application/vnd.ms-excel';
var table_div = document.getElementsByClassName("dvData");
var table_html = table_div[0].outerHTML.replace(/ /g, '%20');
var table_html2 = table_div[1].outerHTML.replace(/ /g, '%20');
var table_html3 = table_div[2].outerHTML.replace(/ /g, '%20');
a.href = data_type + ', ' + table_html + "<br></br>" + table_html2 + "<br></br>" + table_html3;
//setting the file name
a.download = 'exported_table_' + postfix + '.xls';
//triggering the function
a.click();
//just in case, prevent default behaviour
e.preventDefault();
});
});
</script>
When the excel file opens, I want it to have some vba code that automatically runs when the user opens the downloaded file.
Is this possible? If so, how do I "embed" the vba code into the excel file my code exports?