前端 vue/react 或者 js 导入/导出 xlsx/xls (带样式)表格的功能
第一种
导出表格的功能:
- yarn add xlsx script-loader file-saver xlsx-style
效果展示
- xlsx-style的bug修复:node_module/xlsx-style/dist/cpexcel.js的807行的var cpt = require('./cpt' + 'able')改为var cpt = cptable;
上封装的代码:
- require('script-loader!file-saver');
- import XLSX from 'xlsx-style';
- import XLSX2 from 'xlsx';
- function datenum(v, date1904) {
- if (date1904) v += ;
- var epoch = Date.parse(v);
- return (epoch - new Date(Date.UTC(, , ))) / ( * * * );
- }
- function sheet_from_array_of_arrays(data, opts) {
- var ws = {};
- var range = {
- s: {
- c: ,
- r:
- },
- e: {
- c: ,
- r:
- }
- };
- for (var R = ; R != data.length; ++R) {
- for (var C = ; C != data[R].length; ++C) {
- if (range.s.r > R) range.s.r = R;
- if (range.s.c > C) range.s.c = C;
- if (range.e.r < R) range.e.r = R;
- if (range.e.c < C) range.e.c = C;
- var cell = {
- v: data[R][C]
- };
- if (cell.v == null) continue;
- var cell_ref = XLSX.utils.encode_cell({
- c: C,
- r: R
- });
- if (typeof cell.v === 'number') cell.t = 'n';
- else if (typeof cell.v === 'boolean') cell.t = 'b';
- else if (cell.v instanceof Date) {
- cell.t = 'n';
- cell.z = XLSX.SSF._table[];
- cell.v = datenum(cell.v);
- } else cell.t = 's';
- ws[cell_ref] = cell;
- }
- }
- if (range.s.c < ) ws['!ref'] = XLSX.utils.encode_range(range);
- return ws;
- }
- function Workbook() {
- if (!(this instanceof Workbook)) return new Workbook();
- this.SheetNames = [];
- this.Sheets = {};
- }
- function s2ab(s) {
- var buf = new ArrayBuffer(s.length);
- var view = new Uint8Array(buf);
- for (var i = ; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
- return buf;
- }
- // 通过table标签渲染导出表格
- export function export_table_to_excel({
- id,
- filename,
- bookType = 'xlsx',
- styleFun
- } = {}) {
- var table = document.querySelector(id);
- var ws = XLSX2.utils.table_to_sheet(table);
- styleFun(ws);
- var wb = XLSX2.utils.book_new();
- XLSX2.utils.book_append_sheet(wb, ws, "SheetJS");
- var wbout = XLSX.write(wb, {
- bookType: bookType,
- bookSST: false,
- type: 'binary'
- });
- function s2ab(s) {
- var buf = new ArrayBuffer(s.length);
- var view = new Uint8Array(buf);
- for (var i = ; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
- return buf;
- }
- saveAs(new Blob([s2ab(wbout)], { type: "" }), filename + "." + bookType)
- }
- //通过json渲染导出表格
- export function export_json_to_excel({
- multiHeader = [],
- header,
- data,
- filename,
- merges = [],
- autoWidth = true,
- bookType = 'xlsx'
- } = {}) {
- /* original data */
- filename = filename || 'excel-list'
- data = [...data]
- data.unshift(header);
- for (let i = multiHeader.length - ; i > -; i--) {
- data.unshift(multiHeader[i])
- }
- var ws_name = "SheetJS";
- var wb = new Workbook(),
- ws = sheet_from_array_of_arrays(data);
- if (merges.length > ) {
- if (!ws['!merges']) ws['!merges'] = [];
- merges.forEach(item => {
- ws['!merges'].push(XLSX.utils.decode_range(item))
- })
- }
- if (autoWidth) {
- /*设置worksheet每列的最大宽度*/
- const colWidth = data.map(row => row.map(val => {
- /*先判断是否为null/undefined*/
- if (val == null) {
- return {
- 'wch':
- };
- }
- /*再判断是否为中文*/
- else if (val.toString().charCodeAt() > ) {
- return {
- 'wch': val.toString().length *
- };
- } else {
- return {
- 'wch': val.toString().length
- };
- }
- }))
- /*以第一行为初始值*/
- let result = colWidth[];
- for (let i = ; i < colWidth.length; i++) {
- for (let j = ; j < colWidth[i].length; j++) {
- if (result[j]['wch'] < colWidth[i][j]['wch']) {
- result[j]['wch'] = colWidth[i][j]['wch'];
- }
- }
- }
- ws['!cols'] = result;
- }
- /* add worksheet to workbook */
- wb.SheetNames.push(ws_name);
- wb.Sheets[ws_name] = ws;
- var wbout = XLSX.write(wb, {
- bookType: bookType,
- bookSST: false,
- type: 'binary'
- });
- saveAs(new Blob([s2ab(wbout)], {
- type: "application/octet-stream"
- }), `${filename}.${bookType}`);
- }
提供了2种调用方式:
1.直接获取table标签获取
- exportTable() {
- //通过table标签渲染导出表格
- import("@/vendor/Export2Excel").then(excel => {
- excel.export_table_to_excel({
- id: this.id,
- filename: this.filename,
- bookType: this.bookType,
- styleFun: function(ws) { // 自定义样式
- for (let item in ws) {
- switch (item) {
- case "!merges":
- break;
- case "!ref":
- break;
- case "A1":
- ws['A1'].s = {
- font: {
- sz: ,
- bold: true,
- color: {
- rgb: "FFFFAA00"
- }
- },
- alignment: {
- horizontal: "center",
- vertical: "center"
- }
- };
- break;
- default:
- ws[item].s = {
- font: {
- sz: ,
- bold: true,
- },
- alignment: {
- horizontal: "center",
- vertical: "center"
- }
- };
- }
- }
- }
- });
- });
- },
2.通过后台数据data数组
- exportTable() {
- import("@/vendor/Export2Excel").then(excel => {
- const multiHeader = [
- [
- "工作情况一览表",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- ""
- ],
- [
- "截止日期:2019年09月11日",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- ""
- ]
- ];
- const tHeader = [
- "序号",
- "分类",
- "报建项目",
- "有效期",
- "计划开始时间",
- "计划完成时间",
- "受理",
- "所需资料",
- "办理周期",
- "责任人",
- "工作进展"
- ];
- const filterVal = [
- "code",
- "name",
- "orderBy",
- "pageviews",
- "display_time"
- ];
- const list = this.tableData;
- const data = this.formatJson(filterVal, list);
- const merges = ['A1:K1','A2:K2']; // 合并单元格
- excel.export_json_to_excel({
- multiHeader,
- header: tHeader,
- merges,
- data,
- filename: this.filename,
- autoWidth: this.autoWidth,
- bookType: this.bookType
- });
- });
- },
- // 辅助导出表格的函数
- formatJson(filterVal, jsonData) {
- return jsonData.map(v =>
- filterVal.map(j => {
- if (j === "timestamp") {
- return parseTime(v[j]);
- } else {
- return v[j];
- }
- })
- );
- },
对应的html就是element的table
- <div id="protable">
- <el-table :data="tableData" :span-method="objectSpanMethod" border style="width: 100%; margin-top: 20px">
- <el-table-column label="工作情况一览表" align="center">
- <el-table-column label="截止日期:2019年09月11日" align="right">
- <el-table-column prop="id" label="序号" align="center">
- </el-table-column>
- <el-table-column prop="code" label="分类" align="center">
- </el-table-column>
- <el-table-column prop="name" label="报建项目" align="center">
- </el-table-column>
- <el-table-column prop="amount2" label="有效期" align="center">
- </el-table-column>
- <el-table-column prop="amount3" label="计划开始时间" align="center">
- </el-table-column>
- <el-table-column prop="amount3" label="计划完成时间" align="center">
- </el-table-column>
- <el-table-column prop="amount3" label="受理" align="center">
- </el-table-column>
- <el-table-column prop="amount3" label="所需资料" align="center">
- </el-table-column>
- <el-table-column prop="amount3" label="办理周期" align="center">
- </el-table-column>
- <el-table-column prop="amount3" label="责任人" align="center">
- </el-table-column>
- <el-table-column prop="amount3" label="工作进展概述" align="center">
- </el-table-column>
- </el-table-column>
- </el-table-column>
- </el-table>
- </div>
第二种
- // 导出Excel方法(表格id,不加扩展名的文件名,sheet名)
- export function exportExcelMethod(tableId, fileName, sheetName) {
- tableToExcel(tableId, fileName, sheetName)
- }
- const tableToExcel = (function() {
- const uri = 'data:application/vnd.ms-excel;base64,'
- // 设置导出表格的单元格默认高度/宽度/边框样式/字体颜色/背景颜色/居中,网页显示表格宽度建议1240,tr/td视情况而定
- const template = `<html xmlns:x="urn:schemas-microsoft-com:office:excel"><head><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><meta charset="UTF-8"><style type="text/css">table td {border: 1px solid #;width:100px;text-align: center;color: #;} th {border: 1px solid #;width:100px;text-align: center;color: #;}</style></head><body><table>{table}</table></body></html>`
- const base64 = function(s) { return window.btoa(unescape(encodeURIComponent(s))) }
- const format = function(s, c) { return s.replace(/{(\w+)}/g, function(m, p) { return c[p] }) }
- return function(table, filename, sheetname) {
- if (!table.nodeType) table = document.getElementById(table)
- const ctx = { worksheet: sheetname || 'Worksheet', table: table.innerHTML }
- const aTag = document.createElement('a')
- aTag.href = uri + base64(format(template, ctx))
- aTag.download = filename
- aTag.click()
- }
- })()
- import { exportExcelMethod } from './exportExcel'
- <table id="table" class="tg" style="table-layout: fixed; width: 1228px;margin: auto;left: 50%;right: 50%">
- <tr>
<th style="background-color: red; height: 60px;" colspan="6">Header 1</th>
</tr>
<tr>
<th style="background-color: red">Header 1</th>
<th style="background-color: red">Header 1</th>
<th style="background-color: red">Header 1</th>
<th style="background-color: red">Header 1</th>
<th style="background-color: red">Header 1</th>
<th style="background-color: red">Header 1</th>
</tr>
<tr>
<td>row 1, cell 1</td>
<td>row 1, cell 2</td>
<td>row 1, cell 1</td>
<td>row 1, cell 2</td>
<td>row 1, cell 1</td>
<td>row 1, cell 2</td>
</tr>
<tr>
<td>row 1, cell 1</td>
<td>row 1, cell 2</td>
<td>row 1, cell 1</td>
<td>row 1, cell 2</td>
<td>row 1, cell 1</td>
<td>row 1, cell 2</td>
</tr>
<tr>
<td>row 1, cell 1</td>
<td>row 1, cell 2</td>
<td>row 1, cell 1</td>
<td>row 1, cell 2</td>
<td>row 1, cell 1</td>
<td>row 1, cell 2</td>
</tr>
<tr>
<td>row 1, cell 1</td>
<td>row 1, cell 2</td>
<td>row 1, cell 1</td>
<td>row 1, cell 2</td>
<td>row 1, cell 1</td>
<td>row 1, cell 2</td>
</tr>
- </table>
- exportExcelMethod('table', '发货单', 'sheet1')
前端 vue/react 或者 js 导入/导出 xlsx/xls (带样式)表格的功能的更多相关文章
- 使用VUE+SpringBoot+EasyExcel 整合导入导出数据
使用VUE+SpringBoot+EasyExcel 整合导入导出数据 创建一个普通的maven项目即可 项目目录结构 1 前端 存放在resources/static 下 index.html &l ...
- vue+element-ui的简洁导入导出功能
1.前段后台管理系统中数据展示一般都是用表格,表格会涉及到导入和导出;原生js导出excel2.导入是利用element-ui的Upload 上传组件; <el-upload class=&qu ...
- Vue框架下实现导入导出Excel、导出PDF
项目需求:开发一套基于Vue框架的工程档案管理系统,用于工程项目资料的填写.编辑和归档,经调研需支持如下功能: Excel报表的导入.导出 PDF文件的导出 打印表格 经过技术选型,项目组一致决定通过 ...
- React Native的导入导出
1.组件的导入导出方式 问1:如何导出一个组件? export default class EIComponent extends Component{ render(){ return( <T ...
- NPOI 操作数据库中数据的导入导出(Excel.xls文件) 和null数据的处理。
App.config: <?xml version="1.0" encoding="utf-8" ?> <configuration> ...
- 使用NPOI导入导出Excel(xls/xlsx)数据到DataTable中
using System; using System.Collections.Generic; using System.Text; using System.IO; using NPOI.SS.Us ...
- winfrom 使用NPOI导入导出Excel(xls/xlsx)数据到DataTable中
1.通过NUGET管理器下载nopi,在引入命令空间 using System; using System.Collections.Generic; using System.Text; using ...
- js导入导出excel
导入: <html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>Unti ...
- JS导入导出Excel表格的方法
https://blog.csdn.net/aa122273328/article/details/50388673 导出 https://blog.csdn.net/qq_37281252/arti ...
随机推荐
- Swift 构造过程
构造过程是为了使用某个类.结构体或枚举类型的实例而进行的准备过程.这个过程包含了为实例中的每个属性设置初始值和为其执行必要的准备和初始化任务. Swift 构造函数使用 init() 方法. 与 Ob ...
- kotlin之函数的基本用法
fun main(arg: Array<String>) { val )//调用函数 print(double) } fun double(x:Int):Int{ *x } kotlin函 ...
- Python使用hashlib模块做字符串加密
#-*- encoding:gb2312 -*- import hashlib a = "a test string" print 'md5 = %s' % (hashlib.md ...
- C#使用CUDA
随着信息处理的爆炸增长,传统使用CPU计算已经无法满足计算作业增长的需求,GPU的出现为批量作业提供了新的契机.GPU计算拥有很类库,比如CUDA.OpenCL等,但是可以发现CUDA是其中相对比较成 ...
- 修改阿里源为Ubuntu 18.04默认的源
步骤如下: Step1:备份/etc/apt/sources.list sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak Step2:在/ ...
- 【miscellaneous】使用Google语音识别引擎(Google Speech API)[3月5日修改]
原文:http://blog.csdn.net/dlangu0393/article/details/7214728#comments 近期重写本文,暂时禁止评论. 最近在使用Qt编写一个客户端程序的 ...
- BootStrap Table方法使用小结
参考链接:https://www.cnblogs.com/Amaris-Lin/p/7797920.html
- eNSP——Hybrid接口的应用
原理: Hybrid接口既可以连接普通终端的接入链路又可以连接交换机间的干道链路,它允许多个VLAN的帧通过,并可以在出接口方向将某些VLAN帧的标签剥掉. Hybrid接口处理VLAN帧的过程如下: ...
- HashMap集合-遍历方法
# HashMap集合-遍历方法 先定义好集合: public static void main(String[] args) { Map<String,String> onemap=ne ...
- (十四)mybatis 和 spring 整合
目录 整合思想 整合步骤 整合之后原始 dao 开发 整合之后 Mapper 代理开发 总结 整合思想 让 spring 管理 sqlSessionFactory ,使用 单例模式 创建该对象 : 根 ...