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 相关文章推荐
JQuery入门——用one()方法绑定事件处理函数(仅触发一次)
Feb 05 Javascript
jquery 图片缩放拖动的简单实例
Jan 08 Javascript
JS实现仿微博可关闭弹出层效果
Sep 21 Javascript
js验证身份证号有效性并提示对应信息
Oct 19 Javascript
基于JQuery实现图片上传预览与删除操作
May 24 Javascript
基于JQuery及AJAX实现名人名言随机生成器
Feb 10 Javascript
layui框架中layer父子页面交互的方法分析
Nov 15 Javascript
webpack vue 项目打包生成的文件,资源文件报404问题的修复方法(总结篇)
Jan 09 Javascript
详解es6超好用的语法糖Decorator
Aug 01 Javascript
微信小程序实现登录遮罩效果
Nov 01 Javascript
如何解决webpack-dev-server代理常切换问题
Jan 09 Javascript
如何修改Vue打包后文件的接口地址配置的方法
Apr 22 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与ASP
2006/10/09 PHP
PHP 判断变量类型实现代码
2009/10/23 PHP
PHP图像处理类库及演示分享
2015/05/17 PHP
利用php的ob缓存机制实现页面静态化方法
2017/07/09 PHP
JavaScript Cookie显示用户上次访问的时间和次数
2009/12/08 Javascript
JavaScript的parseInt 取整使用
2011/05/09 Javascript
jquery中ajax学习笔记一
2011/10/16 Javascript
JAVASCRIPT模式窗口中下载文件无法接收iframe的流
2013/10/11 Javascript
Javascript中call与apply的学习笔记
2014/09/22 Javascript
js全选实现和判断是否有复选框选中的方法
2015/02/17 Javascript
javascript实现 百度翻译 可折叠的分享按钮列表
2015/03/12 Javascript
使用iojs的jsdom库实现同步系统时间
2015/04/20 Javascript
JS实现黑色大气的二级导航菜单效果
2015/09/18 Javascript
Jquery zTree 树控件异步加载操作
2016/02/25 Javascript
canvas实现简易的圆环进度条效果
2017/02/28 Javascript
JS基于正则表达式的替换操作(replace)用法示例
2017/04/28 Javascript
JavaScript严格模式下关于this的几种指向详解
2017/07/12 Javascript
AngularJS 购物车全选/取消全选功能的实现方法
2017/08/14 Javascript
jQuery中extend函数简单用法示例
2017/10/11 jQuery
jQuery实时统计输入框字数及限制
2020/06/24 jQuery
vue中组件通信详解(父子组件, 爷孙组件, 兄弟组件)
2020/07/27 Javascript
11个Python Pandas小技巧让你的工作更高效(附代码实例)
2019/04/30 Python
详解Python利用random生成一个列表内的随机数
2019/08/21 Python
使用pygame编写Flappy bird小游戏
2020/03/14 Python
HTML5 实现一个访问本地文件的实例
2012/12/13 HTML / CSS
Html5应用程序缓存(Cache manifest)
2018/06/04 HTML / CSS
什么叫做SQL注入,如何防止
2016/10/04 面试题
JSP和Servlet有哪些相同点和不同点,他们之间的联系是什么?
2015/10/22 面试题
农田水利实习自我鉴定
2013/09/19 职场文书
中学生评语大全
2014/04/18 职场文书
市场营销调查计划书
2014/05/02 职场文书
小学三好学生事迹材料
2014/08/15 职场文书
创业计划书之面包店
2019/09/12 职场文书
导游词之千岛湖
2019/09/23 职场文书
七年级作文之英语老师
2019/10/28 职场文书
Apache Pulsar结合Hudi构建Lakehouse方案分析
2022/03/31 Servers