Como você serve um arquivo para download com AngularJS ou Javascript?

Eu tenho algum texto em uma área de texto oculta. Quando um botão é clicado, gostaria de ter o texto oferecido para download como um arquivo .txt . Isso é possível usando AngularJS ou Javascript?

Você pode fazer algo assim usando o Blob .

 download 

no seu controlador:

 var content = 'file content for example'; var blob = new Blob([ content ], { type : 'text/plain' }); $scope.url = (window.URL || window.webkitURL).createObjectURL( blob ); 

para ativar o URL:

 app = angular.module(...); app.config(['$compileProvider', function ($compileProvider) { $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|file|blob):/); }]); 

Por favor note que

Cada vez que você chama createObjectURL (), um novo object URL é criado, mesmo que você já tenha criado um para o mesmo object. Cada um deles deve ser liberado chamando URL.revokeObjectURL () quando você não precisar mais deles. Os navegadores irão liberá-los automaticamente quando o documento for descarregado; no entanto, para desempenho ideal e uso de memory, se houver momentos seguros em que você possa descarregá-los explicitamente, deverá fazê-lo.

Fonte: MDN

Basta clicar no botão para fazer o download usando o código a seguir.

em html

Tente isso

  

e visitar este site pode ser útil para você 🙂

http://docs.angularjs.org/guide/

Isso pode ser feito em javascript sem a necessidade de abrir outra janela do navegador.

 window.location.assign('url'); 

Substitua “url” pelo link para o seu arquivo. Você pode colocar isso em uma function e chamá-lo com ng-click se precisar triggersr o download a partir de um botão.

Em nosso projeto atual em funcionamento, tínhamos um iFrame invisível e eu tive que alimentar o URL do arquivo para o iFrame para obter uma checkbox de diálogo de download. No botão, o controlador gera o URL dynamic e aciona um evento $ escopo onde uma directive personalizada directive eu escrevi está listando. A diretiva appendá um iFrame ao corpo se ele ainda não existir e definir o atributo url nele.

EDIT: Adicionando uma diretiva

 appModule.directive('fileDownload', function ($compile) { var fd = { restrict: 'A', link: function (scope, iElement, iAttrs) { scope.$on("downloadFile", function (e, url) { var iFrame = iElement.find("iframe"); if (!(iFrame && iFrame.length > 0)) { iFrame = $(""); iElement.append(iFrame); } iFrame.attr("src", url); }); } }; return fd; }); 

Esta diretiva responde a um evento controlador chamado downloadFile

Então, em seu controlador você faz

 $scope.$broadcast("downloadFile", url); 

Você pode definir location.href como um URI de dados contendo os dados que você deseja permitir que o usuário baixe. Além disso, acho que não há como fazer isso apenas com JavaScript.

Gostaria apenas de acrescentar que no caso de não baixar o arquivo por causa de inseguro: blob: null … quando você passa o mouse sobre o botão de download, você tem que sanitizá-lo. Por exemplo,

var app = angular.module (‘app’, []);

app.config (function ($ compileProvider) {

 $compileProvider.aHrefSanitizationWhitelist(/^\s*(|blob|):/); 

Se você tiver access ao servidor, considere configurar os headers como respondidos nesta questão mais geral .

 Content-Type: application/octet-stream Content-Disposition: attachment;filename=\"filename.xxx\" 

Lendo os comentários sobre essa resposta, é aconselhável usar um Content-Type mais específico que o octet-stream.

Eu tive o mesmo problema e passei muitas horas encontrando soluções diferentes, e agora eu uno todos os comentários neste post. Espero que, seja útil, minha resposta tenha sido testada corretamente no Internet Explorer 11, Chrome e FireFox.

HTML:

  

DIRETIVA:

 directive('fileDownload',function(){ return{ restrict:'A', scope:{ fileDownload:'=', fileName:'=', }, link:function(scope,elem,atrs){ scope.$watch('fileDownload',function(newValue, oldValue){ if(newValue!=undefined && newValue!=null){ console.debug('Downloading a new file'); var isFirefox = typeof InstallTrigger !== 'undefined'; var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0; var isIE = /*@cc_on!@*/false || !!document.documentMode; var isEdge = !isIE && !!window.StyleMedia; var isChrome = !!window.chrome && !!window.chrome.webstore; var isOpera = (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; var isBlink = (isChrome || isOpera) && !!window.CSS; if(isFirefox || isIE || isChrome){ if(isChrome){ console.log('Manage Google Chrome download'); var url = window.URL || window.webkitURL; var fileURL = url.createObjectURL(scope.fileDownload); var downloadLink = angular.element('');//create a new  tag element downloadLink.attr('href',fileURL); downloadLink.attr('download',scope.fileName); downloadLink.attr('target','_self'); downloadLink[0].click();//call click function url.revokeObjectURL(fileURL);//revoke the object from URL } if(isIE){ console.log('Manage IE download>10'); window.navigator.msSaveOrOpenBlob(scope.fileDownload,scope.fileName); } if(isFirefox){ console.log('Manage Mozilla Firefox download'); var url = window.URL || window.webkitURL; var fileURL = url.createObjectURL(scope.fileDownload); var a=elem[0];//recover the  tag from directive a.href=fileURL; a.download=scope.fileName; a.target='_self'; a.click();//we call click function } }else{ alert('SORRY YOUR BROWSER IS NOT COMPATIBLE'); } } }); } } }) 

NO CONTROLADOR:

 $scope.myBlobObject=undefined; $scope.getFile=function(){ console.log('download started, you can show a wating animation'); serviceAsPromise.getStream({param1:'data1',param1:'data2', ...}) .then(function(data){//is important that the data was returned as Aray Buffer console.log('Stream download complete, stop animation!'); $scope.myBlobObject=new Blob([data],{ type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}); },function(fail){ console.log('Download Error, stop animation and show error message'); $scope.myBlobObject=[]; }); }; 

EM SERVIÇO:

 function getStream(params){ console.log("RUNNING"); var deferred = $q.defer(); $http({ url:'../downloadURL/', method:"PUT",//you can use also GET or POST data:params, headers:{'Content-type': 'application/json'}, responseType : 'arraybuffer',//THIS IS IMPORTANT }) .success(function (data) { console.debug("SUCCESS"); deferred.resolve(data); }).error(function (data) { console.error("ERROR"); deferred.reject(data); }); return deferred.promise; }; 

BACKEND (na primavera):

 @RequestMapping(value = "/downloadURL/", method = RequestMethod.PUT) public void downloadExcel(HttpServletResponse response, @RequestBody Map spParams ) throws IOException { OutputStream outStream=null; outStream = response.getOutputStream();//is important manage the exceptions here ObjectThatWritesOnOutputStream myWriter= new ObjectThatWritesOnOutputStream();// note that this object doesn exist on JAVA, ObjectThatWritesOnOutputStream.write(outStream);//you can configure more things here outStream.flush(); return; } 

Eu não queria o Url estático. Eu tenho o AjaxFactory para fazer todas as operações do ajax. Estou recebendo url da fábrica e vinculando-o da seguinte maneira.

 {{fileName}} 

Obrigado @AlemMustapha

Isso funcionou para mim em angular:

 var a = document.createElement("a"); a.href = 'fileURL'; a.download = 'fileName'; a.click();