12

I have constructed a file from base64 and I want to save it to the local system

dataURLtoFile(dataurl, filename, format) {
    const arr = dataurl.split(',');
    const mime = arr[0].match(/:(.*?);/)[1];
    const bstr = atob(arr[1]);
    let n = bstr.length;
    const u8arr = new Uint8Array(n);
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new File([u8arr], filename, {type: format});
  }

Using this function I can convert my base64 to File. But I want to download this to my local system. How can I do this in angular 2 and above?

3 Answers 3

6

Specifying download location dialog is completely browser dependent. Through Javascript, you cannot specify a user's Desktop location to download files. Javascript accessing your directory locations will cause serious security risks. At max, you can change your browser settings to ask for the download location every time.

To implement a normal download at default download location, you can use filesaver

Just import it in your code as:

import { saveAs } from 'file-saver'

and use saveAs in your downloadUrlToFile method.

dataURLtoFile(dataurl, filename, format) {
    const arr = dataurl.split(',');
    const mime = arr[0].match(/:(.*?);/)[1];
    const bstr = atob(arr[1]);
    let n = bstr.length;
    const u8arr = new Uint8Array(n);
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
    }
    saveAs(new File([u8arr], filename, {type: format}));
}

See an example here: https://stackblitz.com/edit/angular-xrubur?file=src%2Fapp%2Fapp.component.ts

Sign up to request clarification or add additional context in comments.

2 Comments

please update the example link, it is not working..
please update the link. seems broken
5

There is no need for an external library for triggering the "Save as..." window (such as file-saver, which is different from the node filesaver mentioned in another answer in here, meant for another purpose).

The simplest way I found was to create an <a> element in one of the component's methods:

saveAFile(): void {
  const dlink: HTMLAnchorElement = document.createElement('a');
  dlink.download = 'myfile.txt'; // the file name
  const myFileContent: string = 'I am a text file! 😂';
  dlink.href = 'data:text/plain;charset=utf-16,' + myFileContent;
  dlink.click(); // this will trigger the dialog window
  dlink.remove();
}

Which can be invoked with a click event in the template, for example:

<button (click)="saveAFile()">Save file</button>

I also initially transformed the file's contents into a Blob but I soon noticed that even with the right charset, complex characters may be lost in translation (e.g. 😂).

You might also find useful the complete list of media/MIME types for creating non-plain text files (e.g. text/csv or application/json).

Comments

2

you can try function below. IT works on both IE10+ and other evergreen compatible browsers

 createImageFromBlob(image: Blob) {
    if (window.navigator.msSaveOrOpenBlob) // IE10+
      window.navigator.msSaveOrOpenBlob(image, "myFile.jpg");
    else {
      var url = window.URL.createObjectURL(image);
      window.open(url);
    }
  }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.