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 相关文章推荐
使用JS进行目录上传(相当于批量上传)
Dec 05 Javascript
疯狂Jquery第一天(Jquery学习笔记)
May 11 Javascript
javascript window.confirm确认 取消对话框实现代码小结
Oct 21 Javascript
jQuery中:first-child选择器用法实例
Dec 31 Javascript
详解JavaScript实现设计模式中的适配器模式的方法
May 18 Javascript
关于两个jQuery(js)特效冲突的bug的解决办法
Sep 04 Javascript
easyui combobox开启搜索自动完成功能的实例代码
Nov 08 Javascript
浅谈js函数的多种定义方法与区别
Nov 29 Javascript
swiper动态改变滑动内容的实现方法
Jan 17 Javascript
JS实现同一DOM元素上onClick事件与onDblClick事件并存的解决方法
Jun 07 Javascript
Vue.js获取被选择的option的value和text值方法
Aug 24 Javascript
Vue双向绑定实现原理与方法详解
May 07 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
JQuery this 和 $(this) 的区别
2009/08/23 Javascript
jQuery实现的导航条切换可显示隐藏
2014/10/22 Javascript
javascript跨域方法、原理以及出现问题解决方法(详解)
2015/08/06 Javascript
Hallo.js基于jQuery UI所见即所得的Web编辑器
2016/01/26 Javascript
实现高性能JavaScript之执行与加载
2016/01/30 Javascript
JavaScript 轮播图和自定义滚动条配合鼠标滚轮分享代码贴
2016/10/28 Javascript
jQuery插件开发发送短信倒计时功能代码
2017/05/09 jQuery
浅谈react 同构之样式直出
2017/11/07 Javascript
bmob js-sdk 在vue中的使用教程
2018/01/21 Javascript
jQuery中将json数据显示到页面表格的方法
2018/05/27 jQuery
vue基于element的区间选择组件
2018/09/07 Javascript
Vue中 v-if 和v-else-if页面加载出现闪现的问题及解决方法
2018/10/12 Javascript
详解koa2学习中使用 async 、await、promise解决异步的问题
2018/11/13 Javascript
vue将后台数据时间戳转换成日期格式
2019/07/31 Javascript
微信小程序添加插屏广告并设置显示频率(一天一次)
2019/12/06 Javascript
[58:29]DOTA2-DPC中国联赛 正赛 Phoenix vs XG BO3 第一场 1月31日
2021/03/11 DOTA
Python天气预报采集器实现代码(网页爬虫)
2012/10/07 Python
python检测远程udp端口是否打开的方法
2015/03/14 Python
详解Python自建logging模块
2018/01/29 Python
Python实现的端口扫描功能示例
2018/04/08 Python
Python返回数组/List长度的实例
2018/06/23 Python
对python读写文件去重、RE、set的使用详解
2018/12/11 Python
centos 安装Python3 及对应的pip教程详解
2019/06/28 Python
python读取并写入mat文件的方法
2019/07/12 Python
浅谈Django中view对数据库的调用方法
2019/07/18 Python
Python上下文管理器用法及实例解析
2019/11/11 Python
HTML5 文件域+FileReader 分段读取文件并上传到服务器
2017/10/23 HTML / CSS
入党积极分子介绍信
2014/01/17 职场文书
光荣入党自我鉴定
2014/01/22 职场文书
安全横幅标语
2014/06/09 职场文书
售后客服工作职责
2014/06/16 职场文书
2014年个人工作总结模板
2014/12/15 职场文书
2015年派出所民警工作总结
2015/04/24 职场文书
法院答辩状格式
2015/05/22 职场文书
英文投诉信格式
2015/07/03 职场文书
Python实现机器学习算法的分类
2021/06/03 Python