转载:http://asdfblog.com/an-angularjs-directive-to-download-xls-files.html
在AngularJS中要下载一个Excel文件到底有多难呢?
最简单的方法
这当然是放一个 a
链接元素在页面搞定。
<a href="/path/file.xlsx" target="_blank">下载文件</a>
可如果我们涉及到一些身份验证,而且又是通过 Cookie
,浏览器会很怪的一并发送到服务端,是不是一切都很好呢?
如果……
像上面说的如果我需要自定义请求头,例如:OWIN等身份验证的情况下,怎么办呢?
问题
也许我们可以非常简单的通过 ajax
发送一个 get
请求,并填写相应 headers
,比如:
$http.get({
url: '/path/file.xlsx',
method: 'get',
headers: {
Authorization: 'Bearer pTVhzRZgA6yW-fp8c5vcxzBxr6vuIBYQrlo0ASIVxgkfN6'
}
}).success(function (data) {
// 怎么保存?
});
有一个办法就是我们可以通过 HTML5
的 a
元素,指定一段 Base64
数据编码,我们可以生成一个 a
链接,然后点击下载。
这种方式在我的实验中,发现对于 Excel 支持不好,对于大一点的文件,下载回来都是无法打开。
Blob
Blob 存储的是二进制,实则就是一个 JavaScript 下的一个 File 对象,目前被大部分流行浏览器所支持。
我这里还找到一个 FileServer.js 是对 Blob 保存的具体实现。
以下是我结合 FileServer.js 写的一个AngularJS指令,好了,废话不多说:
App.directive('downFile', ['$http',function ($http) {
return {
restrict: 'A',
scope: true,
link: function (scope, element, attr) {
var ele = $(element);
ele.on('click', function (e) {
ele.prop('disabled', true);
e.preventDefault();
$http({
url: attr.downFile,
method: 'get',
responseType: 'arraybuffer'
}).success(function (data, status, headers) {
ele.prop('disabled', false);
var type;
switch (attr.downFileType) {
case 'xlsx':
type = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
break;
}
if (!type) throw '无效类型';
saveAs(new Blob([data], { type: type }), decodeURI(headers()["x-filename"])); // 中文乱码
}).error(function (data, status) {
alert(data);
ele.prop('disabled', false);
});
});
}
};
}]);
相对于 View
的具体实现:
<button down-file="/order/export/{{item.id}}" down-file-type="xlsx" class="btn btn-green btn-sm">导出</button>
以下是 ASP.NET API 的具体实现:
HttpResponseMessage response = new HttpResponseMessage();
response.StatusCode = HttpStatusCode.OK;
response.Content = new ByteArrayContent(pck.GetAsByteArray());
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
response.Content.Headers.Add("x-filename", System.Web.HttpUtility.UrlEncode(item.title, System.Text.Encoding.UTF8) + ".xlsx"); // 中文乱码
return response;
中文文件名乱码问题
文件名为中文时获取到的 x-filename
会是乱码,所以需要进行编码,在示例中已经标识鸟。
写文章时比较仓促,所以示例中只对 Excel
进行转化,可以根据需求加入各种文件格式类型。
以上,希望帮助到各位。