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中的数学函数
Apr 04 Javascript
javascript 自动转到命名锚记
Jan 10 Javascript
event.srcElement 用法笔记e.target
Dec 18 Javascript
基于jquery的一行代码轻松实现拖动效果
Dec 28 Javascript
Jquery进度条插件 Progress Bar小问题解决
Jul 12 Javascript
javascript 中的console.log和弹出窗口alert
Aug 30 Javascript
详解jQuery中ajax.load()方法
Jan 25 Javascript
详解刷新页面vuex数据不消失和不跳转页面的解决
Jan 30 Javascript
vue中element-ui表格缩略图悬浮放大功能的实例代码
Jun 26 Javascript
小程序云开发之用户注册登录
May 18 Javascript
20道JS原理题助你面试一臂之力(必看)
Jul 22 Javascript
CountUp.js实现数字滚动增值效果
Oct 17 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数据库开发知多少
2006/10/09 PHP
windows下升级PHP到5.3.3的过程及注意事项
2010/10/12 PHP
php利用腾讯ip分享计划获取地理位置示例分享
2014/01/20 PHP
EarthLiveSharp中cloudinary的CDN图片缓存自动清理python脚本
2017/04/04 PHP
Linux下 php7安装redis的方法
2018/11/01 PHP
JS JavaScript获取Url参数,src属性参数
2021/03/09 Javascript
jquery tools系列 expose 学习
2009/09/06 Javascript
JavaScript高级程序设计 阅读笔记(十七) js事件
2012/08/14 Javascript
jQuery实现用方向键控制层的上下左右移动
2013/01/13 Javascript
javascript删除option选项的多种方法总结
2013/11/22 Javascript
解决window.opener=null;window.close(),只支持IE6不支持IE7,IE8的问题
2014/01/14 Javascript
jQuery中:file选择器用法实例
2015/01/04 Javascript
Backbone.js的Hello World程序实例
2015/06/19 Javascript
微信小程序 canvas API详解及实例代码
2016/10/08 Javascript
JavaScript 值类型和引用类型的初次研究(推荐)
2017/07/19 Javascript
JS数组实现分类统计实例代码
2018/09/30 Javascript
pageGroup.js实现分页功能
2019/07/27 Javascript
python list使用示例 list中找连续的数字
2014/01/27 Python
Python对象的深拷贝和浅拷贝详解
2014/08/25 Python
详谈python中冒号与逗号的区别
2018/04/18 Python
Python3实现配置文件差异对比脚本
2019/11/18 Python
关于numpy数组轴的使用详解
2019/12/05 Python
Python OpenCV实现测量图片物体宽度
2020/05/27 Python
浅析python实现动态规划背包问题
2020/12/31 Python
Pytorch 中的optimizer使用说明
2021/03/03 Python
7款设计巧妙的css3飘带状3D立体效果的导航菜单和表单窗口
2013/02/04 HTML / CSS
使用CSS3的ruby-position固定注音位置的用法示例
2016/07/05 HTML / CSS
Html5之自定义属性(data-,dataset)
2019/11/19 HTML / CSS
印度尼西亚电子产品购物网站:Kliknklik
2018/06/05 全球购物
Charlotte Tilbury澳大利亚官网:英国美妆品牌
2018/10/05 全球购物
法国女性内衣购物网站:Glamuse
2019/05/13 全球购物
《鲁班和橹板》教学反思
2014/04/27 职场文书
课外科技活动总结
2014/08/27 职场文书
组织生活会表态发言材料
2014/10/17 职场文书
刑事和解协议书范本
2014/11/19 职场文书
数学教师个人工作总结
2015/02/06 职场文书