Ich habe Text in einem versteckten Textbereich. Wenn auf eine Schaltfläche geklickt wird, möchte ich den Text als .txt
Datei zum Download anbieten . Ist dies mit AngularJS oder Javascript möglich?
Ich habe Text in einem versteckten Textbereich. Wenn auf eine Schaltfläche geklickt wird, möchte ich den Text als .txt
Datei zum Download anbieten . Ist dies mit AngularJS oder Javascript möglich?
Antworten:
Sie können so etwas mit tun Blob
.
<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
Jedes Mal, wenn Sie createObjectURL () aufrufen, wird eine neue Objekt-URL erstellt, auch wenn Sie bereits eine für dasselbe Objekt erstellt haben. Jedes dieser Elemente muss durch Aufrufen 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 es sichere Zeiten gibt, in denen Sie diese explizit entladen können.
Quelle: MDN
$scope.url
bei mir nicht funktioniert. Ich musste window.location
stattdessen verwenden.
Klicken Sie einfach auf die Schaltfläche, um den folgenden 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();
};
$http.get(...)
stellen Sie sicher, dass Sie die responseType:'arraybuffer'
hier erläuterten Einstellungen vornehmen
Versuche dies
<a target="_self" href="mysite.com/uploads/ahlem.pdf" download="foo.pdf">
und besuchen Sie diese Seite, es könnte für Sie hilfreich sein :)
download
Attribut, das von keiner IE- oder Safari-Version unterstützt wird. Überprüfen Sie es hier: caniuse.com/#feat=download
Dies kann in Javascript erfolgen, 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 aufrufen, ng-click
wenn Sie den Download über eine Schaltfläche auslösen müssen.
In unserem aktuellen Projekt hatten wir einen unsichtbaren iFrame und ich musste die URL für die Datei dem iFrame zuführen, um ein Download-Dialogfeld zu erhalten. Beim Klicken auf die Schaltfläche generiert der Controller die dynamische URL und löst ein $ scope-Ereignis aus, in dem ein von directive
mir geschriebener Benutzer aufgelistet wird. Die Direktive hängt einen iFrame an den Body an, falls dieser noch nicht vorhanden ist, und legt das URL-Attribut darauf fest.
EDIT: Hinzufügen einer Direktive
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 aufgerufenes Controller-Ereignis downloadFile
So tun Sie es in Ihrem Controller
$scope.$broadcast("downloadFile", url);
Sie können location.href
einen Daten-URI festlegen , der die Daten enthält, die der Benutzer herunterladen möchte. Abgesehen davon glaube ich nicht, dass es eine Möglichkeit gibt, dies nur mit JavaScript zu tun.
$location.href
geändert zu$window.location.href
Ich möchte nur hinzufügen, dass die Datei nicht heruntergeladen wird, weil sie unsicher ist: blob: null ... Wenn Sie mit der Maus über den Download-Button fahren, müssen Sie sie bereinigen. Zum Beispiel,
var app = angle.module ('app', []);
app.config (Funktion ($ compileProvider) {
$compileProvider.aHrefSanitizationWhitelist(/^\s*(|blob|):/);
Wenn Sie auf dem Server Zugriff haben, sollten Sie die in dieser allgemeineren Frage beantworteten Header festlegen .
Content-Type: application/octet-stream
Content-Disposition: attachment;filename=\"filename.xxx\"
Wenn Sie die Kommentare zu dieser Antwort lesen, ist es ratsam, einen spezifischeren Inhaltstyp als den Oktett-Stream zu verwenden.
Ich hatte das gleiche Problem und verbrachte viele Stunden damit, verschiedene Lösungen zu finden, und jetzt verbinde ich alle Kommentare in diesem Beitrag. Ich hoffe, es wird hilfreich sein, meine Antwort wurde in Internet Explorer 11, Chrome und FireFox korrekt 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 = /*@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;
}
Das hat bei mir im Winkel funktioniert:
var a = document.createElement("a");
a.href = 'fileURL';
a.download = 'fileName';
a.click();
data:text/plain;base64,${btoa(theStringGoesHere)}
Ich wollte keine statische URL. Ich habe AjaxFactory für alle Ajax-Operationen. Ich erhalte eine URL aus der Fabrik und binde sie wie folgt.
<a target="_self" href="{{ file.downloadUrl + '/' + order.OrderId + '/' + fileName }}" download="{{fileName}}">{{fileName}}</a>
Danke @AhlemMustapha