Creating an xls or csv file from a Javascript variable - javascript

I have an app that uses Javascript to perform some calculations and then plot the data, but I'd like to add the option for the user to be able to actually download the data into a csv or xls file.
Is there a way in Javascript (or some other method) to have the user press a button, then it will prompt them for the name of the file to save it as, and it will then create a comma-delimited or excel spreadsheet?
Thanks!
EDIT:
Thanks for all the suggestions everyone. Wish I could mark you all as answers, but upboats will have to do for now

It's not hard to open a window and write the csv into it. But I don't know of any way for javascript to change the Content-Type: header. And without that it won't prompt to save or open.
You'll need assistance from the server to do this. You can send the data to the server in a form variable and have the server send it right back with the correct header Content-type: text/csv you may also want the Content-Disposition: header to give your file a name.

Yes, but you'll need to use server-side code as well. Use JavaScript to construct a link to a page that streams the csv data back as an attachment. The server output should contain a content-disposition header of attachment; filename="fileName.csv".

No, you can't create and/or save a file directly from JavaScript. On some browsers/platforms (IE/Windows), you could create and write to a file via ActiveX object:
function WriteToFile()
{
var fso = new ActiveXObject("Scripting.FileSystemObject");
var s = fso.CreateTextFile("C:\\temp\\Test.txt", true);
s.WriteLine('Hello');
s.Close();
}
Another solution is to use client-side JavaScript (inside a browser) to output CSV data into a separate window (or pop-up) and have a user to copy/paste it into Excel.

If you want to do it in a browser website style it might be hard. But Javascript is a good language to do this, but you will need to use .hta instead of a normal .html. Creating an .hta creates a stand alone application just like a normal .exe.
Here is what you want to look for ActiveXObject("Excel.Application")
In order to transform a html into an hta, here is the tag
<HTA:APPLICATION
id="SomeId"
border="thin"
borderStyle="normal"
caption="yes"
maximizeButton="yes"
minimizeButton="yes"
showInTaskbar="yes"
windowState="yes"
innerBorder="yes"
navigable="yes"
scroll="auto"
scrollFlat="yes"
singleinstance="yes"
/>
For futher reading on hta and the excel active X

You could certainly write a browser plugin (ActiveX control on IE, NPAPI on others) with FireBreath that would do this; you'd have to write it in C++. Honestly, I agree with others in suggesting that you do this server-side instead, but you can do it with a plugin and it wouldn't be too difficult.

I think that it would be possible to do this (up to a certain size limit) with data URIs

Related

How to serve blob and have good filename for all users?

