HTML:
<a href="mysite.com/uploads/asd4a4d5a.pdf" download="foo.pdf">
Uploads erhalten einen eindeutigen Dateinamen, während der tatsächliche Name in der Datenbank gespeichert wird. Ich möchte einen einfachen Dateidownload realisieren. Der obige Code leitet jedoch zu / wegen:
$routeProvider.otherwise({
redirectTo: '/',
controller: MainController
});
Ich habe es mit versucht
$scope.download = function(resource){
window.open(resource);
}
Dies öffnet jedoch nur die Datei in einem neuen Fenster.
Irgendwelche Ideen, wie man einen echten Download für jeden Dateityp ermöglicht?
target="_blank"
odertarget="_self"
? Siehe: docs.angularjs.org/guide/…Antworten:
https://docs.angularjs.org/guide/$location#html-link-rewriting
In Ihrem Fall sollten Sie also ein Zielattribut wie folgt hinzufügen ...
<a target="_self" href="example.com/uploads/asd4a4d5a.pdf" download="foo.pdf">
quelle
download
wird von IE oder Safari nicht unterstützt.Wir mussten auch eine Lösung entwickeln, die sogar mit APIs funktioniert, die eine Authentifizierung erfordern (siehe diesen Artikel ).
AngularJS auf den Punkt gebracht: So haben wir es gemacht:
Schritt 1: Erstellen Sie eine dedizierte Direktive
// jQuery needed, uses Bootstrap classes, adjust the path of templateUrl app.directive('pdfDownload', function() { return { restrict: 'E', templateUrl: '/path/to/pdfDownload.tpl.html', scope: true, link: function(scope, element, attr) { var anchor = element.children()[0]; // When the download starts, disable the link scope.$on('download-start', function() { $(anchor).attr('disabled', 'disabled'); }); // When the download finishes, attach the data to the link. Enable the link and change its appearance. scope.$on('downloaded', function(event, data) { $(anchor).attr({ href: 'data:application/pdf;base64,' + data, download: attr.filename }) .removeAttr('disabled') .text('Save') .removeClass('btn-primary') .addClass('btn-success'); // Also overwrite the download pdf function to do nothing. scope.downloadPdf = function() { }; }); }, controller: ['$scope', '$attrs', '$http', function($scope, $attrs, $http) { $scope.downloadPdf = function() { $scope.$emit('download-start'); $http.get($attrs.url).then(function(response) { $scope.$emit('downloaded', response.data); }); }; }] });
Schritt 2: Erstellen Sie eine Vorlage
<a href="" class="btn btn-primary" ng-click="downloadPdf()">Download</a>
Schritt 3: Verwenden Sie es
<pdf-download url="/some/path/to/a.pdf" filename="my-awesome-pdf"></pdf-download>
Dadurch wird eine blaue Schaltfläche gerendert. Wenn Sie darauf klicken, wird ein PDF heruntergeladen (Achtung: Das Backend muss das PDF in Base64-Codierung liefern!) Und in die href eingefügt. Die Schaltfläche wird grün und schaltet den Text auf Speichern . Der Benutzer kann erneut klicken und erhält einen Standarddialog für die Download-Datei für die Datei my-awesome.pdf .
In unserem Beispiel werden PDF-Dateien verwendet, aber anscheinend können Sie jedes Binärformat bereitstellen, wenn es ordnungsgemäß codiert ist.
quelle
Wenn Sie eine erweiterte Richtlinie benötigen, empfehle ich die von mir implementierte Lösung, die in Internet Explorer 11, Chrome und FireFox korrekt getestet wurde.
Ich hoffe es wird hilfreich sein.
HTML:
<a href="#" class="btn btn-default" file-name="'fileName.extension'" ng-click="getFile()" file-download="myBlobObject"><i class="fa fa-file-excel-o"></i></a>
RICHTLINIE:
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('<a></a>');//create a new <a> 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 <a> 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'); } } }); } } })
IM CONTROLLER:
$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=[]; }); };
IM DIENST:
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 (am FRÜHLING):
@RequestMapping(value = "/downloadURL/", method = RequestMethod.PUT) public void downloadExcel(HttpServletResponse response, @RequestBody Map<String,String> 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; }
quelle
in Vorlage
<md-button class="md-fab md-mini md-warn md-ink-ripple" ng-click="export()" aria-label="Export"> <md-icon class="material-icons" alt="Export" title="Export" aria-label="Export"> system_update_alt </md-icon></md-button>
in der Steuerung
$scope.export = function(){ $window.location.href = $scope.export; };
quelle