How to display base64 string as a pdf in lightning component - salesforce

i have a requirement where i need to display Base64 string as PDF in lightning component without saving that string as file or attachment in salesforce.

You could use a 3rd party Javascript library that can generate PDF on the client side.
Example with jsPDF
Define a Blob and insert in in a <iframe> :
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.debug.js" integrity="sha384-NaWTHo/8YCBYJ59830LTz/P4aQZK1sS0SneOgAvhsIl3zBu8r9RevNg5lHCHAuQ/" crossorigin="anonymous"></script>
<iframe id=iframe></iframe>
<script>
var doc = new jsPDF();
doc.text("Hello World", 35, 25);
var blob = doc.output( 'blob' )
var file = new File( [blob], 'a_name.pdf', { type: 'application/pdf' } )
iframe.src = URL.createObjectURL( file )
</script>

Related

jsPDF package is downloading as an empty PDF for html content in react (typescript)

I am using jsPDF to download HTML content as pdf in react. I can download a pdf file, but it is showing an empty page only. If I use text for download like this
const doc = new jsPDF("p", "pt", "a4", true);
doc.text("hello", 10, 20);
doc.save();
it is downloading with the content "hello". But I use html to download,
const doc = new jsPDF("p", "pt", "a4", true);
var elem: any = document.getElementById("test");
doc.html(elem, {
callback: (doc: any) => {
doc.save(`Test.pdf`);
}
});
It is downloading as an empty page only. Since the tag changed to fromHTML to html, I need help on this. (previous discussions are a long time ago happened).

upload image file converted from html to s3

I have a piece of HTML which I converted into an image using html-to-image and now I need to upload that image file to s3.
What I get after conversion is base 64 url. I have my s3 setup on remote backend where I send files to the api route and it uploads it to s3 and returns the s3 url for the file.
How can I convert this base url to image obj and send it to the api?
Function to convert html to img:
htmlToImage.toPng(document.getElementById('my-node'))
.then(function (dataUrl) {
// do stuff with url
});
There is a pretty simple common function which converts image data url to a file object defined as following:
function dataURLtoFile(dataurl, filename) {
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, { type:mime });
}
// Usage in your case
htmlToImage.toPng(document.getElementById('my-node'))
.then(function (dataUrl) {
const yourFile = dataURLtoFile(dataUrl, 'yourImageName');
});

How to get a tensor from an image

I have an image and I would like to get the tensor from it.
Some of the images are already on the frontend server be whereas others will be served by the server
To do that, one needs to use fromPixels
In case the image is already displayed in an html page
You can consider doing a querySelector to get the image first and then you can use fromPixels
html
<img id="my-image" src="mydata.jpg">
js
const image = document.querySelector("#my-image")
const t = tf.fromPixels(image)
If the image is not present in the html page, you can use the constructor Image to create it and then pass it as parameter to fromPixels
const im = new Image()
im.onload = () => {
const a = tf.fromPixels(im, 4)
a.print()
console.log(a.shape)
}
im.src = "url-of-the-image"
document.body.appendChild(im)
onload makes sure that the image has finished downloading before converting it to a tensor.
If the image url and the url on which the frontend page is served are different there will be a cross-origin issue when creating the tensor. If the server serves the image with an access control that allows the frontend to retrieve that image, then setting the crossOrigin attribute of the image will solve the issue, otherwise there will nothing that can be done to get the tensor from that image.
const im = new Image()
im.crossOrigin = "anonymous";
im.src = "https://i.imgur.com/lVlPvCB.gif"
document.body.appendChild(im)
im.onload = () => {
const a = tf.fromPixels(im, 4)
a.print()
console.log(a.shape)
}
<html>
<head>
<!-- Load TensorFlow.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/tensorflow/0.12.4/tf.js"> </script>
</head>
<body>
</body>
</html>

PDF file name not taken into account in IE10 / Edge

Using this code, i have the pdf's name that is incorrect : A string of random letters like a uuid.
This problem seems to only be with IE 10 / Edge.
AngularJS's version 1.4.7
this.downloadPdf = function(pdfName){
console.log(pdfName);
$http.get(config.UrlApi + "/pdf/"+ pdfName.nameFile, { responseType: 'arraybuffer' });
var a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.target = '_blank';
a.download = pdfName.name;
document.body.appendChild(a);
a.click();
});
Use the Blob Interface:
function build(response)
{
var bb = new Blob([response.data], { type: "application/pdf"});
if (URL && URL.hasOwnProperty("createObjectURL") )
{
var url = URL.createObjectURL(bb);
}
else if (window.navigator.msSaveOrOpenBlob)
{
window.navigator.msSaveOrOpenBlob(bb, 'foo.pdf');
}
}
$http.get(config.UrlApi + "/pdf/"+ pdfName.nameFile, { responseType: 'arraybuffer' }).then(build);
Blob urls are subject to an origin policy. This means that they can only be used in documents that have the same site-of-origin as the document running the script that created the url. If you need to use the blob object from an <iframe> that is running in a different domain, you must use the postMessage API to send the blob data to the frame and then create the blob: url there.
References
Saving files locally using Blob and msSaveBlob
New Blob Constructor in IE10
Edge Doesn't Use download attribute to set filename for blob URI downloading
Blob Object
URL.createObjectURL
MSDN: JavaScript Version Information

Save PDF file loaded in iframe

I am trying to save a pdf file that is loaded in an iFrame. There is by default a button in the iFrame to save the file but I want an extra button (outside the iFrame) to save the file.
<iframe id="labelFrame" src="loadedFile.pdf"></iframe>
<button id="savePDF">Download File</button>
In javascript:
$('#savePDF').click(function(){
var save = document.getElementById('labelFrame');
//Save the file by opening the explorer for the user to select the place to save or save the file in a default location, how do I do this?
}
What is the best way to reach this?
I needed an answer to this question as well and found a solution.
When displaying a PDF in an IFrame the browser will render it in an <embed> element and from there we cant use it in javascript as far as i know.
We'll need to use XMLHttpRequest to get the PDF from a server as a Blob object only then we can both display it and save it using javascript.
var iframe = document.getElementById('labelFrame'),
saveBtn = document.getElementById('savePDF'),
pdfUrl = 'loadedFile.pdf';
var xhr = new XMLHttpRequest();
xhr.open("GET", pdfUrl);
xhr.responseType = 'blob'; // <- important (but since IE10)
xhr.onload = function() {
var blobUrl = URL.createObjectURL(xhr.response); // <- used for display + download
iframe.src = blobUrl
saveBtn.onclick = function() {
downloadBlob(blobUrl, 'myFilename.pdf');
}
};
xhr.send();
The xhr.onload function will set to src of the iframe and add the onclick handler to the save button
Here is the downloadBlob() function that i've used in the example
function downloadBlob(blobUrl, filename) {
var a = document.createElement('a');
a.href = blobUrl;
a.target = '_parent';
// Use a.download if available. This increases the likelihood that
// the file is downloaded instead of opened by another PDF plugin.
if ('download' in a) {
a.download = filename;
}
// <a> must be in the document for IE and recent Firefox versions,
// otherwise .click() is ignored.
(document.body || document.documentElement).appendChild(a);
a.click();
a.remove();
}

Resources