Angular Excel 导入与导出的实现代码
前言
本文基于angularv7.2.7,初次编写于2019-4-17。
虽然代码是基于angular7.2.7,但是语法是基于angular4.X以上均可使用。在项目开发过程中,我们经常需要跟后端进行文件交互,常见的诸如图片上传,excel导入与导出等。这里我们只讨论关于excel的导入与导出。
Excel导入
excel导入在angular中其实非常简单,只需要安装xlsx插件就可以了。
安装xlsx插件
npminstallxlsx--save
在component中导入
import*asXLSXfrom'xlsx';
关键代码
import*asXLSXfrom'xlsx'; excelData=[]; importExcel(evt:any){ /*wireupfilereader*/ consttarget:DataTransfer=(evt.target); if(target.files.length!==1)thrownewError('Cannotusemultiplefiles'); constreader:FileReader=newFileReader(); reader.onload=(e:any)=>{ /*readworkbook*/ constbstr:string=e.target.result; constwb:XLSX.WorkBook=XLSX.read(bstr,{type:'binary'}); /*grabfirstsheet*/ constwsname:string=wb.SheetNames[0]; constws:XLSX.WorkSheet=wb.Sheets[wsname]; /*savedata*/ this.excelData=(XLSX.utils.sheet_to_json(ws,{header:1})); evt.target.value=""//清空 }; reader.readAsBinaryString(target.files[0]); }
Excel导出
传统的导出功能我们一般是放在后端实现,由后端生成文件的Url或者文件流给到前端。注:这种是通过浏览器的下载功能直接下载的。一般有以下几种方式实现:
get请求+window.open(url)
后端返回一个文件的url或者文件流,这种方式均可以直接下载。前提是http请求为get。
post请求+标签
前端代码:
exportExcel(codeList:string[]){ returnthis.http.post(this.ExportExcelByCodesUrl,codeList,{ responseType:'arraybuffer',//设置响应类型 observe:"response",//返回responseheader headers:{'Content-Type':'application/json'} }) .subscribe((response:any)=>{ this.downLoadFile(response,"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8") }) } /** *Methodisusetodownloadfile. *@paramdata-ArrayBufferdata *@paramtype-typeofthedocument. */ downLoadFile(data:any,type:string){ varblob=newBlob([data.body],{type:type}); letdownloadElement=document.createElement('a'); lethref=window.URL.createObjectURL(blob);//创建下载的链接 downloadElement.href=href; letfilename=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对象 }
后端代码:
这里后端是使用的Asp.NetCore2.1
publicIActionResultCreateExcel(stringfileName,Listlist) { string[]propertyNames={""};//业务代码 string[]propertyNameCn={""};//业务代码 MemoryStreamms=ExcelsHelper .ListToExcel(fileName,list,propertyNames,propertyNameCn); HttpContext.Response.Headers.Add("Download-FileName",WebUtility.UrlEncode(fileName)); returnFile(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”),具体每个语言有自己的实现方式。如果不设置的话,前端无法获取响应头。
post请求+form表单+iframe标签(暂无代码实现)
总结
我在开发过程中有遇到以下几个问题,折腾了很久:
- 前后端的MIME类型没有对应,导致文件无法成功下载,这里是完整的MIME类型列表
- 无法获取responseheader,原因有二:
(1)后端没有设置跨域的响应头
(2)前端的http请求语法书写错误,一直获取到的是httpresponsebody,而非完整的httpresponse。完整写法参考以上代码,关键是:observe:"response"
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。