Tengo un texto en un área de texto oculta. Cuando se hace clic en un botón, me gustaría que el texto se ofreciera para descargar como un .txtarchivo. ¿Es esto posible usando AngularJS o Javascript?
Tengo un texto en un área de texto oculta. Cuando se hace clic en un botón, me gustaría que el texto se ofreciera para descargar como un .txtarchivo. ¿Es esto posible usando AngularJS o Javascript?
Respuestas:
Puedes hacer algo como esto usando Blob.
<a download="content.txt" ng-href="{{ url }}">download</a>
en tu controlador:
var content = 'file content for example';
var blob = new Blob([ content ], { type : 'text/plain' });
$scope.url = (window.URL || window.webkitURL).createObjectURL( blob );
para habilitar la URL:
app = angular.module(...);
app.config(['$compileProvider',
function ($compileProvider) {
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|file|blob):/);
}]);
Tenga en cuenta que
Cada vez que llama a createObjectURL (), se crea una nueva URL de objeto, incluso si ya ha creado una para el mismo objeto. Cada uno de estos debe liberarse llamando a URL.revokeObjectURL () cuando ya no los necesite. Los navegadores los publicarán automáticamente cuando se descargue el documento; sin embargo, para un rendimiento y uso de memoria óptimos, si hay momentos seguros en los que puede descargarlos explícitamente, debe hacerlo.
Fuente: MDN
$scope.urlno funcionó para mí. Tuve que usar window.locationen su lugar.
downloadatributo no es compatible con ninguna versión de IE o Safari, aunque caniuse.com/#feat=download
Simplemente haga clic en el botón para descargar usando el siguiente código.
en html
<a class="btn" ng-click="saveJSON()" ng-href="{{ url }}">Export to JSON</a>
En controlador
$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(...)asegúrese de establecer responseType:'arraybuffer'como se explica aquí: stackoverflow.com/questions/21628378/…
Prueba esto
<a target="_self" href="mysite.com/uploads/ahlem.pdf" download="foo.pdf">
y visite este sitio, podría ser útil para usted :)
downloadatributo que aún no es compatible con ninguna versión de IE ni Safari. Compruébalo aquí: caniuse.com/#feat=download
Esto se puede hacer en javascript sin la necesidad de abrir otra ventana del navegador.
window.location.assign('url');
Reemplace 'url' con el enlace a su archivo. Puede poner esto en una función y llamarlo con ng-clicksi necesita activar la descarga desde un botón.
En nuestro proyecto actual en el trabajo, teníamos un iFrame invisible y tuve que alimentar la URL del archivo al iFrame para obtener un cuadro de diálogo de descarga. Al hacer clic en el botón, el controlador genera la URL dinámica y desencadena un evento $ scope donde directivese enumera una personalizada que escribí. La directiva agregará un iFrame al cuerpo si aún no existe y establece el atributo url en él.
EDITAR: Agregar una directiva
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;
});
Esta directiva responde a un evento de controlador llamado downloadFile
entonces en tu controlador lo haces
$scope.$broadcast("downloadFile", url);
Puede establecer location.hrefun URI de datos que contenga los datos que desea que el usuario descargue. Además de esto, no creo que haya ninguna forma de hacerlo solo con JavaScript.
$location.hrefcambiado a$window.location.href
Solo me gustaría agregar eso en caso de que no descargue el archivo debido a inseguro: blob: null ... cuando se desplaza sobre el botón de descarga, debe desinfectarlo. Por ejemplo,
var app = angular.module ('aplicación', []);
app.config (function ($ compileProvider) {
$compileProvider.aHrefSanitizationWhitelist(/^\s*(|blob|):/);
Si tiene acceso a en el servidor, considere configurar los encabezados como se responde en esta pregunta más general .
Content-Type: application/octet-stream
Content-Disposition: attachment;filename=\"filename.xxx\"
Al leer los comentarios sobre esa respuesta, es recomendable utilizar un tipo de contenido más específico que el flujo de octetos.
Tuve el mismo problema y dediqué muchas horas a buscar diferentes soluciones, y ahora me uno a todos los comentarios de esta publicación, espero que sea de ayuda, mi respuesta fue probada correctamente en Internet Explorer 11, Chrome y 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>
DIRECTIVA:
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');
}
}
});
}
}
})
EN CONTROLADOR:
$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 SERVICIO:
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 (en PRIMAVERA):
@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;
}
Esto funcionó para mí en angular:
var a = document.createElement("a");
a.href = 'fileURL';
a.download = 'fileName';
a.click();
data:text/plain;base64,${btoa(theStringGoesHere)}
No quería URL estática. Tengo AjaxFactory para hacer todas las operaciones de Ajax. Recibo la URL de fábrica y la estoy vinculando de la siguiente manera.
<a target="_self" href="{{ file.downloadUrl + '/' + order.OrderId + '/' + fileName }}" download="{{fileName}}">{{fileName}}</a>
Gracias @AhlemMustapha