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 相关文章推荐
动态改变textbox的宽高的js
Oct 26 Javascript
用js实现手把手教你月入万刀(转贴)
Nov 07 Javascript
JavaScript可否多线程? 深入理解JavaScript定时机制
May 23 Javascript
Linux CentOS系统下安装node.js与express的方法
Apr 01 Javascript
ES6中Proxy代理用法实例浅析
Apr 06 Javascript
Vue导出json数据到Excel电子表格的示例
Dec 04 Javascript
详解Vue.js自定义tipOnce指令用法实例
Dec 19 Javascript
浅谈JavaScript闭包
Apr 09 Javascript
JavaScript交换变量的常用方法小结【4种方法】
May 07 Javascript
小程序实现列表展开收起效果
Jul 29 Javascript
JS变量提升及函数提升实例解析
Sep 03 Javascript
vue使用vant中的checkbox实现全选功能
Nov 17 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
深入解析yii权限分级式访问控制的实现(非RBAC法)
2013/06/13 PHP
在PHP中使用redis
2013/11/04 PHP
PHP 动态生成静态HTML页面示例代码
2014/01/15 PHP
Zend Framework教程之MVC框架的Controller用法分析
2016/03/07 PHP
PHP使用PhpSpreadsheet操作Excel实例详解
2020/03/26 PHP
PHP7新增函数
2021/03/09 PHP
jquery 事件冒泡的介绍以及如何阻止事件冒泡
2012/12/25 Javascript
js随机颜色代码的多种实现方式
2013/04/23 Javascript
jQuery实现Twitter的自动文字补齐特效
2014/11/28 Javascript
jquery实现将获取的颜色值转换为十六进制形式的方法
2014/12/20 Javascript
被遗忘的javascript的slice() 方法
2015/04/20 Javascript
Nodejs如何复制文件
2016/03/09 NodeJs
浅谈JavaScript的计时器对象
2016/12/26 Javascript
jQuery使用方法
2017/02/04 Javascript
jQuery实现 上升、下降、删除、添加一行代码
2017/03/06 Javascript
JavaScrip数组删除特定元素的几种方法总结
2017/09/06 Javascript
javascript修改浏览器title方法 JS动态修改浏览器标题
2017/11/30 Javascript
Vue实现根据hash高亮选项卡
2019/05/27 Javascript
layui实现三级联动效果
2019/07/26 Javascript
node 解析图片二维码的内容代码实例
2019/09/11 Javascript
node.js 基于 STMP 协议和 EWS 协议发送邮件
2021/02/14 Javascript
[41:41]TFT vs Secret Supermajor小组赛C组 BO3 第一场 6.3
2018/06/04 DOTA
Python安装Imaging报错:The _imaging C module is not installed问题解决方法
2014/08/22 Python
python爬虫爬取网页表格数据
2018/03/07 Python
python人民币小写转大写辅助工具
2018/06/20 Python
python提取具有某种特定字符串的行数据方法
2018/12/11 Python
python3用PIL把图片转换为RGB图片的实例
2019/07/04 Python
Python 依赖库太多了该如何管理
2019/11/08 Python
pytorch实现focal loss的两种方式小结
2020/01/02 Python
澳大利亚票务和娱乐市场领导者:Ticketmaster
2017/03/03 全球购物
南京某软件公司的.net面试题
2015/11/30 面试题
2014教师研修学习体会
2014/07/08 职场文书
水电施工员岗位职责
2015/04/11 职场文书
志愿者工作心得体会
2016/01/15 职场文书
SSM项目使用拦截器实现登录验证功能
2022/01/22 Java/Android
SQL Server数据库基本概念、组成、常用对象与约束
2022/03/20 SQL Server