No pdf generated - jspdf

i use jsPDF and plugin jsPDF-AutoTable
I have a html table i want to print
$('#printFreeRoom').on('click', function (e) {
freeRoomAvailableReport($("#freeRoomTableResult"));
});
function freeRoomAvailableReport(tableId) {
var doc = new jsPDF('p', 'pt');
doc.text("From HTML", 40, 50);
var res = doc.autoTableHtmlToJson(tableId);
doc.autoTable(res.columns, res.data, {
startY: 60
});
doc.output('dataurlnewwindow');
doc.save('test.pdf');
}
nothing is generated when i click on the button.
I created a example on jsfiddle
http://jsfiddle.net/8da5e1fj/
seem like a chrome problem...
tried other example: http://jsfiddle.net/8tLt9yof/10/ and get same result.

You need to add FileSaver.js to use doc.save() also, Chrome has issues with doc.output('dataurlnewwindow')
Hence, here is a working fiddle for doc.save fiddle
And, to open the PDF in new window try this -
var blob = doc.output("blob");
window.open(URL.createObjectURL(blob));
Just an additional "Enter" on the browser address bar will show the PDF in chrome.
UPDATE
Longer URL's are not supported by Chrome as per this. Canvas in the fiddle is generating base64 URL which Chrome fails to load.

Related

Vaadin Flow download code works for Chrome but not for Firefox - How can I support both?

I have the following code to download a file from Vaadin Flow (12.0.7).
exportBtn.addClickListener(e -> {
toDownload = FileUtil.getLatestExport();
(toDownload != null) {
StreamResource resource = new StreamResource(toDownload.getName(),
() -> FileUtil.getInputStreamForFile(toDownload));
Element object = new Element("object");
object.setAttribute("download", true);
object.setAttribute("data", resource);
Input name = new Input();
UI.getCurrent().getElement().appendChild(name.getElement(), object);
}
});
toDownload locates the file which I want to download. If I click the button from Chrome the browser downloads my file if I click the button from Firefox nothing happens. In what way do I need to adjust my code to support Chrome and Firefox?
I used this tutorial as reference.
There is also a workaround for downloads triggered by some action in Vaadin Flow, e.g. you have a button that conditionally shows a dialog before downloading the file:
Anchor hiddenDownloadLink = new Anchor(createYourStreamResource(), "Workaround");
hiddenDownloadLink.setId("DownloadLinkWorkaround_" + System.currentTimeMillis());
hiddenDownloadLink.getElement().setAttribute("style", "display: none");
// TODO: add the link somehwere in your view
UI.getCurrent().getPage().executeJs("document.getElementById('" + hiddenDownloadLink.getId().orElseThrow() + "').click();");
Tested in FF, Chrome and Edge. The workaround simulates a click on an anchor that triggers the download.

pdf.js rendering as PDF with base64

