本文基于 angular v7.2.7,初次编写于2019-4-17。前端
虽然代码是基于angular 7.2.7,可是语法是基于 angular 4.X 以上都可使用。在项目开发过程当中,咱们常常须要跟后端进行文件交互,常见的诸如 图片上传,excel 导入与导出等。这里咱们只讨论关于excel 的导入与导出。npm
excel 导入在angular 中其实很是简单,只须要安装 xlsx插件 就能够了。json
npm install xlsx --save
后端
import * as XLSX from 'xlsx';
跨域
import * as XLSX from 'xlsx';
excelData = [];
importExcel(evt: any) {
/* wire up file reader */
const target: DataTransfer = <DataTransfer>(evt.target);
if (target.files.length !== 1) throw new Error('Cannot use multiple files');
const reader: FileReader = new FileReader();
reader.onload = (e: any) => {
/* read workbook */
const bstr: string = e.target.result;
const wb: XLSX.WorkBook = XLSX.read(bstr, { type: 'binary' });
/* grab first sheet */
const wsname: string = wb.SheetNames[0];
const ws: XLSX.WorkSheet = wb.Sheets[wsname];
/* save data */
this.excelData = (XLSX.utils.sheet_to_json(ws, { header: 1 }));
evt.target.value = "" // 清空
};
reader.readAsBinaryString(target.files[0]);
}复制代码
传统的导出功能咱们通常是放在后端实现,由后端生成文件的Url或者文件流给到前端。注:这种是经过浏览器的下载功能直接下载的。通常有如下几种方式实现:浏览器
后端返回一个 文件的url 或者 文件流,这种方式都可以直接下载。前提是http请求为get。bash
前端代码:app
exportExcel(codeList: string[]) {
return this.http.post(this.ExportExcelByCodesUrl, codeList, {
responseType: 'arraybuffer',//设置响应类型
observe:"response",//返回response header
headers: { 'Content-Type': 'application/json' }
})
.subscribe((response:any)=>{
this.downLoadFile(response, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8")
})
}
/**
* Method is use to download file.
* @param data - Array Buffer data
* @param type - type of the document.
*/
downLoadFile(data: any, type: string) {
var blob = new Blob([data.body], { type: type});
let downloadElement = document.createElement('a');
let href = window.URL.createObjectURL(blob); //建立下载的连接
downloadElement.href = href;
let filename = data.headers.get("Download-FileName");//后端返回的自定义header
downloadElement.download = decodeURI(filename);
document.body.appendChild(downloadElement);
downloadElement.click(); //点击下载
document.body.removeChild(downloadElement); //下载完成移除元素
window.URL.revokeObjectURL(href); //释放掉blob对象
}复制代码
后端代码:post
这里后端是使用的Asp.Net Core 2.1 ui
public IActionResult CreateExcel(string fileName,List<ExportProductModel> list)
{
string[] propertyNames = {""};//业务代码
string[] propertyNameCn = {""};//业务代码
MemoryStream ms = ExcelsHelper<ExportProductModel>.ListToExcel(fileName, list, propertyNames, propertyNameCn);
HttpContext.Response.Headers.Add("Download-FileName",WebUtility.UrlEncode(fileName));
return File(ms, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;", WebUtility.UrlEncode(fileName));
}
services.AddCors(options =>
{
options.AddPolicy("AllowAllOrigin", builder =>
{
builder.AllowAnyHeader()
.AllowAnyMethod()
.AllowAnyOrigin()
.AllowCredentials()
.WithExposedHeaders("Download-FileName");
});
});复制代码
后端代码这里关键点是须要设置跨域的响应头(也就是“Download-FileName”),具体每一个语言有本身的实现方式。若是不设置的话,前端没法获取响应头。
我在开发过程当中有遇到如下几个问题,折腾了好久:
(1)后端没有设置跨域的响应头
(2)前端的http请求 语法书写错误,一直获取到的是http response body,而非完整的http response。完整写法参考以上代码,关键是 : observe:"response"
最后,但愿这篇文章可以帮助到你,共勉!