How do I convert html2pdf PDF to base64? - javascript

I'm having some trouble getting the html2pdf.js to properly give me a callback so that I can convert it to a base64 string.
I have tried this:
html2pdf().from(el).then(function(pdf) {
// pdf is null when I log this...
console.log(pdf);
}).save();
Along with many other variations using everything from output() to this:
var pdf = new jsPDF();
html2pdf().from(element).set({ pdf: pdf }).toPdf().save();
All to no avail.
I'm currently on v.0.9.0. All that I really need to get is the base64 so I can send that back to the server and attach it to an email - it doesn't really matter to me how I accomplish that but I'm having issues figuring out how to use this callback properly.
I have searched through the documentation and the issues on github.

What is missing is a call to the outputPdf() method. You should also make sure that you have upgraded to the latest version of the html2pdf plugin as older versions did not have this support.
Your new code should look like this:
html2pdf().from(el).outputPdf().then(function(pdf) {
// This logs the right base64
console.log(btoa(pdf));
});
From the documentation:
[outputPdf] Sends type and options to the jsPDF object's output method, and
returns the result as a Promise (use .then to access)
Simply using output() will not return a promise, you must use outputPdf().

Related

Print Image in Server side on Button Click by Client [duplicate]

Ok, so I'm trying to print from a webpage (the typical "print" button, but I don't want the print dialog to appear) so I decided to use my already existing node.js backend to do the task (mainly because printing from browser is nearly impossible without the printing dialog).
I found the node-printer (https://github.com/tojocky/node-printer) module, and it works great, but only with text. I tried to send RAW data, but what it does is printing the raw characters. What I actually need is to print a logo, along with some turn information (this is for a customer care facility).
Also, the printer must be installed locally, so I can't use IPP.
Is there any way to print an image, or a combination of images and text with node.js? can it be done through node-printer or is there another way?
I ended calling an exe to do the work for me. I use a child_process to call printhtml, which does all the printing work for me. My code ended this way:
var exec = require('child_process').exec;
exec('printhtml.exe file=file.html', function(err, data) {
console.log(data.toString());
});
Actually, you can print image using node-printer. This work for me
var Printer = require('node-printer');
var fs = require('fs');
// Get available printers list
var listPrinter = Printer.list();
// Create a new Pinter from available devices
var printer = new Printer('YOUR PRINTER HERE. GET IT FROM listPrinter');
// Print from a buffer, file path or text
var fileBuffer = fs.readFileSync('PATH TO YOUR IMAGE');
var jobFromBuffer = printer.printBuffer(fileBuffer);
// Listen events from job
jobFromBuffer.once('sent', function() {
jobFromBuffer.on('completed', function() {
console.log('Job ' + jobFromBuffer.identifier + 'has been printed');
jobFromBuffer.removeAllListeners();
});
});
I had success with the Node IPP package https://www.npmjs.com/package/ipp.
The example code on the docs, which uses another node module PDFKIT to convert your html/file into a PDF, does not work. See my answer here: Cannot print with node js ipp module for a working example.

Loading CSV file with AlaSQL and JQuery

I'm building an HTML based app for querying imported CSV file using AlaSQL. I started with this demo and tried to implement the same behavior by setting the onChange event through JQuery rather than in the tag. I basically follow the same pattern, and naively pass the event forward to the loadFile method. Alternatively, I tried just handling the alasql request right in the callback.
html:
<input id="with-jquery" name="with-jquery" type="file" />
javascript:
$('#with-jquery').on('change', function(event)
{
console.log('in jquery callback');
filename = $('#with-jquery').val();
console.log("filename: " + filename);
alasql('SELECT * FROM FILE(?,{headers:true})',[event],function(res){
console.log('in alasql callback');
data = res;
console.log(res);
document.getElementById("jquery-result").textContent = JSON.stringify(res);
});
//loadFile(event);
});
http://plnkr.co/edit/FOWwVsW7zAUGwv3BDBdN?p=preview
When I try to load the file using the JQuery handler, I get
in jquery callback
test.js:7 filename: C:\fakepath\sample.csv
alasql.min.js:13 Uncaught Error: Wrong usage of FILE() function
Here are some questions:
I can't find documentation for what alasql expects in the [event] slot.
How does the FROM FILE method relate to the more specific FROM CSV and FROM XLSX methods.
The wiki shows using the FROM CSV method by supplying a file name. I can't imagine how that would work without supplying the full path to a local file. But you can't get that from the browser.
The wiki also recommends using the "promise" format. How would I implement that here?

S3 waitUntilObjectExists in Javascript

I have a web app that uses S3 for storage. Sometimes one of my projects stored in S3 may be missing a resource (usually an image file) in this case I want to copy a missing image placeholder and display this instead. I am currently using copyObject but when I get the return from copyObject, the image is not yet there. I would rather not have to use a setTimeout to delay in hopes of the object actually being there a bit later so how can I do this in Javascript?
In
this post there is a reference to an S3 function called waitUntilObjectExists but it seems that is a PHP only function. What would be a Javascript friendly way to do this with the Javascript sdk?
You can use the error event to substitute broken images:
function imageMissingError(image) {
image.onerror = "";
image.src = "/path/to/the/image/replacement.gif";
return true;
}
<img src="thegoodimage.gif" onerror="imageMissingError(this);"/>

Use FileAPI to download big generated data file

The JavaScript process generates a lot of data (200-300MB). I would like to save this data for further analysis but the best I found so far is saving using this example http://jsfiddle.net/c2U2T/ which is not an option for me, because it looks like it requires all the data being available before starting the downloading. But what I need is something like
var saver = new Saver();
saver.save(); // The Save As ... dialog appears
saver.onaccepted = function () { // user accepted saving
for (var i = 0; i < 1000000; i++) {
saver.write(Math.random());
}
};
Of course, instead of the Math.random() will be some meaningful construction.
#dader - I would build upon dader's example.
Use HTML5 FileSystem API - but instead of writing to the file each and every line (more IO than it is worth), you can batch some of the lines in memory in a javascript object/array/string, and only write it to the file when they reach a certain threshold. You are thus appending to a local file as the process chugs (makes it easy to pause/restart/stop etc)
Of note is the following, which is an example of how you can spawn the dialoge to request the amount of data that you would need (it sounds large). Tested in chrome.:
navigator.persistentStorage.queryUsageAndQuota(
function (usage, quota) {
var availableSpace = quota - usage;
var requestingQuota = args.size + usage;
if (availableSpace >= args.size) {
window.requestFileSystem(PERSISTENT, availableSpace, persistentStorageGranted, persistentStorageDenied);
} else {
navigator.persistentStorage.requestQuota(
requestingQuota, function (grantedQuota) {
window.requestFileSystem(PERSISTENT, grantedQuota - usage, persistentStorageGranted, persistentStorageDenied);
}, errorCb
);
}
}, errorCb);
When you are done you can use Javascript to open a new window with the url of that blob object that you saved which you can retrieve via: fileEntry.toURL()
OR - when it is done crunching you can just display that URL in an html link and then they could right click on it and do whatever Save Link As that they want.
But this is something that is new and cool that you can do entirely in the browser without needing to involve a server in any way at all. Side note, 200-300MB of data generated by a Javascript Process sounds absolutely huge... that would be a concern for whether you are storing the "right" data...
What you actually are trying to do is a kind of streaming. I mean FileAPI is not suited for the task. Instead, I could suggest two options :
The first, using XHR facility, ie ajax, by splitting your data into several chunks which will sequencially be sent to the server, each chunk in its own request along with an id ( for identifying the stream ) and a position index ( for identifying the chunk position ). I won't recommend that, since it adds work to break up and reassemble data, and since there's a better solution.
The second way of achieving this is to use Websocket API. It allows you to send data sequentially to the server as it is generated. Following a usual stream API. I think you definitely need this.
This page may be a good place to start at : http://binaryjs.com/
That's all folks !
EDIT considering your comment :
I'm not sure to perfectly get your point though but, what about HTML5's FileSystem API ?
There are a couple examples here : http://www.html5rocks.com/en/tutorials/file/filesystem/ among which this sample that allows you to append data to an existant file. You can also create a new file, etc. :
function onInitFs(fs) {
fs.root.getFile('log.txt', {create: false}, function(fileEntry) {
// Create a FileWriter object for our FileEntry (log.txt).
fileEntry.createWriter(function(fileWriter) {
fileWriter.seek(fileWriter.length); // Start write position at EOF.
// Create a new Blob and write it to log.txt.
var blob = new Blob(['Hello World'], {type: 'text/plain'});
fileWriter.write(blob);
}, errorHandler);
}, errorHandler);
}
EDIT 2 :
What you're trying to do is not possible using javascript as said on SO here. Tha author nonetheless suggest to use Java Applet to achieve needed behaviour.
To put it in a nutshell, HTML5 Filesystem API only provides a sandboxed filesystem, ie located in some hidden directory of the browser. So if you want to access the true filesystem, using java would be just fine considering your use case. I guess there is an interface between java and javascript here.
But if you want to make your data only available from the browser ( constrained by same origin policy ), use FileSystem API.

Reading image capture files in PhoneGap

I'm working on a PhoneGap application that captures images using the camera and, later, uploads them. There are two modes of operation for camera in PhoneGap: raw base64 encoded data or a file URI.
The docs themselves say:
Note: The image quality of pictures taken using the camera on newer
devices is quite good. Encoding such images using Base64 has caused
memory issues on some of these devices (iPhone 4, BlackBerry Torch
9800). Therefore, using FILE_URI as the 'Camera.destinationType' is
highly recommended.
So I'm keen to use FILE_URI option. This works great and you can even show the images in IMG tags. The URL looks like this:
file://localhost/var/mobile/Applications/4FE4642B-944C-449BB-9BD6-1E442E47C7CE/tmp/photo_047.jpg
However, at some point later I want to read the contents of the file to upload to a server. I was going to do this using the FileReader type. This doesn't work and I think it's because I can't access the file at the URL above.
The error code I get back from readDataUrl is 1 > FileError.NOT_FOUND_ERR = 1;
Any ideas how I can get to the file? I tried just accessing the last part of the path (photo_047.jpg) based on another sample I saw but no luck.
I'm just getting started with PhoneGap, and given the age of this question you may have found an answer already, but I'll give it a try anyway.
First, would you be able to use the built-in FileTransfer object? It takes a file: URI as an argument.
If FileTransfer won't work for you, and you need to read the file data yourself, you'll need the PhoneGap File objects, like FileReader , as you said. But most of those expect a plain pathname -- not a URI -- to specify the file to work with. The reason you're getting NOT_FOUND_ERR is because it's trying to open a file named file:/localhost/var....
Here's a quick one-liner to extract the path part from your URI:
var path = /file:\/\/.*?(\/.*)/.exec(fileuri)[1];
Hope this helps!
The answer from jgarbers was of help to me but it did not solve the problem. I realized the camera stores photos in Temp folder instead of Document folder. Setting my local file system to temporary allowed it to find the correct location for the camera images.
window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, ...
...
window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, ...
...
var path = /file://.?(/.)/.exec(fileuri)[1];
Ref. above jgarbers and Rik answers (solution has been tested successfully on iOs 7)
you can user the file transfer plugin for uploading any file to the server.
//// pass your file uri to the mediafie param
function uploadFile(mediaFile) {
var ft = new FileTransfer();
path = mediaFile.fullPath;
name = mediaFile.name;
////your service method url
var objUrl = http://example.com;
ft.upload(path,
objUrl,
function (result) {
alert("Success");
},
function (error) {
alert('Error uploading file ' + path + ': ' + error.code);
},
{ fileName: name });
}

Categories