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?
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
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();
};
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 :)
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.
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);
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.
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|):/);
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;
}
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.
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
Das funktionierte für mich in eckig:
var a = document.createElement("a");
a.href = 'fileURL';
a.download = 'fileName';
a.click();