I am stuck at last point of my application, i am supposed to display user form in PDF which works fine on desktop browsers as they has pdf viewer built in, but for Android / iOS its not working as pdf viewer is missing.
So i was trying to use PDF.js to display it, (to be honest, this is very widely used but documentation is lacking), only catch is i am getting data in base64 format. PDF.js has example on site which shows how to render the base64 data but its not PDF, for that displaying PDF as "PDF" i need to user their "viewer.html" but that does not take base64 data?
closest i have come to Pdf.js: rendering a pdf file using base64... on stack overflow, but i dont know how to use it after PDFJS.getDocument(pdfAsArray)?.
Other link that came across was other link
I dont want to rely on Google / Third party PDF viewer as i dont know how long they will support this.
There are no end-to-end answers on this topic in community so here is my attempt to put something here. (maybe it will help others)
Okay, PDF.js is one way of showing PDF in browser, specially when you don't want to rely on PDF plugin to be installed. In my case, my application generates report in PDF and that can be viewed before downloading but on handheld devices it was not working because of missing PDF viewer plugin.
In my case PDF was sent to browse in base64 string, that I can use to display PDF with <object src="base64-data"...></object>. This works like charm on Chrome / FF but switch to mobile view and it stops working.
<object type="application/pdf" id="pdfbin" width="100%" height="100%" title="Report.pdf">
<p class="text-center">Looks like there is no PDF viewer plugin installed, try one of the below approach...</p>
</object>
In above code it will try to show the PDF or fall back to <p> and show error message. And I Was planning to add the PDF viewer at this point, PDF.js was the choice but was not able to display it. One example on PDF.js with Base64 data shows how to do this but that renders it as an Image not PDF, and I was not able to find solution for that and hence the question, here is what I did,
First add the JavaScript code to convert base64 to array
convert to blob and use viewer.html file packaged with PDF.js to display it as PDF
In case if you are wondering why base64 data, then answer is simple I can create the PDF, read it, send the data to client and delete the file, I don't have to run any cleaner service/cron job to delete generated PDF files
Few Things To Note
Below code is using Flask + Jinja2, change the way base64 is read in html if you are using something else
viewer.html needs to be changed to have required js & css files in proper location (by default their location is relative; you need them to be referred from static folder)
viewer.js looks for pdf.worker.js in predefined location, change that in case its throwing error as above file not found.
viewer.js might throw file origin does not match viewer error in that case as a quick fix comment the code which throws this error and see if that solves the issue (look for that error in viewer.js)
I am not the author of below code, I have just put it together from different places.
Now to the code (so PDF will be displayed when user clicks on button with id="open_id")
Jquery
var pdfDataX = '{{ base64Pdf }}';
var BASE64_MARKER = ';base64,';
PDFJS.workerSrc = "{{ url_for('static', filename='js/pdf.worker.js') }}";
$('#open_id').click(function() {
PDFJS.disableWorker = true;
var pdfAsDataUri = "data:application/pdf;base64," + pdfDataX ;
PDFJS.workerSrc = "{{ url_for('static', filename='js/pdf.worker.js') }}";
// Try to show in the viewer.html
var blob = base64toBlob(pdfDataX, 'application/pdf');
var url = URL.createObjectURL(blob);
var viewerUrl = "{{ url_for('static', filename='viewer.html') }}" + '?file=' + encodeURIComponent(url);
$('#pdfViewer').attr('src', viewerUrl);
// Finish
var mdObj = $('#pdfbin');
mdObj.hide();
mdObj.attr('data', pdfAsDataUri);
mdObj.show();
$('#myModal').modal();
});
var base64toBlob = function(b64Data, contentType, sliceSize) {
contentType = contentType || '';
sliceSize = sliceSize || 512;
var byteCharacters = atob(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i=0; i<slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
var blob = new Blob(byteArrays, {type: contentType});
return blob;
}
$('.save').click(function(e) {
e.preventDefault();
var blob = base64toBlob(pdfDataX, 'application/pdf');
saveAs(blob, 'abcd.pdf'); // requires https://github.com/eligrey/FileSaver.js/
return false;
});
HTML
<object type="application/pdf" id="pdfbin" width="100%" height="100%" title="Resume.pdf">
<p class="text-center">Looks like there is no PDF viewer plugin installed, try one of the below approach...</p>
<iframe id="pdfViewer" style="width: 100%; height: 100%;" allowfullscreen="" webkitallowfullscreen=""></iframe>
</object>
Hope this will be useful for others in future.

How to enable downloadify in jsPdf?

Hey I have added jsPdf into my HTML to download the HTML as a PDF, but in IE 9 it doesn't works. It is not downloading any PDF so I searched about this and got the I have to enable the IE shim for this so can you help me out that how I can be able to do that, I have tried to use Downloadify but didn't understand how to pass full HTML file and get the image of that into PDF.
These are the steps, but the support for downloadify is poor.
Add these script tags to the top of your page (changing the path as appropriate to the files in the lib directory of jspdf):
<script src="./js/jspdf/libs/Downloadify/js/downloadify.min.js"></script>
<script src="./js/jspdf/libs/Downloadify/js/swfobject.js"></script>
add a <div id="downloadify"> in your dom. This div should be empty.
Next, add a script tag to the bottom of your page that will run after the DOM has been populated. This script will generate a button in the '#downloadify' div. Put this inside of the script tag:
Downloadify.create('downloadify',{ // this first argument id a dom element id. this is how it knows where to populate the flash button it's creating.
filename: "afilename.pdf",
data: function(){
// generate your pdf here.
var pdf = new jsPDF;
// various other jspdf commands here
return pdf.output();
},
onComplete: function(){
alert('Your File Has Been Saved!');
},
onCancel: function(){
alert('You have cancelled the saving of this file.');
},
onError: function(){
alert('You must put something in the File Contents or there will be nothing to save!');
},
swf: './js/jspdf/libs/Downloadify/media/downloadify.swf', // make sure this links properly to your file as well.
downloadImage: './js/jspdf/libs/Downloadify/images/download.png', // this is the link to the image of the button itself. An ugly default is included. If you want to style the button, you have to create a sprite image of the same kind.
width: 100, // width of the button
height: 30, // 1/4 height of the button image (which has four states present)
transparent: true, // seems to do nothing, set to true or false.
append: false // have not figured out what this does.
});

Rails Cloudinary Direct Image Upload After Commit

I have a question regarding direct-image-upload from Cloudinary. I could set this up in a rails app using simple-form and <% = f.cl_image_upload (: file)%> but after I select the file, it start uploading. I don't like this approach and I want that upload start just after commit the form. Is it possible? I worry about having file in Cloudinary server which does not have a corresponding id in my database.
The default implementation indeed automatically uploads a file once selected. Most users don't bother with deleting accidentally uploaded images as they don't take a lot of extra storage. However, if you wish not to upload the image automatically on selection, you can set the autoUpload to false in the fileupload call. For example:
$(document).ready(function() {
$('.cloudinary-fileupload').fileupload({
autoUpload: false
});
});
I think you can help me, Actually, I have this script...
<script>
$(document).ready(function() {
// Cloudinary jQuery integration library uses jQuery File Upload widget
// (see http://blueimp.github.io/jQuery-File-Upload/).
// Any file input field with cloudinary-fileupload class is automatically
// wrapped using the File Upload widget and configured for Cloudinary uploads.
// You can further customize the configuration using .fileupload method
// as we do below.
$(".cloudinary-fileupload")
.fileupload({
// Uncomment the following lines to enable client side image resizing and valiation.
// Make sure cloudinary/processing is included the js file
disableImageMetaDataLoad: true,
disableImageResize: false,
imageMaxWidth: 800,
imageMaxHeight: 800,
acceptFileTypes: /(\.|\/)(gif|jpe?g|png|bmp|ico)$/i,
maxFileSize: 20000000, // 20MB
dropZone: "#direct_upload",
start: function (e) {
$(".status").text("Starting upload...");
},
progress: function (e, data) {
$(".status").text("Uploading... " + Math.round((data.loaded * 100.0) / data.total) + "%");
},
fail: function (e, data) {
$(".status").text("Upload failed");
}
})
.off("cloudinarydone").on("cloudinarydone", function (e, data) {
$(".status").text("");
$(".preview").html(
$.cloudinary.image(data.result.public_id, {
format: data.result.format, width: 150, height: 100, crop: "limit"
})
);
});
});
</script>
I'm beginning with javascript. This script above is working fine, but it just show me the preview after upload it. I don't like this approach because, if user change the preview image, I will have one file upload to Cloudinary without relative register in my db. Will be great if is possible show the preview and just upload after the user press submit in the form.
Note: I hope you understand me, I'm from Brazil and I don't write in english very well.

Cordova 2.3.0 Open links in Safari on iOS

I know this has been asked a lot, but i tried almost anything I could find here and nothing helps.
I want to open links with class "external" in native iOS browser, but i'm not able to manage it.
Here is what I tried:
$('.external').live('click', function(event) {
event.preventDefault();
var url = $(this).attr('href');
loadURL(url);
})
function loadURL(url){
var ref = window.open(url, '_system');
}
As of phonegap documentation, it should now open the link in system webbrowser, but it always uses the InAppBrowser, no matter of the link-target.
I also set "OpenAllWhitelistURLsInWebView" to false in config.xml. No change.
Can you double check that your click handler is actually being invoked? If you put the code that attaches the event handler in the wrong location(i.e. in onDeviceReady(), then the click handler will not be invoked) -> the links will always be opened inside of the app. Also I am using jquery ".on" since ".live" has been removed in jquery 1.9; which I was using for my test.
I just tested the following code on Cordova 2.4.0, and it works. Here is some important code excerpts:
HTML portion:
<a class=".external" href="http://www.google.com">Go to external page</a>
JAVASCRIPT portion:
function loadURL(url){
var ref = window.open(url, '_system');
}
$(function(){
$('.external').on('click', function(event) {
event.preventDefault();
var url = $(this).attr('href');
loadURL(url);
});
});

Resources