it-swarm.com.de

Wie liefern Sie eine Datei zum Herunterladen mit AngularJS oder Javascript?

Ich habe etwas Text in einem versteckten Textbereich. Wenn Sie auf eine Schaltfläche klicken, möchte ich, dass der Text als .txt-Datei zum Download angeboten wird. Ist dies mit AngularJS oder Javascript möglich?

93
nickponline

Sie können dies mit Blob tun.

<a download="content.txt" ng-href="{{ url }}">download</a>

in Ihrem Controller:

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

um die URL zu aktivieren:

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

Bitte beachte, dass 

Bei jedem Aufruf von createObjectURL () wird eine neue Objekt-URL erstellt, auch wenn Sie bereits eine für dasselbe Objekt erstellt haben. Jeder von diesen muss durch Aufruf von URL.revokeObjectURL () freigegeben werden, wenn Sie sie nicht mehr benötigen. Browser geben diese automatisch frei, wenn das Dokument entladen wird. Für eine optimale Leistung und Speichernutzung sollten Sie dies jedoch tun, wenn sichere Zeiten vorliegen, in denen Sie sie explizit entladen können.

Quelle: MDN

106
Tosh

Klicken Sie einfach auf die Schaltfläche, um mit folgendem Code herunterzuladen.

in html

<a class="btn" ng-click="saveJSON()" ng-href="{{ url }}">Export to JSON</a>

In der Steuerung

$scope.saveJSON = function () {
                        $scope.toJSON = '';
                        $scope.toJSON = angular.toJson($scope.data);
                        var blob = new Blob([$scope.toJSON], { type:"application/json;charset=utf-8;" });                       
                        var downloadLink = angular.element('<a></a>');
                        downloadLink.attr('href',window.URL.createObjectURL(blob));
                        downloadLink.attr('download', 'fileName.json');
                        downloadLink[0].click();
                };
31
Amrut

Versuche dies 

<a target="_self" href="mysite.com/uploads/ahlem.pdf" download="foo.pdf">

und besuchen Sie diese Seite, es könnte hilfreich für Sie sein :) 

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

26
AhlemMustapha

Dies kann in Javascript gemacht werden, ohne dass ein anderes Browserfenster geöffnet werden muss.

window.location.assign('url');

Ersetzen Sie "URL" durch den Link zu Ihrer Datei. Sie können dies in eine Funktion einfügen und mit ng-click aufrufen, wenn Sie den Download über eine Schaltfläche auslösen möchten.

21
mm8154

In unserem aktuellen Projekt bei der Arbeit hatten wir einen unsichtbaren iFrame und ich musste die URL für die Datei in den iFrame eingeben, um ein Dialogfeld zum Herunterladen zu erhalten. Beim Klicken auf die Schaltfläche generiert der Controller die dynamische URL und löst ein $ scope -Ereignis aus, in dem eine benutzerdefinierte directive-Datei aufgeführt wird, die ich geschrieben habe. Die Direktive fügt einen iFrame an den Body an, falls noch nicht vorhanden, und legt das URL-Attribut fest.

BEARBEITEN: Eine Direktive hinzufügen

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 = $("<iframe style='position:fixed;display:none;top:-1px;left:-1px;'/>");
                    iElement.append(iFrame);
                }

                iFrame.attr("src", url);


            });
        }
    };

    return fd;
});

Diese Anweisung reagiert auf ein Controller-Ereignis mit dem Namen downloadFile

also in deinem Controller

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

Sie können location.href auf eine data URI setzen, die die Daten enthält, die der Benutzer herunterladen soll. Abgesehen davon glaube ich nicht, dass es nur mit JavaScript möglich ist.

12

Ich möchte nur hinzufügen, falls die Datei wegen unsicherer Dateien nicht heruntergeladen wird: blob: null ... Wenn Sie den Mauszeiger über den Download-Button bewegen, müssen Sie die Datei desinfizieren. Zum Beispiel,

var app = angle.module ('app', []);

app.config (Funktion ($ compileProvider) {

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

Ich hatte das gleiche Problem und verbrachte viele Stunden damit, andere Lösungen zu finden, und jetzt schließe ich mich allen Kommentaren in diesem Beitrag an. Ich hoffe, es wird hilfreich sein, meine Antwort wurde korrekt auf Internet Explorer 11, Chrome und FireFox getestet.

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 = /*@[email protected]*/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');
                    }
                }
            });

        }
    }
})

IN 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 (auf 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;
}
4
havelino

Wenn Sie Zugriff auf den Server haben, sollten Sie die Kopfzeilen als beantworten, die in dieser allgemeineren Frage beantwortet werden.

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

Wenn Sie die Kommentare zu dieser Antwort lesen, empfiehlt es sich, einen spezifischeren Content-Type als Octet-Stream zu verwenden.

4
plong0

Ich wollte keine statische URL. Ich habe AjaxFactory für alle Ajax-Operationen. Ich bekomme URL aus der Fabrik und binde sie wie folgt.

<a target="_self" href="{{ file.downloadUrl + '/' + order.OrderId + '/' + fileName }}" download="{{fileName}}">{{fileName}}</a>

Danke @AhlemMustapha

2
om471987

Das funktionierte für mich in eckig:

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