J'ai du texte dans une zone de texte cachée. Lorsqu'un bouton est cliqué, je souhaite que le texte soit proposé au téléchargement sous forme de .txt
fichier. Est-ce possible en utilisant AngularJS ou Javascript?
J'ai du texte dans une zone de texte cachée. Lorsqu'un bouton est cliqué, je souhaite que le texte soit proposé au téléchargement sous forme de .txt
fichier. Est-ce possible en utilisant AngularJS ou Javascript?
Réponses:
Vous pouvez faire quelque chose comme ça en utilisant Blob
.
<a download="content.txt" ng-href="{{ url }}">download</a>
dans votre contrôleur:
var content = 'file content for example';
var blob = new Blob([ content ], { type : 'text/plain' });
$scope.url = (window.URL || window.webkitURL).createObjectURL( blob );
afin d'activer l'URL:
app = angular.module(...);
app.config(['$compileProvider',
function ($compileProvider) {
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|file|blob):/);
}]);
Veuillez noter que
Chaque fois que vous appelez createObjectURL (), une nouvelle URL d'objet est créée, même si vous en avez déjà créé une pour le même objet. Chacun de ces éléments doit être libéré en appelant URL.revokeObjectURL () lorsque vous n'en avez plus besoin. Les navigateurs les publieront automatiquement lorsque le document sera déchargé; cependant, pour des performances et une utilisation de la mémoire optimales, s'il existe des moments sûrs où vous pouvez les décharger explicitement, vous devez le faire.
Source: MDN
$scope.url
n'a pas fonctionné pour moi. J'ai dû utiliser à la window.location
place.
download
attribut n'est pris en charge dans aucune version d'IE ou de Safari bien que caniuse.com/#feat=download
Cliquez simplement sur le bouton pour télécharger en utilisant le code suivant.
en html
<a class="btn" ng-click="saveJSON()" ng-href="{{ url }}">Export to JSON</a>
Dans le contrôleur
$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(...)
assurez-vous de définir responseType:'arraybuffer'
comme expliqué ici: stackoverflow.com/questions/21628378/…
Essaye ça
<a target="_self" href="mysite.com/uploads/ahlem.pdf" download="foo.pdf">
et visitez ce site, cela pourrait vous être utile :)
download
attribut qui n'est toujours pris en charge par aucune version d'IE ni de Safari. Découvrez-le ici: caniuse.com/#feat=download
Cela peut être fait en javascript sans avoir besoin d'ouvrir une autre fenêtre de navigateur.
window.location.assign('url');
Remplacez «url» par le lien vers votre fichier. Vous pouvez mettre cela dans une fonction et l'appeler avec ng-click
si vous devez déclencher le téléchargement à partir d'un bouton.
Dans notre projet actuel au travail, nous avions un iFrame invisible et je devais fournir l'URL du fichier à l'iFrame pour obtenir une boîte de dialogue de téléchargement. En cliquant sur le bouton, le contrôleur génère l'URL dynamique et déclenche un événement $ scope où une personnalisation que directive
j'ai écrite est listée. La directive ajoutera un iFrame au corps s'il n'existe pas déjà et y définit l'attribut url.
EDIT: Ajout d'une directive
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;
});
Cette directive répond à un événement du contrôleur appelé downloadFile
donc dans votre contrôleur vous faites
$scope.$broadcast("downloadFile", url);
Vous pouvez définir location.href
un URI de données contenant les données que vous souhaitez permettre à l'utilisateur de télécharger. En plus de cela, je ne pense pas qu'il y ait moyen de le faire avec juste JavaScript.
$location.href
changé en$window.location.href
Je voudrais juste ajouter qu'au cas où il ne téléchargerait pas le fichier à cause de unsafe: blob: null ... lorsque vous survolez le bouton de téléchargement, vous devez le nettoyer. Par exemple,
var app = angular.module ('app', []);
app.config (fonction ($ compileProvider) {
$compileProvider.aHrefSanitizationWhitelist(/^\s*(|blob|):/);
Si vous avez accès à sur le serveur, envisagez de définir des en-têtes comme répondu à cette question plus générale .
Content-Type: application/octet-stream
Content-Disposition: attachment;filename=\"filename.xxx\"
En lisant les commentaires sur cette réponse, il est conseillé d'utiliser un Content-Type plus spécifique que l'octet-stream.
J'ai eu le même problème et j'ai passé de nombreuses heures à trouver des solutions différentes, et maintenant je rejoins tous les commentaires de cet article, j'espère que cela vous sera utile, ma réponse a été correctement testée sur Internet Explorer 11, Chrome et FireFox.
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>
DIRECTIVE:
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');
}
}
});
}
}
})
DANS LE CONTRÔLEUR:
$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=[];
});
};
EN SERVICE:
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 (au PRINTEMPS):
@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;
}
Cela a fonctionné pour moi en angulaire:
var a = document.createElement("a");
a.href = 'fileURL';
a.download = 'fileName';
a.click();
data:text/plain;base64,${btoa(theStringGoesHere)}
Je ne voulais pas d'URL statique. J'ai AjaxFactory pour faire toutes les opérations ajax. J'obtiens l'URL de l'usine et je la lie comme suit.
<a target="_self" href="{{ file.downloadUrl + '/' + order.OrderId + '/' + fileName }}" download="{{fileName}}">{{fileName}}</a>
Merci @AhlemMustapha