숨겨진 텍스트 영역에 텍스트가 있습니다. 버튼을 클릭하면 텍스트를 파일로 다운로드 할 수 있도록하고 싶습니다 .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
현재 작업중인 프로젝트에서는 보이지 않는 iFrame이 있었고 다운로드 대화 상자를 얻기 위해 파일의 URL을 iFrame에 제공해야했습니다. 버튼을 클릭하면 컨트롤러가 동적 URL을 생성하고 directive
내가 작성한 사용자 정의 가 나열 되는 $ scope 이벤트를 트리거합니다 . 지시문은 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
서버에서에 대한 액세스 권한 이있는 경우이보다 일반적인 질문에 대한 답변으로 헤더를 설정 하는 것이 좋습니다.
Content-Type: application/octet-stream
Content-Disposition: attachment;filename=\"filename.xxx\"
해당 답변에 대한 의견을 읽으면 옥텟 스트림보다 더 구체적인 콘텐츠 유형을 사용하는 것이 좋습니다.
나는 같은 문제가 있었고 다른 해결책을 찾는 데 많은 시간을 보냈고 이제이 게시물의 모든 의견에 참여했습니다.
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;
}