Decisions regarding the discussion of Xan are a bit outdated. Some time ago I did the same in my extension. It was part of the GWT, so now I quickly wrote the JS version (see code below).
The stream is as follows:
- generate file contents as a callback for user action (_getFileContents)
- use the Blob constructor to create the file (_createDownloadData)
- get a link to a file using window.URL.createObjectURL (_createDownloadData)
- set binding attributes that will be used to load the file (prepareFileExport)
This approach requires two steps from the user:
- Click the Prepare Data button
- After creating the file, click the link to download the actual file.
But you can easily implement file function loading in your extension.
JavaScript:
var FileDownload = { //Existing file URL. exportFileObjectUrl: null, // add click listener to the "prepare" button initialize: function(){ FileDownload.prepareButton.addEventListener('click', FileDownload.prepareFileExport); }, // prepare the file and "add" it the download button. prepareFileExport: function(e){ var content = FileDownload._getFileContents(); var contentType = 'application/json'; FileDownload.exportFileObjectUrl = FileDownload._createDownloadData(content, contentType); var fileName = "some_file.json"; FileDownload.downloadButton.href = FileDownload.exportFileObjectUrl; FileDownload.downloadButton.setAttribute("download", fileName); FileDownload.downloadButton.setAttribute("data-downloadurl", contentType + ":" + fileName + ":" + FileDownload.exportFileObjectUrl); FileDownload.downloadButton.removeAttribute("hidden"); }, // File content generator _getFileContents: function(){ //generate some content as a string. var mock = { 'a': 'test data' }; return JSON.stringify(mock); }, //Result with URL to the file. _createDownloadData: function(data, contentType){ if(FileDownload.exportFileObjectUrl !== null){ FileDownload._revokeDownloadData(); } var blob = new window.Blob([data], {type: contentType}); return window.URL.createObjectURL(blob); }, /// Cleanup. _revokeDownloadData: function(){ window.URL.revokeObjectURL(FileDownload.exportFileObjectUrl); }, // a reference to the "prepare" button get prepareButton(){ /// prepare button. return document.querySelector('[prepare]'); }, // a reference to the "download" button. get downloadButton(){ /// Download button. return document.querySelector('[download]'); } }; FileDownload.initialize();
HTML:
<button prepare>Prepare data</button> <a href="about:blank" download hidden>Download data</a>
Paweł Psztyć
source share