Angular Excel 导入与导出的实现代码


Posted in Javascript onApril 17, 2019

前言

本文基于 angular v7.2.7,初次编写于2019-4-17。

虽然代码是基于angular 7.2.7,但是语法是基于 angular 4.X 以上均可使用 。在项目开发过程中,我们经常需要跟后端进行文件交互,常见的诸如 图片上传,excel 导入与导出等。这里我们只讨论关于excel 的导入与导出。

Excel 导入

excel 导入在angular 中其实非常简单,只需要安装 xlsx插件 就可以了。

安装 xlsx 插件

npm install xlsx --save

在component 中导入

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]);

 }

Excel 导出

传统的导出功能我们一般是放在后端实现,由后端生成文件的Url或者文件流给到前端。注:这种是通过浏览器的下载功能直接下载的。一般有以下几种方式实现:

get 请求 + window.open(url)

后端返回一个 文件的url 或者 文件流,这种方式均可以直接下载。 前提是http请求为get 。

post 请求 + <a>标签

前端代码:

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对象
 }

后端代码:

这里后端是使用的Asp.Net Core 2.1

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”),具体每个语言有自己的实现方式。如果不设置的话,前端无法获取响应头。

post 请求 + form 表单 + iframe 标签(暂无代码实现)

总结

我在开发过程中有遇到以下几个问题,折腾了很久:

  • 前后端的MIME类型没有对应,导致文件无法成功下载,这里是完整的MIME类型列表
  • 无法获取response header,原因有二:

(1)后端没有设置跨域的响应头

(2)前端的http请求 语法书写错误,一直获取到的是http response body,而非完整的http response。完整写法参考以上代码,关键是 : observe:"response"

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Prototype Selector对象学习
Jul 23 Javascript
appendChild() 或 insertBefore()使用与区别介绍
Oct 11 Javascript
浅析JQuery UI Dialog的样式设置问题
Dec 18 Javascript
IE8中动态创建script标签onload无效的解决方法
Dec 22 Javascript
jQuery中ready事件用法实例
Jan 19 Javascript
js获取微信版本号的方法
May 12 Javascript
基于js实现投票的实例代码
Aug 04 Javascript
js实现瀑布流的三种方式比较
Jun 28 Javascript
深入学习Bootstrap表单
Dec 13 Javascript
React中jquery引用的实现方法
Sep 12 jQuery
基于vue和bootstrap实现简单留言板功能
May 30 Javascript
基于vue+element实现全局loading过程详解
Jul 10 Javascript
详解Vue路由自动注入实践
Apr 17 #Javascript
在Vue项目中使用jsencrypt.js对数据进行加密传输的方法
Apr 17 #Javascript
js的继承方法小结(prototype、call、apply)(推荐)
Apr 17 #Javascript
详解JavaScript的内存空间、赋值和深浅拷贝
Apr 17 #Javascript
Vue源码探究之虚拟节点的实现
Apr 17 #Javascript
ES6知识点整理之数组解构和字符串解构的应用示例
Apr 17 #Javascript
ES6知识点整理之对象解构赋值应用示例
Apr 17 #Javascript
You might like
Oracle 常见问题解答
2006/10/09 PHP
ThinkPHP之import方法实例详解
2014/06/20 PHP
smarty中常用方法实例总结
2015/08/07 PHP
laravel 5.3中自定义加密服务的方案详解
2017/05/09 PHP
Laravel给生产环境添加监听事件(SQL日志监听)
2017/06/19 PHP
jQuery live
2009/05/15 Javascript
SOSO地图JS画出标注和中心点以html形式运行
2013/08/09 Javascript
jQuery实现字符串按指定长度加入特定内容的方法
2015/03/11 Javascript
JS实现网站菜单拖拽移位效果的方法
2015/09/24 Javascript
移动端使用localResizeIMG4压缩图片
2017/04/22 Javascript
react native与webview通信的示例代码
2017/09/25 Javascript
薪资那么高的Web前端必看书单
2017/10/13 Javascript
微信小程使用swiper组件实现图片轮播切换显示功能【附源码下载】
2017/12/12 Javascript
微信小程序实现MUI数字输入框效果
2018/01/31 Javascript
vue + vuex todolist的实现示例代码
2018/03/09 Javascript
layer关闭弹出窗口触发表单提交问题的处理方法
2019/09/25 Javascript
js实现简易拖拽的示例
2020/10/26 Javascript
Python常用正则表达式符号浅析
2014/08/13 Python
Python环境下搭建属于自己的pip源的教程
2016/05/05 Python
基于PyQt4和PySide实现输入对话框效果
2019/02/27 Python
python psutil模块使用方法解析
2019/08/01 Python
Python实现基于socket的udp传输与接收功能详解
2019/11/15 Python
python读取ini配置的类封装代码实例
2020/01/08 Python
Macbook安装Python最新版本、GUI开发环境、图像处理、视频处理环境详解
2020/02/17 Python
PyCharm设置注释字体颜色以及是否倾斜的操作
2020/09/16 Python
国贸专业大学生职业生涯规划范文
2014/01/10 职场文书
《纸船和风筝》教学反思
2014/02/15 职场文书
卫校毕业生个人自我鉴定
2014/04/28 职场文书
会计系毕业生求职信
2014/05/28 职场文书
工地门卫岗位职责范本
2014/07/01 职场文书
2014年“向国旗敬礼”网上签名寄语活动方案
2014/09/27 职场文书
2014年环卫工作总结
2014/11/22 职场文书
工作服管理制度范本
2015/08/06 职场文书
如何写好闭幕词
2019/04/02 职场文书
四年级作文之植物
2019/09/20 职场文书
浅析Django接口版本控制
2021/06/26 Python