ฉันมีข้อความบางส่วนในพื้นที่ข้อความที่ซ่อนอยู่ เมื่อคลิกปุ่มฉันต้องการให้ข้อความที่เสนอให้ดาวน์โหลดเป็น.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(...)
make sure to set 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
สามารถทำได้ในจาวาสคริปต์โดยไม่จำเป็นต้องเปิดหน้าต่างเบราว์เซอร์อื่น
window.location.assign('url');
แทนที่ "url" ด้วยลิงก์ไปยังไฟล์ของคุณ คุณสามารถใส่ฟังก์ชันนี้และเรียกใช้งานได้ng-click
หากต้องการเรียกใช้การดาวน์โหลดจากปุ่ม
ในโครงการปัจจุบันของเราที่ทำงานเรามี iFrame ที่มองไม่เห็นและฉันต้องป้อน url สำหรับไฟล์ไปที่ iFrame เพื่อรับกล่องโต้ตอบการดาวน์โหลด เมื่อคลิกปุ่มตัวควบคุมจะสร้าง URL แบบไดนามิกและทริกเกอร์เหตุการณ์ $ ขอบเขตที่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
อยากจะเพิ่มในกรณีที่ไม่ดาวน์โหลดไฟล์เนื่องจากไม่ปลอดภัย: blob: null ... เมื่อคุณวางเมาส์เหนือปุ่มดาวน์โหลดคุณต้องล้างมัน ตัวอย่างเช่น
var app = angular.module ('แอป', []);
app.config (ฟังก์ชัน ($ 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;
};
BACKEND (บน SPRING):
@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;
}
สิ่งนี้ใช้ได้ผลสำหรับฉันในเชิงมุม:
var a = document.createElement("a");
a.href = 'fileURL';
a.download = 'fileName';
a.click();
data:text/plain;base64,${btoa(theStringGoesHere)}
ฉันไม่ต้องการ Static Url ฉันมี AjaxFactory สำหรับการดำเนินการ ajax ทั้งหมด ฉันได้รับ url จากโรงงานและผูกไว้ดังนี้
<a target="_self" href="{{ file.downloadUrl + '/' + order.OrderId + '/' + fileName }}" download="{{fileName}}">{{fileName}}</a>
ขอบคุณ @AhlemMustapha