it-roy-ru.com

Как вы обслуживаете файл для загрузки с AngularJS или Javascript?

У меня есть текст в скрытой текстовой области. При нажатии кнопки мне бы хотелось, чтобы текст был предложен для загрузки в виде файла .txt. Возможно ли это с помощью AngularJS или Javascript?

93
nickponline

Вы можете сделать что-то подобное, используя 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 (), когда они вам больше не нужны. Браузеры выпустят их автоматически, когда документ выгружен; однако для оптимальной производительности и использования памяти, если есть безопасные времена, когда вы можете явно выгружать их, вы должны сделать это.

Источник: МДН

106
Tosh

Просто нажмите кнопку, чтобы загрузить, используя следующий код.

в 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();
		};

31
Amrut

Попробуй это 

<a target="_self" href="mysite.com/uploads/ahlem.pdf" download="foo.pdf">

и посетите этот сайт, это может быть полезно для вас :) 

http://docs.angularjs.org/guide/

26
AhlemMustapha

Это может быть сделано в JavaScript без необходимости открывать другое окно браузера.

window.location.assign('url');

Замените «url» ссылкой на ваш файл. Вы можете поместить это в функцию и вызвать ее с помощью ng-click, если вам нужно запустить загрузку с кнопки.

21
mm8154

В нашем текущем проекте на работе у нас был невидимый 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);
14
Ketan

Вы можете установить location.href в data URI , содержащий данные, которые вы хотите разрешить пользователю загружать. Кроме того, я не думаю, что есть какой-то способ сделать это только с помощью JavaScript.

12
Jani Hartikainen

Хотелось бы добавить, что в случае, если файл не загружается из-за небезопасного: blob: null ... при наведении курсора на кнопку загрузки, вы должны очистить его. Например,

var app = angular.module ('app', []);

app.config (функция ($ compileProvider) {

$compileProvider.aHrefSanitizationWhitelist(/^\s*(|blob|):/);
6
Samir Alajmovic

У меня была та же проблема, и я потратил много часов, чтобы найти разные решения, и теперь я присоединяюсь ко всем комментариям в этом посте. Надеюсь, это будет полезно, мой ответ был правильно протестирован в 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 = /*@[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');
                    }
                }
            });

        }
    }
})

В КОНТРОЛЛЕРЕ:

$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;
}
4
havelino

Если у вас есть доступ к серверу, рассмотрите возможность установки заголовков как ответили на этот более общий вопрос .

Content-Type: application/octet-stream
Content-Disposition: attachment;filename=\"filename.xxx\"

Читая комментарии к этому ответу, желательно использовать более конкретный Content-Type, чем octet-stream.

4
plong0

Я не хотел статический URL. У меня есть AjaxFactory для выполнения всех операций Ajax. Я получаю URL с завода и связываю его следующим образом.

<a target="_self" href="{{ file.downloadUrl + '/' + order.OrderId + '/' + fileName }}" download="{{fileName}}">{{fileName}}</a>

Спасибо @AhlemMustapha

2
om471987

Это сработало для меня в угловых:

var a = document.createElement("a");
a.href = 'fileURL';
a.download = 'fileName';
a.click();
0
Zohab Ali