У меня есть текст в скрытом текстовом поле. При нажатии кнопки я хотел бы, чтобы текст предлагался для загрузки в виде .txt
файла. Возможно ли это с помощью AngularJS или Javascript?
У меня есть текст в скрытом текстовом поле. При нажатии кнопки я хотел бы, чтобы текст предлагался для загрузки в виде .txt
файла. Возможно ли это с помощью AngularJS или Javascript?
Ответы:
Вы можете сделать что-то подобное, используя Blob
.
<a download="content.txt" ng-href="{{ url }}">download</a>
в вашем контроллере:
var content = 'file content for example';
var blob = new Blob([ content ], { type : 'text/plain' });
$scope.url = (window.URL || window.webkitURL).createObjectURL( blob );
чтобы включить URL:
app = angular.module(...);
app.config(['$compileProvider',
function ($compileProvider) {
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|file|blob):/);
}]);
Обратите внимание, что
Каждый раз, когда вы вызываете createObjectURL (), создается новый URL-адрес объекта, даже если вы уже создали его для того же объекта. Каждый из них должен быть освобожден путем вызова URL.revokeObjectURL (), когда они вам больше не нужны. Браузеры автоматически освобождают их, когда документ выгружается; однако для оптимальной производительности и использования памяти, если есть безопасные моменты, когда вы можете явно выгрузить их, вы должны это сделать.
Источник: MDN
$scope.url
у меня не сработало. Мне пришлось использовать window.location
вместо этого.
download
Атрибут не поддерживается в IE любой версии или Safari , хотя caniuse.com/#feat=download
Просто нажмите кнопку, чтобы загрузить, используя следующий код.
в html
<a class="btn" ng-click="saveJSON()" ng-href="{{ url }}">Export to JSON</a>
В контроллере
$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(...)
убедитесь, что вы установили, responseType:'arraybuffer'
как описано здесь: stackoverflow.com/questions/21628378/…
Попробуй это
<a target="_self" href="mysite.com/uploads/ahlem.pdf" download="foo.pdf">
и посетите этот сайт, это может быть вам полезно :)
download
атрибута, который по-прежнему не поддерживается ни в IE, ни в версии Safari. Проверьте это здесь: caniuse.com/#feat=download
Это можно сделать с помощью javascript без необходимости открывать другое окно браузера.
window.location.assign('url');
Замените url ссылкой на ваш файл. Вы можете поместить это в функцию и вызвать ее, ng-click
если вам нужно запустить загрузку с помощью кнопки.
В нашем текущем проекте у нас был невидимый iFrame, и мне пришлось передать URL-адрес файла в iFrame, чтобы получить диалоговое окно загрузки. При нажатии кнопки контроллер генерирует динамический URL-адрес и запускает событие $ scope, в котором отображается пользовательский, который directive
я написал. Директива добавит iFrame к телу, если он еще не существует, и установит для него атрибут url.
РЕДАКТИРОВАТЬ: добавление директивы
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;
});
Эта директива реагирует на событие контроллера, называемое downloadFile
так что в вашем контроллере вы делаете
$scope.$broadcast("downloadFile", url);
Вы можете установить location.href
в данных URI , содержащий данные , которые вы хотите , чтобы позволить загрузку пользователя. Помимо этого, я не думаю, что есть способ сделать это с помощью только JavaScript.
$location.href
изменен на$window.location.href
Я просто хотел бы добавить, что в случае, если он не загружает файл из-за unsafe: blob: null ... когда вы наводите курсор на кнопку загрузки, вы должны его дезинфицировать. Например,
var app = angular.module ('приложение', []);
app.config (function ($ compileProvider) {
$compileProvider.aHrefSanitizationWhitelist(/^\s*(|blob|):/);
Если у вас есть доступ к серверу, рассмотрите возможность установки заголовков, как указано в этом более общем вопросе .
Content-Type: application/octet-stream
Content-Disposition: attachment;filename=\"filename.xxx\"
Читая комментарии к этому ответу, рекомендуется использовать более конкретный Content-Type, чем octet-stream.
У меня была такая же проблема, и я потратил много часов на поиск разных решений, и теперь я присоединяюсь ко всем комментариям в этом сообщении. Надеюсь, это будет полезно, мой ответ был правильно протестирован в Internet Explorer 11, Chrome и 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('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');
}
}
});
}
}
})
В КОНТРОЛЛЕРЕ:
$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=[];
});
};
В СЕРВИСЕ:
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;
};
НАЗАД (ВЕСНОЙ):
@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;
}
Это сработало для меня в angular:
var a = document.createElement("a");
a.href = 'fileURL';
a.download = 'fileName';
a.click();
data:text/plain;base64,${btoa(theStringGoesHere)}
Мне не нужен статический URL. У меня есть AjaxFactory для выполнения всех операций ajax. Я получаю URL-адрес с завода и привязываю его следующим образом.
<a target="_self" href="{{ file.downloadUrl + '/' + order.OrderId + '/' + fileName }}" download="{{fileName}}">{{fileName}}</a>
Спасибо @AhlemMustapha