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 相关文章推荐
HTA版JSMin(省略修饰语若干)基于javascript语言编写
Dec 24 Javascript
jQuery 点击图片跳转上一张或下一张功能的实现代码
Mar 12 Javascript
文本框中禁止非数字字符输入比如手机号码、邮编
Aug 19 Javascript
JavaScript缓冲运动实现方法(2则示例)
Jan 08 Javascript
Javascript获取图片原始宽度和高度的方法详解
Sep 20 Javascript
Angular.js自定义指令学习笔记实例
Feb 24 Javascript
vue 之 .sync 修饰符示例详解
Apr 21 Javascript
详解如何在Angular优雅编写HTTP请求
Dec 05 Javascript
微信小程序封装多张图片上传api代码实例
Dec 30 Javascript
在vue中实现禁止屏幕滚动,禁止屏幕滑动
Jul 22 Javascript
vue下载二进制流图片操作
Oct 26 Javascript
vue 获取到数据但却渲染不到页面上的解决方法
Nov 19 Vue.js
详解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 AJAX实例根据邮编自动完成地址信息
2008/11/23 PHP
深入理解PHP内核(一)
2015/11/10 PHP
php获取本机真实IP地址实例代码
2016/03/31 PHP
php+webSoket实现聊天室示例代码(附源码)
2017/02/17 PHP
PHP实现将标点符号正则替换为空格的方法
2017/08/09 PHP
PHP设计模式之工厂模式实例总结
2017/09/01 PHP
PHP的PDO预处理语句与存储过程
2019/01/27 PHP
Laravel创建数据库表结构的例子
2019/10/09 PHP
用javascript获取当页面上鼠标光标位置和触发事件的对象的代码
2009/12/09 Javascript
IE与Firefox在JavaScript上的7个不同句法分享
2011/10/30 Javascript
arguments对象验证函数的参数是否合法
2015/06/26 Javascript
js面向对象之常见创建对象的几种方式(工厂模式、构造函数模式、原型模式)
2015/11/09 Javascript
EasyUI 中combotree 默认不能选择父节点的实现方法
2016/11/07 Javascript
JavaScript变量作用域_动力节点Java学院整理
2017/06/27 Javascript
解决element ui select下拉框不回显数据问题的解决
2019/02/20 Javascript
vue使用swiper.js重叠轮播组建样式
2019/11/14 Javascript
vue操作dom元素的3种方法示例
2020/09/20 Javascript
Python3基础之基本数据类型概述
2014/08/13 Python
一个基于flask的web应用诞生 记录用户账户登录状态(6)
2017/04/11 Python
基于数据归一化以及Python实现方式
2018/07/11 Python
python 用下标截取字符串的实例
2018/12/25 Python
Pytorch抽取网络层的Feature Map(Vgg)实例
2019/08/20 Python
100行Python代码实现每天不同时间段定时给女友发消息
2019/09/27 Python
如何把python项目部署到linux服务器
2020/08/26 Python
Onzie官网:美国时尚瑜伽品牌
2019/08/21 全球购物
俄罗斯隐形眼镜和眼镜在线商店:Cronos
2020/06/02 全球购物
JMS中Topic和Queue有什么区别
2013/05/15 面试题
生产部厂长助理职位说明书
2014/03/03 职场文书
办公室文员岗位职责
2015/02/04 职场文书
2015年毕业生个人自荐书
2015/03/24 职场文书
公司周年庆寄语
2019/06/21 职场文书
高中16字霸气押韵班级口号集锦!
2019/06/27 职场文书
spring boot项目application.properties文件存放及使用介绍
2021/06/30 Java/Android
Java基于Dijkstra算法实现校园导游程序
2022/03/17 Java/Android
十大最强奥特曼武器:怪兽战斗仪在榜,第五奥特之父只使用过一次
2022/03/18 日漫
MySQL读取JSON转换的方式
2022/03/18 MySQL