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 相关文章推荐
Javascript实现的鼠标经过时播放声音
May 18 Javascript
鼠标右击事件代码(asp.net后台)
Jan 27 Javascript
JS和Jquery获取和修改label的值的示例代码
Jan 15 Javascript
以WordPress为例讲解jQuery美化页面Title的方法
May 23 Javascript
jQuery获取元素父节点的方法
Jun 21 Javascript
BootStrap初学者对弹出框和进度条的使用感觉
Jun 27 Javascript
AngularJS 过滤器(自带和自建)详解
Sep 19 Javascript
jQuery实现文档树效果
Feb 20 Javascript
React实践之Tree组件的使用方法
Sep 30 Javascript
jquery中ajax请求后台数据成功后既不执行success也不执行error的完美解决方法
Dec 24 jQuery
JavaScript工具库之Lodash详解
Jun 15 Javascript
package.json各个属性说明详解
Mar 11 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
PHP 5昨天隆重推出--PHP 5/Zend Engine 2.0新特性
2006/10/09 PHP
php读取文件内容的几种方法详解
2013/06/26 PHP
解析CI的AJAX分页 另类实现方法
2013/06/27 PHP
php去除html标记的原生函数详解
2015/01/27 PHP
php实现简单文件下载的方法
2015/01/30 PHP
PHP实现将textarea的值根据回车换行拆分至数组
2015/06/10 PHP
php使用redis的有序集合zset实现延迟队列应用示例
2020/02/20 PHP
extjs3 combobox取value和text案例详解
2013/02/06 Javascript
javascript 上下banner替换具体实现
2013/11/14 Javascript
javascript 表格内容排序 简单操作示例代码
2014/01/03 Javascript
js返回前一页刷新本页重载页面
2014/07/29 Javascript
jQuery点缩略图弹出层显示大图片
2015/02/13 Javascript
JS简单生成随机数(随机密码)的方法
2017/05/11 Javascript
vue 组件中slot插口的具体用法
2018/04/03 Javascript
详解vue-router 命名路由和命名视图
2018/06/01 Javascript
原生JS实现列表子元素顺序反转的方法分析
2018/07/02 Javascript
vue+elementUI中表格高亮或字体颜色改变操作
2020/11/02 Javascript
[02:04]2016国际邀请赛中国区预选赛VG.R晋级之路
2016/07/01 DOTA
[27:08]完美世界DOTA2联赛PWL S2 SZ vs Rebirth 第二场 11.21
2020/11/23 DOTA
pycharm 使用心得(九)解决No Python interpreter selected的问题
2014/06/06 Python
Python字符串替换实例分析
2015/05/11 Python
Python从MP3文件获取id3的方法
2015/06/15 Python
Python第三方库xlrd/xlwt的安装与读写Excel表格
2017/01/21 Python
itchat和matplotlib的结合使用爬取微信信息的实例
2017/08/25 Python
Django学习笔记之为Model添加Action
2019/04/30 Python
Tensorflow Summary用法学习笔记
2020/01/10 Python
如何在windows下安装配置python工具Ulipad
2020/10/27 Python
pandas统计重复值次数的方法实现
2021/02/20 Python
Html5原创俄罗斯方块(基于canvas)
2019/01/07 HTML / CSS
Notino芬兰:购买香水和化妆品
2019/04/15 全球购物
Flesh Beauty官网:露华浓集团旗下彩妆品牌
2021/02/15 全球购物
如何反序的迭代一个序列?how do I iterate over a sequence in reverse order
2012/02/04 面试题
艺术学院毕业生求职信
2014/07/09 职场文书
2014年保卫科工作总结
2014/12/05 职场文书
2015年学校少先队工作总结
2015/07/20 职场文书
JavaScript正则表达式实现注册信息校验功能
2022/05/30 Java/Android