आप AngularJS या जावास्क्रिप्ट के साथ डाउनलोड के लिए एक फ़ाइल कैसे सेवा करते हैं?


96

मैं एक छिपे हुए textarea में कुछ पाठ है। जब एक बटन पर क्लिक किया जाता है तो मैं एक .txtफ़ाइल के रूप में डाउनलोड के लिए दिए गए पाठ की पेशकश करना चाहूंगा । क्या यह एंगुलरजेएस या जावास्क्रिप्ट का उपयोग करना संभव है?


1
आप किन ब्राउज़रों का समर्थन करते हैं? इसे कुछ रचनात्मक तरीकों से हल किया जा सकता है (जैसे डेटा-यूरिस, ब्लॉब्स, ब्राउज़र का इतिहास एपीआई आदि) लेकिन यह वास्तव में निर्भर करता है।
बेंजामिन ग्रुएनबाम

कम आधुनिक ब्राउज़रों के लिए कोणीय फ़ाइल सेवर एक अच्छा पॉलीफ़िल है।
जार्जियावग

जवाबों:


110

आप इस तरह से कुछ का उपयोग कर सकते हैं 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 () पर कॉल करके जारी किया जाना चाहिए, जब आपको उनकी आवश्यकता नहीं होगी। दस्तावेज़ अनलोड होने पर ब्राउज़र स्वचालित रूप से इन्हें जारी करेगा; हालाँकि, इष्टतम प्रदर्शन और स्मृति उपयोग के लिए, यदि कोई सुरक्षित समय है जब आप उन्हें स्पष्ट रूप से अनलोड कर सकते हैं, तो आपको ऐसा करना चाहिए।

स्रोत: एमडीएन


3
आधुनिक ब्राउज़र और IE10 +
dave1010

@thriqon वाह फ़ायरफ़ॉक्स + क्रोम वास्तव में वहाँ दूसरों को दिखा रहा है!
जॉनीराया

महान समाधान, लेकिन $scope.urlमेरे लिए काम नहीं किया। मुझे window.locationइसके बजाय उपयोग करना था।
बजे गुस्तावो स्ट्राबे