I have a PDF file as a blob object. I want to serve to my users, and right now I'm doing:
html = '<iframe src="' + URL.createURL(blob) + '">';
That works fine for people that want to use their in-browser PDF tool.
But...some people have their browser set to automatically download PDFs. For those people, the name of the downloaded file is some random string based on the blob URL. That's a bad experience for them.
I know I can also do:
<a href="blobURL" download="some-filename.pdf">
But that's a bad experience for the people who want to use in-browser PDF readers, since it forces them to download the file.
Is there a way to make everybody have good file names and to allow everybody to read the PDF the way they want to (in their browser or in their OS's reader)?
Thanks
At least looking at Google Chrome, if the user disables the PDF Viewer (using the option "Download PDF files instead of automatically opening them in Chrome") then window.navigator.plugins will show neither "Chromium PDF Plugin" nor "Chromium PDF Viewer". If the option is left at the default setting, the viewer will show in the plugin list.
Using this method, one can utilize window.navigator.plugins to check if any of the elements' names are either of the aforementioned plugins. Then, depending upon that result, either display a <iframe> or a <a href="blobUrl" download="file.pdf">. For other browsers I imagine that different methods would have to be used. You can also check for a "Acrobat Reader" plugin, which some machines may have instead, or even just the word "PDF".
On a side note, it does look like it is possible to detect if the default Firefox PDF viewer is enabled by using http://www.pinlady.net/PluginDetect/PDFjs/ .
Try to append &filename=thename.pdf to the binary, metadata or http header:
Content-Disposition: attachment; filename="thename.pdf"
I have looked through the documentation of createObjectURL(blob), it will always return a unique and specific format of url. It is not possible to change the URL here.
The plugin thing is not consistent across browsers.
Now here is my radical idea
Find or create(if not available) a js library that can create and save PDF files to server from blob. (I looked through some of them like 'jsPDF','pdfkit' but none of them use blob)
Save the file to server with a valid name
use the above name in the iframe.

Download a <div> to .doc or .docx using JS

Say I have dynamic content of a div :
//a button to click, or something
<button type="button">Download Content as a .doc</button>
//Div to be downloads as .div
<div class="gc"> //Generated content
<h1>A Header</h1>
<p>A Paragraph</p>
<ul><li>A</li><li>List</li><li>Here</li></ul>
</div>
What ways can you suggest approaching this without using server side help? I am open to JS, as I am currently learning this, and can access the div with Jquery, just looking either for a simple answer or a hint down the right direction to learn.
Hopefully it is as easy as the oppposite as showing a pdf in a div, like the this, but I don't know.
For my particular situation, the content can formatted or not, placed as an object within word or some other quirky workaround, or maybe using a common browser extension. Ultimately, I just want to be able to offer the user a .doc (potentially .docx) version of the content.
If I MUST use server side functionality, have any good links to help me meander through a solution? as I do not know AJAX or PHP, but am willing to learn!
This is not possible without some sort of serverside thing that will send the correct headers.
You can rename a .html file to .doc, and word will eat it, but you will still need some PHP, or whatever serverside language is your drug of choice to send a content-disposition download tag and a content-type application/vnd-ms-word header.
This is impossible with pure javascript, due to obvious security risks.
Part of this is possible with HTML5 using blob builders and object URLs. The hard part is generating a word-compatible file, left as an exercise to the reader:
// normalize vendor extensions
window.BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder;
window.URL = window.URL || window.webkitURL;
// create the file and append contents to it
var blobthebuilder = new BlobBuilder();
blobthebuilder.append("some text");
// create a URL for the newly created file with a mime
// type and make the anchor point to it
anchor.href = window.URL.createObjectURL(blobthebuilder.getBlob("text/html"));​
Webkit also supports a[download] which will automatically download the file instead of requiring left-click → Save As...
Demo on jsFiddle.
I dont think you can do this without some serverside scripting via AJAX.
If you use php it would be simple to send via AJAX and send back as a text file to download. Then you just need to find a script that can convert it to .doc file as this is a complex format.
However i'm not sure with HTML5 though.. Has a lot of new features.
Edit: ok i can see SchizoDuckie beat me to by 1 min lol :o)

save as PDF: recommend a server solution to receive raw data from client and send back PDF to client?

