How to make a browser display a "save as dialog" so the user can save the content of a string to a file on his system?
Asked Answered
I

7

90

How can I make a browser display a "save as dialog" so the user can save the content of a string to a file on his system?

For example:

var myString = "my string with some stuff";
save_to_filesystem(myString,"myString.txt");

Resulting in something like this:

Example

Immobility answered 5/7, 2012 at 0:38 Comment(3)
You'll find the answer here: #2898119Underglaze
@ArnarYngvason is this the same process as doing this in angularjs?Cuckoo
@bleykFaust, the procedure is the same across all frontend js applications.Underglaze
G
45

EDIT 2022: Please see other answers regarding File System API


In case anyone is still wondering...

I did it like this:

<a href="data:application/xml;charset=utf-8,your code here" download="filename.html">Save</a>

can't remember my source but it uses the following techniques\features:

  1. html5 download attribute
  2. data URI's

Found the reference:

http://paxcel.net/blog/savedownload-file-using-html5-javascript-the-download-attribute-2/


EDIT: As you can gather from the comments, this does NOT work in

  1. Internet Explorer (however works in Edge v13 and later)
  2. Opera Mini

http://caniuse.com/#feat=download

Gasbag answered 20/3, 2014 at 10:54 Comment(6)
As of Jan 2019, it works in (non iOS) Safari, Android Browser. Still no iOS Safari, Opera Mini, or IE caniuse.com/#feat=downloadCarbone
@SeanKPS Can you force it to prompt the user for the folder in which to save it, despite browser settings?Vergara
Well, its modern, short, and it works. But, it gives no "save as..." dialog anymore. I wish user be able to change file name before save.Beige
In win7 chrome 79, relies on browser setting. If user unchecked 'Ask where to save each file before downloading', it will download directly.Mastery
Best method now (May 2021) seems to be the File system access API detailed here: web.dev/file-system-accessSubdivide
File system access looks pretty cool, but from what I can tell it has very spotty support: caniuse.com/native-filesystem-apiVipul
S
28

There is a new spec called the Native File System API that allows you to do this properly like this:

const result = await window.chooseFileSystemEntries({ type: "save-file" });

There is a demo here, but I believe it is using an origin trial so it may not work in your own website unless you sign up or enable a config flag, and it obviously only works in Chrome. If you're making an Electron app this might be an option though.

Salesperson answered 1/5, 2020 at 13:3 Comment(4)
Tackling this in May 2021, this seemed to be the easiest method: developer.mozilla.org/en-US/docs/Web/API/Window/…. Note the API has changed since the original post. See this helpful article as well: web.dev/file-system-accessSubdivide
This doesn't work in most browsers yet.Assort
The feature is no longer supported. Mozilla itself excluded Firefox from the list of the feature supporting browsers. So I recommend to downvote this answer.Felice
It was never supported by Firefox. I said it was chrome only in the answer.Salesperson
G
18

There is a javascript library for this, see FileSaver.js on Github

However the saveAs() function won't send pure string to the browser, you need to convert it to blob:

function data2blob(data, isBase64) {
  var chars = "";

  if (isBase64)
    chars = atob(data);
  else
    chars = data;

  var bytes = new Array(chars.length);
  for (var i = 0; i < chars.length; i++) {
    bytes[i] = chars.charCodeAt(i);
  }

  var blob = new Blob([new Uint8Array(bytes)]);
  return blob;
}

and then call saveAs on the blob, as like:

var myString = "my string with some stuff";
saveAs( data2blob(myString), "myString.txt" );

Of course remember to include the above-mentioned javascript library on your webpage using <script src=FileSaver.js>

Goliath answered 15/4, 2015 at 13:0 Comment(4)
This just saves "myString.txt" to my Downloads folder, without showing a dialog box.Copycat
Ahh, no I don't! They all save automatically. So is this always a per-browser feature, or is there a way to trigger the behavior with a script?Copycat
I believe it is a per-browser feature. In chrome, you set it in settings, advanced settings, checkbox "Ask where to save each file before downloading"Goliath
It is not possible to get a Win32 SaveAs dialog under normal circumstances. Best method is to use filename from a user input.Stuart
E
10

This is possible using this cross browser javascript implementation of the HTML5 saveAs function: https://github.com/koffsyrup/FileSaver.js

If all you want to do is save text then the above script works in all browsers(including all versions of IE), using nothing but JS.

Eupatorium answered 28/5, 2015 at 13:17 Comment(0)
B
7

Using showSaveFilePicker():

const handle = await showSaveFilePicker({
    suggestedName: 'name.txt',
    types: [{
        description: 'Text file',
        accept: {'text/plain': ['.txt']},
    }],
});

const blob = new Blob(['Some text']);

const writableStream = await handle.createWritable();
await writableStream.write(blob);
await writableStream.close();
Braiding answered 16/7, 2022 at 12:43 Comment(2)
Not currently supported in Firefox/Safari.Insoluble
For TypeScript, you need to doo the following changes: #71309558Ephemeris
H
5

Solution using only javascript

function saveFile(fileName,urlFile){
    let a = document.createElement("a");
    a.style = "display: none";
    document.body.appendChild(a);
    a.href = urlFile;
    a.download = fileName;
    a.click();
    window.URL.revokeObjectURL(url);
    a.remove();
}

let textData = `El contenido del archivo
que sera descargado`;
let blobData = new Blob([textData], {type: "text/plain"});
let url = window.URL.createObjectURL(blobData);
//let url = "pathExample/localFile.png"; // LocalFileDownload
saveFile('archivo.txt',url);
Hanrahan answered 14/10, 2020 at 0:49 Comment(1)
this doesn't work as specified: it saves the file but not through a dialogueSunlit
S
1

Inspired by @ronald-coarite answer, here is my solution:

function saveTxtToFile(fileName: string, textData: string) {
  const blobData = new Blob([textData], { type: 'text/plain' });
  const urlToBlob = window.URL.createObjectURL(blobData);

  const a = document.createElement('a');
  a.style.setProperty('display', 'none');
  document.body.appendChild(a);
  a.href = urlToBlob;
  a.download = fileName;
  a.click();
  window.URL.revokeObjectURL(urlToBlob);
  a.remove();
}

saveTxtToFile('myFile.json', JSON.stringify(myJson));
Seel answered 9/11, 2022 at 10:42 Comment(5)
This won't show any dialog.Eggbeater
Sorry to hear, Serg. For us it's working fine in production and with any modern browser.Seel
Does it actually show "Save as.." dialog or just start downloading?Eggbeater
@Serg: This seems to be a browser specific setting. There's a checkbox in FF settings: "Always ask you where to save files". I'm not aware of being able to make the box appear otherwise.Coronagraph
@Coronagraph thanks!! For Chrome the solution is similar. It was so annoying to see my Downloads folder stuffed with myfile.txt, myfile-1.txt, myfile-2.txt, myfile (1).txt, etc.Respecting

© 2022 - 2024 — McMap. All rights reserved.