7
मैंने देखा कि तब एंकर टैग असुरक्षित के साथ उपसर्ग करता है। इसके चारों ओर पाने के लिए आपको $ compileProvider `.config (('' $ compileProvider ') फंक्शन ($ compileProvider) {$ compileProvider.aHrefSanitizationWhitelist (/ ^) का उपयोग करके अपने ऐप में सफेद सूची में' बूँद 'जोड़ने की आवश्यकता होगी। \ s * (https (? https; ftto
coderman

10
यह downloadविशेषता किसी भी IE या सफारी संस्करणों में समर्थित नहीं है, हालांकि caniuse.com/#feat=download
हारून

33

निम्नलिखित कोड का उपयोग करके डाउनलोड करने के लिए बस बटन पर क्लिक करें।

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


1
@Arrut ने मेरे लिए आवश्यकतानुसार काम किया, लेकिन क्या आप कोड समझा सकते हैं?
हर्ष दफ्तरी

इस समाधान की तरह! सर्वर से डेटा प्राप्त करते समय, उदाहरण के $http.get(...)लिए सुनिश्चित करें कि responseType:'arraybuffer'जैसे यहाँ बताया गया है, वैसे ही इस्तेमाल करना : stackoverflow.com/questions/21628378/…
टिम ब्यूथ

Chrome (Win) में काम करता है, लेकिन Safari (Mac) ब्राउज़र में ब्लॉब्ड फ़ाइल को खोलता है। (बूँद: https / ...) इस समाधान से मुझे अपने वादों के हल होने की प्रतीक्षा करने की सुविधा मिलती है।
सेक् ी

26

इसे इस्तेमाल करे

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

और इस साइट पर जाएँ यह आपके लिए उपयोगी हो सकता है :)

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


7
उस downloadविशेषता से सावधान रहें जो अभी भी किसी भी IE या सफारी संस्करण द्वारा समर्थित नहीं है। इसे यहाँ देखें: caniuse.com/#feat=download
पियरे-

जब मैं इसे कोणीय के साथ उपयोग करता हूँ तो यह url से $ urlRouterProvider ले जाता है और मेरे डिफ़ॉल्ट पृष्ठ पर रीडायरेक्ट होता है, क्या नेविगेशन के बजाय किसी फ़ाइल को डाउनलोड करने का कोई समाधान है
HardikDG

मुझे हमेशा यह पता चलता है कि जब कोई इस तरह से लिंक पोस्ट करता है।
अगस्त

22

यह दूसरी ब्राउज़र विंडो खोलने की आवश्यकता के बिना जावास्क्रिप्ट में किया जा सकता है।

window.location.assign('url');

अपनी फ़ाइल के लिंक के साथ 'url' बदलें। आप इसे एक फ़ंक्शन में रख सकते हैं और इसे कॉल कर सकते हैं ng-clickयदि आपको एक बटन से डाउनलोड को ट्रिगर करने की आवश्यकता है।


2
यह डायलॉग विंडो दिखाने के बजाय Pdf doc के साथ साइट को प्रतिस्थापित करता है।
fdrv

धन्यवाद! एक जादू की तरह काम करता है।
सागी

14

काम पर हमारी वर्तमान परियोजना में हमारे पास एक अदृश्य iFrame था और मुझे एक डायलॉग बॉक्स डाउनलोड करने के लिए iFrame में फ़ाइल के लिए url फीड करना था। बटन पर क्लिक करने पर, नियंत्रक गतिशील यूआरएल उत्पन्न करता है और एक $ गुंजाइश घटना को ट्रिगर करता है जहां एक कस्टम directiveमैंने लिखा है, सूचीबद्ध है। यदि यह पहले से ही मौजूद नहीं है और इस पर url विशेषता सेट करता है, तो निर्देश शरीर को एक iFrame संलग्न करेगा।

संपादित करें: एक निर्देश जोड़ना

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);

1
कोड स्निपेट एक बड़ी मदद होगी।
सुधीर एन

ऊपर का निर्देश मेरे लिए काम नहीं कर रहा है, जब मैंने iframe निर्माण को दायरे से बाहर रखा है। इस पर $ iframe बनाता है, लेकिन प्रसारण का उपयोग करते समय घटना पर $ कॉल नहीं कर रहा है
Kanagu

हाँ $ गुंजाइश। $ प्रसारण केवल बच्चों पर काम करता है। यदि संभव हो तो आप निर्देश को शीर्ष स्तर के दायरे में रख सकते हैं।
केतन

12

आप location.hrefएक डेटा यूआरआई सेट कर सकते हैं जिसमें वह डेटा है जिसे आप उपयोगकर्ता को डाउनलोड करने देना चाहते हैं। इसके अलावा, मुझे नहीं लगता कि जावास्क्रिप्ट के साथ ऐसा करने का कोई तरीका है।


यह मेरे लिए बहुत अच्छा काम करता है, और हम उन सभी चीजों की तुलना में बहुत साफ थे, जो हम कोशिश कर रहे थे, या IMHO, ऊपर सुझाए गए जटिल दृष्टिकोण। कोणीय इसे पूरी तरह से अनदेखा करता है। या, यदि आप किसी अन्य विंडो में खोलने का प्रयास करना चाहते हैं, तो आप window.open () / $ window.open () का भी उपयोग कर सकते हैं। लेकिन आप आधुनिक ब्राउज़रों में पॉपअप ब्लॉकर्स चलाएंगे ...
XML

1
कोणीय 1.3 में, $location.hrefबदलकर$window.location.href
igortg

यह एक बेहतरीन जवाब है। एसओ पर निम्नलिखित लिंक एक पूर्ण काम करने का उदाहरण प्रदान करता है: stackoverflow.com/a/30889331/1625820
13:27 पर herrtim

7

केवल यह जोड़ना चाहते हैं कि यदि असुरक्षित के कारण यह फ़ाइल डाउनलोड नहीं करता है: blob: null ... जब आप डाउनलोड बटन पर होवर करते हैं, तो आपको इसे sanitize करना होगा। उदाहरण के लिए,

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

app.config (समारोह ($ compileProvider) {

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

5

यदि आपके पास सर्वर पर पहुंच है, तो हेडर सेट करने पर विचार करें जैसा कि इस अधिक सामान्य प्रश्न में उत्तर दिया गया है

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

उस उत्तर पर टिप्पणियों को पढ़ना, ओकटेट-स्ट्रीम की तुलना में अधिक विशिष्ट सामग्री-प्रकार का उपयोग करना उचित है।


4

मेरे पास एक ही समस्या थी और कई घंटे अलग-अलग समाधान खोजने में खर्च करते थे, और अब मैं इस पोस्ट में सभी टिप्पणियों को शामिल करता हूं। मुझे आशा है कि यह उपयोगी होगा, मेरा जवाब सही ढंग से इंटरनेट एक्सप्लोरर 11, क्रोम और फायरफॉक्स पर परीक्षण किया गया था।

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;
}

धन्यवाद, यह वास्तव में मेरे लिए काम किया, विशेष रूप से जब से मुझे बड़ी फ़ाइल स्थानांतरण की आवश्यकता थी।
मार्कोस पाउलो

3

यह मेरे लिए कोणीय में काम करता है:

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

यदि आपके पास एक स्ट्रिंग है जिसे आप डाउनलोड करना चाहते हैं, तो फाइलल को बदल देंdata:text/plain;base64,${btoa(theStringGoesHere)}
चिकन सूप

2

मैं स्टैटिक उरल नहीं चाहता था। मेरे पास सभी अजाक्स संचालन करने के लिए AjaxFactory है। मैं कारखाने से url प्राप्त कर रहा हूं और इसे निम्नानुसार बांध रहा हूं।

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

साभार @AhlemMustapha

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.