My project requires me to add a "SaveAs PDF" feature. I was looking for a pure JavaScript solution which does this just in client end, however, was told that it's not implementable, at least for now.
jsPDF currently is still a limited version, not support graph and others. So now I am looking for a stable open-srouce free solution to set up a server web service, that receive data from client-end and send back the produced PDF file or a link for user to save to their disk.
The data from client is determined by client user, which means, not the whole page. User can choose to save a map, a table, or all of them into PDF file.
Any recommendations?
PS: in Windows environment
You might check out the ReportLab Toolkit - it includes an Open Source Python library for creating PDFs. (You didn't specify what server-side language you wanted, but Python is pretty widely supported.)
If you need something that can be coded in Javascript, one option might be PhantomJS. This tool allows you to run a headless Webkit browser from the command line, and among other things it can render and save webpages as PDFs. Slippy uses this approach, so you might be able to get example code from that project. Scripting the PDF creation would probably be much faster in PhantomJS than in Python, but it's likely to be much slower (it has to fire up a Webkit instance) and server installation might be complicated.
I've create this function in javascript which send on iframe to the server:
function download(url, datas){
if(url && datas){
var inputs = '', value,
iframe = '<iframe name="iframeDownload" id="iframeDownload" width=0 height=0></iframe>';
$(iframe).appendTo('body');
datas.forEach(function(data){
name = encodeURI(data.get('name'));
value = encodeURI(data.get('value'));
inputs+='<input name="'+name+'" value="'+value+'"/>';
});
$('<form action="'+url+'" method="post" target="iframeDownload">'+inputs+'</form>').appendTo('body').submit().remove(); // .appendTo and remove() are needed for firefox
$(iframe).remove();
};
};
I'm encoding the input name and value to be able to send data.
On my server, I'm using php, so to decode this, you need: rawurldecode. If you define the name of the inputs as "fileName" and "file" you can write this:
$fileName = rawurldecode($_POST['fileName']);
$file = rawurldecode($_POST['file']);
After than, to force the download, you need to send the corrects header. I'm using this function:
function download($filename, $file) {
header('Content-disposition: attachment; filename="'.$filename.'"');
header('Content-Type: application/force-download');
header('Content-Length: '. filesize($file));
readfile($file);
}
If you don't need to send the file from javascript because it's created on the server side, just add the path of your file to the download function.
If you're using PHP, You can use fpdf to generate the pdf.

Save html page of using javascript

How I can save rendered html page using javascript.
You can't. Javascript in the browser has no file IO capabilites.
If it had, going to any website could write anything to your hard drive.
var everything = document.all
will give you everything, but then you still need to move off the browser into a localfile. You will need a serverside language for that.
At least I do know of a Windows/IE-specific way to save the current HTML file:
http://p2p.wrox.com/javascript-how/3193-how-do-you-save-html-page-your-local-hd.html#post78192
However, I wonder if other browsers (i.e. Chrome) have some similar file I/O API. Obviously, according to previous answers, there's no universal standard.
On what purpose? If you just want to print the page, use document.print instead.
you can get all of the page contents and then you can
send an ajax request to a script that handles the html content (be aware of cross domain restrictions)
save the contents into a cookie
save the contents into localStorage or some local db
There is no reliable way to do this in js. :(

Saving file from JavaScript string without hitting server

If I have an in-memory string in JavaScript that is let's say Excel or PDF format, and I want to pop open a save dialog so the user can save those bytes to a file, how would I go about doing this? I am trying to avoid going back to the server. If I was going back to the server I could send the correct HTTP headers in the response to tell the browser that I'm sending a file. But I want to do this from JavaScript instead because I already have the bytes I need on the client.
Is this possible?
Edit:
I should clarify what I'm actually looking for here. I am working with a Silverlight app. From Silverlight, I can pop up a save dialog and save the bytes (in this case, let's say they are Excel bytes). This seems to be what people are suggesting below when they suggest using Flash. Silverlight gives the same functionality.
But, I would prefer the the Excel file just opens in a new browser window. I could do that pretty easily if I was generating the file on the server, because I could just send the correct headers. But I already have the bytes in Silverlight on the client. Any way to open that doc in a new browser window so the user can just hit an Open button without having to pick a save location and navigate to the file?
And I can't use the out-of-browser application option. I know it would be possible using that by talking with Excel through COM-interop. But that's a no go in this case.
But I can interop with JavaScript from Silverlight. So I was hoping I could use JavaScript in some way to open a browser window and stream the Excel bytes to it.
You can use data URIs to embed the file in the HTML document; e.g., http://jsfiddle.net/dqWae/ creates a link that initiates a download of the Wikipedia title image. (The MIME type is hard coded as application/octet-stream but you can of course specify it as PDF or XLS).
You will need to encode the bytes of the file as base 64 and create a data URI for the resource. Then, create a new anchor element whose href attribute is the data URI. If you want to automatically initiate the download, programmatically issue a click event to the anchor element.
In JavaScript? I hope not, think of all the millions of security implications that would cause..
In pure javascript this will be possible only with html5 but not for now.
but you can do some javascript/flash 10 bridge, you pass the bytes to Flash who open the "save as" dialog and then you can save 100% client side.
The flash can be loaded dynamically.
see some code here : http://sujitreddyg.wordpress.com/2008/11/04/filereference-in-flash-player-10/
There are one non cross-browser solution (works only in Firefox, and only when user grant permissions).
// ask for security grants
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var pngBinary = 'some string';
var aFile = Components.classes["#mozilla.org/file/local;1"].
createInstance(Components.interfaces.nsILocalFile);
aFile.initWithPath( "/tmp/somefile.png" );
aFile.createUnique( Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 600);
var stream = Components.classes["#mozilla.org/network/safe-file-output-stream;1"].
createInstance(Components.interfaces.nsIFileOutputStream);
stream.init(aFile, 0x04 | 0x08 | 0x20, 0600, 0);
stream.write(pngBinary, pngBinary.length);
if (stream instanceof Components.interfaces.nsISafeOutputStream) {
stream.finish();
} else {
stream.close();
}
But I recommend you to make cross-browser applications and choose Flash solution.

Categories

Resources