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 基于原型的对象(创建、调用)
Oct 16 Javascript
Asp.net下使用Jquery Ajax传送和接收DataTable的代码
Sep 12 Javascript
使用js显示当前时间示例
Mar 02 Javascript
JavaScript两种跨域技术全面介绍
Apr 16 Javascript
jQuery中Ajax的get、post等方法详解
Jan 20 Javascript
Javascript中的几种URL编码方法比较
Jan 23 Javascript
JS排序方法(sort,bubble,select,insert)代码汇总
Jan 30 Javascript
JS滚动到指定位置导航栏固定顶部
Jul 03 Javascript
react-native-video实现视频全屏播放的方法
Mar 19 Javascript
Element的el-tree控件后台数据结构的生成以及方法的抽取
Mar 05 Javascript
解决elementUI 切换tab后 el_table 固定列下方多了一条线问题
Jul 19 Javascript
vue router-link 默认a标签去除下划线的实现
Nov 06 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
Session的工作方式
2006/10/09 PHP
PHP 反射机制实现动态代理的代码
2008/10/22 PHP
php如何调用webservice应用介绍
2012/11/24 PHP
深入PHP变量存储的详解
2013/06/13 PHP
PHP+redis实现添加处理投票的方法
2015/11/14 PHP
PHP统计目录中文件以及目录中目录大小的方法
2016/01/09 PHP
简单谈谈PHP中的Reload操作
2016/12/12 PHP
PHP pthreads v3下worker和pool的使用方法示例
2020/02/21 PHP
PHP实现简单的计算器
2020/08/28 PHP
Javascript 页面模板化很多人没有使用过的方法
2012/06/05 Javascript
jQuery.clean使用方法及思路分析
2013/01/07 Javascript
5款JavaScript代码压缩工具推荐
2014/07/07 Javascript
jQuery中[attribute*=value]选择器用法实例
2014/12/31 Javascript
js获取html的span标签的值方法(超简单)
2016/07/26 Javascript
javascript动画之模拟拖拽效果篇
2016/09/26 Javascript
javascript添加前置0(补零)的几种方法
2017/01/05 Javascript
Jquery异步上传文件代码实例
2019/11/13 jQuery
微信小程序使用自定义组件导航实现当前页面高亮
2020/01/02 Javascript
Angular短信模板校验代码
2020/09/23 Javascript
更改Python命令行交互提示符的方法
2015/01/14 Python
详解Python爬虫的基本写法
2016/01/08 Python
Python中模块string.py详解
2017/03/12 Python
Python+Selenium+PIL+Tesseract自动识别验证码进行一键登录
2017/09/20 Python
Python用access判断文件是否被占用的实例方法
2020/12/17 Python
CSS3.0实现霓虹灯按钮动画特效的示例代码
2021/01/12 HTML / CSS
村委会主任先进事迹
2014/01/15 职场文书
九年级英语教学反思
2014/01/31 职场文书
学雷锋月活动总结
2014/04/25 职场文书
竞聘上岗演讲
2014/05/19 职场文书
三分钟自我介绍演讲稿
2014/08/21 职场文书
树转促学习心得体会
2014/09/10 职场文书
2015年体育教学工作总结
2015/05/20 职场文书
学校运动会感想
2015/08/10 职场文书
Mysql - 常用函数 每天积极向上
2021/04/05 MySQL
vue如何批量引入组件、注册和使用详解
2021/05/12 Vue.js
python代码实现扫码关注公众号登录的实战
2021/11/01 Python