1.xlsx简介

通俗的说,xlsx这个插件可以把html中的table元素或者json数据转换成表格后进行导出

<script src="https://cdn.bootcdn.net/ajax/libs/xlsx/0.17.4/xlsx.js"></script>

2.基本概念

一个excel文件就是一个book,一个book中又包含一个或多个sheet,以下方法均由XLSX.utils对象调用

常用方法 参数 说明
book_new - 创建一个空的book
table_to_book table元素(dom) 将table元素转换成 book
table_to_sheet table元素(dom) 将table元素转换成 sheet
json_to_sheet json数据(数组) 将json数据转换成 sheet
book_append_sheet 参数1:book对象,参数2:sheet对象,参数3:sheet名称 将sheet添加到book中
writeFile 参数1:book对象,参数2:导出的文件名称 导出表格文件

3.JSON转表格

  • 基本代码
 exportEvent () {
// 要打印的数据格式 对象中的key将会作为表头渲染
var print_data = [
{'序号':1,'姓名':'张三','年龄':20},
{'序号':2,'姓名':'李四','年龄':25},
{'序号':3,'姓名':'王五','年龄':30}
]
// 创建一个新sheet
const new_sheet = XLSX.utils.json_to_sheet(print_data)
// 设置每列的列宽(可选),10代表10个字符,注意中文占2个字符
new_sheet['!cols'] = [
{ wch: 10 },
{ wch: 30 },
{ wch: 25 }
]
// 新建book
const new_book = XLSX.utils.book_new()
// 将 sheet 添加到 book 中
XLSX.utils.book_append_sheet(new_book, new_sheet, '人员名单')
// 导出excel文件
XLSX.writeFile(new_book, '数据导出.xlsx')
}
  • 表头标题替换方法
replaceKeyForTableData(tableData = [],mapData = {}){
//要返回的最终数据
var result = []
//循环数组的每行数据
tableData.forEach(row=>{
//新的行数据
var new_row = {}
//循环每个键值
Object.keys(row).forEach(key=>{
//判断这个可以是否 可以在映色中找到对应的值 有则使用,无则使用原来的key
var new_key = mapData[key]? mapData[key]:key
//为新的行数据添加键值对
new_row[new_key] = row[key]
})
//新的行添加到表格数据中
result.push(new_row)
})
return result
}

4.HTML-table转表格

  • 导出原生表格:将table元素传入即可导出
//获取dom元素
var table_dom = document.querySelector('table')
//将dom转换为book
const new_book = XLSX.utils.table_to_book(table_dom)
// 导出excel文件 如导出后的文件不能打开,请将后缀替换为 .xls
XLSX.writeFile(new_book, '数据导出.xlsx')
  • 导出插件生成的表格:插件生成的表格因为兼容一些功能,最终渲染的时候其实是2个table元素,为了能将表格完整的导出(thead+body),需要手动拼接dom
//这里以vxe-table为例
exportEvent () {
// 创建新的table元素
var print_table_dom = document.createElement('table')
// copy一份thead
var print_table_dom_thead = this.$refs.p_table.$el.querySelector('.vxe-table--header-wrapper > .vxe-table--header thead').cloneNode(true)
// copy一份tbody
var print_table_body = this.$refs.p_table.$el.querySelector('.vxe-table--body-wrapper > .vxe-table--body tbody').cloneNode(true)
// 将thead和tbody添加到 目标table中
print_table_dom.appendChild(print_table_dom_thead)
print_table_dom.appendChild(print_table_body)
// 生成 book
const new_sheet = XLSX.utils.table_to_book(print_table_dom)
// 导出excel
XLSX.writeFile(new_sheet, '数据导出.xlsx')
},
  • 数字格式的问题:excel时,以0开头的数据,其开头0被忽略,如001234导出到excel后变为了1234,只需要将dom转换为book的时候,传入第二个参数即可
//将dom转换为book,传入第二个参数{raw:true}
const new_book = XLSX.utils.table_to_book(table_dom,{raw:true})

5.jsonToxlsx封装

  • 1.表格转换过程中,表头可能需要替换
  • 2.表格列宽动态设定
  • 3.20230906升级:导出表格列的顺序已表头信息配置为准,自动过滤表头没有的列(表头信息配置为空时,使用原逻辑)
  • 4.代码已上传至gitee
//此插件依赖xlsl.js
//@author zhoulianli 2022-04-15
//此插件主要用来导出表格数据,在xlsl.js基础上封装了列宽自适应,表头标题替换功能 //使用方法 jsonToxlsx(参数)
//参数1: 表格数据 [{},{}]
//参数2:可选,表头标题映射数据 {name:"姓名",age:"年龄"}
//参数3:可选,文件名 例如:"数据导出"
//参数4:可选,sheet名 例如:"能耗比数据" //闭包 传入当前环境的this
(function (global, factory) {
//1.先判断当前环境是否支持CommonJS规范(node.js)
if (typeof exports == 'object' && typeof module !== 'undefined') {
//console.log('CommonJS规范')
module.exports = factory()
} else if (typeof define == 'function' && define.amd) {//2.再判断是否支持AMD规范(require.js)
//console.log('AMD规范')
define(factory)
} else {
//console.log('script标签引入')
//接收该对象
this.jsonToxlsx = factory()
}
}(this,function(){
//将表格数组导出的方法
function jsonToxlsx(tableData = [],tHeadMap = {},fileName = "数据导出",sheetName = "数据导出"){
//判断依赖是否存在
if(typeof XLSX == undefined){
console.log('请先引入XLSX.js')
return
} //判断是否有表头信息
if(tHeadMap && Object.keys(tHeadMap).length > 0){
//转换数据格式2
var print_data = transFormTableData2(tableData,tHeadMap)
}else{
//转换数据格式1
var print_data = transFormTableData(tableData,tHeadMap)
} // 创建一个新sheet
const new_sheet = XLSX.utils.json_to_sheet(print_data) // 根据每列数据智能设定列宽
var two_dimensional_arr = transformToTwoDimensional(print_data)
var width_arr = two_dimensional_arr.map(arr=>{
return {
wch: getMaxLenByArr(arr) + 2
}
})
new_sheet['!cols'] = width_arr // 新建book
const new_book = XLSX.utils.book_new()
// 将 sheet 添加到 book 中
XLSX.utils.book_append_sheet(new_book, new_sheet, sheetName)
// 导出excel文件
XLSX.writeFile(new_book, `${fileName}${Moment().format('YYYYMMDDHHmmss')}.xlsx`)
} //转换表格数据
function transFormTableData(tableData = [],mapData = {}){
//要返回的最终数据
var result = []
//循环数组的每行数据
tableData.forEach(row=>{
//新的行数据
var new_row = {}
//循环每个键值
Object.keys(row).forEach(key=>{
//判断这个可以是否 可以在映色中找到对应的值 有则使用,无则使用原来的key
var new_key = mapData[key]? mapData[key]:key
//为新的行数据添加键值对
new_row[new_key] = row[key]
})
//新的行添加到表格数据中
result.push(new_row)
})
return result
} //转换表格数据2
//表格行的属性顺序和数量由表头配置来决定
function transFormTableData2(tableData = [],mapData = {}){
//要返回的最终数据
var result = []
//循环数组的每行数据
tableData.forEach(row=>{
//新的行数据
var new_row = {}
//循环表头每个键值
for(var key in mapData){
var target_key = mapData[key]
//给表格行添加字段
new_row[target_key] = row[key]
}
//新的行添加到表格数据中
result.push(new_row)
})
return result
} //将表格数组转换为二维数组 [[col1-1,col1-2],[col2-1,col2-2]]
function transformToTwoDimensional(tableData){
//如果数据源为空 则返回空
if (tableData == 0) {
return []
}
//对象有多少个key,就有多少列,每列数据是一个数组 //先填充标题
var result = []
for (key in tableData[0]) {
result.push([key])
} //接着填充数据
tableData.forEach(row => {
var index = 0
for (key in row) {
result[index].push(row[key])
index++
}
}) return result
} //从一维数组中提取出 最大的字节占位
function getMaxLenByArr(strArr){
var max = 0
strArr.forEach(item => {
//转为字符串
var str = item + ''
var strlen = 0;
for (var i = 0; i < str.length; i++) {
if (str.charCodeAt(i) > 255) //如果是汉字,则字符串长度加2
strlen += 2;
else
strlen++;
}
if( strlen > max){
max = strlen
}
})
return max
}
return jsonToxlsx;
}))

6.表格的导入

表格的导入一般经过几个步骤:

1.文件读取:借助文件域+H5的FileReader对文件进行读取

2.一次转码:使用XLSX对FileReader读取到的数据转换成bookData

3.二次转码:再借助vxe-table中的方法将上个步骤的数据转换成csvData

4.三次转码:将csvData转换为json数据

值得说明的是,前面三个步骤调用的都是浏览器或者插件现成的接口,而且也不会涉及业务层面的逻辑,所以我们不去动它。而第四步将csvData转换为json数据,目标json的数据格式需要根据业务来决定,所以第四步就值得探讨一番

我先说结论,csvData转换为json数据只能通过下标进行匹配,这也就意味着excel文件的列需要一个固定的格式,列的顺序一旦出错,导入就会有问题

这是excel表格数据:

这是转换后的csvData:

以下代码作为参考:

 data: {
tableColumn:[
{field:'id',title:'id'},
{field:'name',title:'姓名'},
{field:'role',title:'角色'},
{field:'sex',title:'性别'},
{field:'age',title:'年龄'},
{field:'address',title:'地址'}
],
tableData: [
{ id: 10001, name: 'Test1', role: 'Develop', sex: 'Man', age: 28, address: 'test abc' },
{ id: 10002, name: 'Test2', role: 'Test', sex: 'Women', age: 22, address: 'Guangzhou' },
{ id: 10003, name: 'Test3', role: 'PM', sex: 'Man', age: 32, address: 'Shanghai' },
{ id: 10004, name: 'Test4', role: 'Designer', sex: 'Women', age: 24, address: 'Shanghai' }
]
},
methods:{
//选择文件
fileChange(){
var file = document.querySelector('#file').files[0]
//如果文件存在 则读取
if(file){
//创建reader对象
var reader = new FileReader()
//读取选择的文件
reader.readAsBinaryString(file) //监听读取事件
var that = this
reader.onload = function(ev){
const data = ev.target.result
//转换book对象
const workbook = XLSX.read(data, { type: 'binary' })
//将某个sheet转换成csvData 注意 sheet 的名称
const csvData = XLSX.utils.sheet_to_csv(workbook.Sheets['Sheet1'])
that.tableData = that.csvToJson(csvData,that.tableColumn)
}
}
},
//将csv数据转换为json数据
csvToJson(csvData,tableColumn=[]){
//1.一般情况下,表格数据与tableColumn根据下标来进行匹配
//1.如果导入的表格有表头,则与表头与tableColumn进行匹配
const tableData = []
// 解析数据
csvData.split('\n').forEach((vRow) => {
//遍历行
if (vRow) {
const vCols = vRow.split(',')
const item = {}
//遍历列
vCols.forEach((val, cIndex) => {
//根据列的下标找到对应的 field
const column = tableColumn[cIndex]
if (column.field) {
//添加字段
item[column.field] = val
}
})
tableData.push(item)
}
})
return tableData
}
}

xlsx.js 表格的导出与导入的更多相关文章

  1. js中各种导出和导入

        exports和module exports的区别: exports是module exports的地址引用 export和export default的区别: export和export d ...

  2. JS导出、导入EXCEL(案例)

    插件下载地址:http://oss.sheetjs.com/js-xlsx/xlsx.full.min.js 1.导出excel <!DOCTYPE html> <html> ...

  3. html table表格导出excel的方法 html5 table导出Excel HTML用JS导出Excel的五种方法 html中table导出Excel 前端开发 将table内容导出到excel HTML table导出到Excel中的解决办法 js实现table导出Excel,保留table样式

    先上代码   <script type="text/javascript" language="javascript">   var idTmr; ...

  4. 十七 bootstrap-table tableExport 导出xlsx格式表格

    原文:十七 bootstrap-table tableExport 导出xlsx格式表格 在[十六.bootstrap-table javascript导出数据]中,打开导出的表格时,总会弹出一个提示 ...

  5. Vue+element UI实现表格数据导出Excel组件

    介绍 这是一个可以将页面中的表格数据导出为Excel文件的功能组件,该组件一般与表格一起使用,将表格数据传给组件,然后通过点击组件按钮可将表格中的数据导出成Excel文件. 使用方法 由于封装该组件内 ...

  6. [moka同学笔记]PHPexcel之excel导出和导入

    原案例来自http://www.sucaihuo.com/有修改 1.目录结构(文件不用解释,应该都可以看得懂,直接看代码)

  7. 将页面中表格数据导出excel格式的文件(vue)

    近期由于项目需要,需要将页面中的表格数据导出excel格式的文件,折腾了许久,在网上各种百度,虽然资料不少,但是大都不全,踩了许多坑,总算是皇天不负有心人,最后圆满解决了. 1.安装相关依赖(npm安 ...

  8. 如何使用免费控件将Word表格中的数据导入到Excel中

    我通常使用MS Excel来存储和处理大量数据,但有时候经常会碰到一个问题—我需要的数据存储在word表格中,而不是在Excel中,这样处理起来非常麻烦,尤其是在数据比较庞大的时候, 这时我迫切地需要 ...

  9. ES5和ES6对象导出和导入(转载,待整理)

    1.import ... form...替代 require() //不接收对象 require:require('s.css'); //(es5) improt 's.css' //(es6) // ...

  10. Elasticsearch的数据导出和导入操作(elasticdump工具),以及删除指定type的数据(delete-by-query插件)

    Elasticseach目前作为查询搜索平台,的确非常实用方便.我们今天在这里要讨论的是如何做数据备份和type删除.我的ES的版本是2.4.1. ES的备份,可不像MySQL的mysqldump这么 ...

随机推荐

  1. 合合信息扫描全能王亮相静安区3·15活动,AI扫描带来绿色消费新体验

    保护消费者的合法权益,是全社会的共同责任.为优化消费环境.促进品质消费高地建设,打造安全优质和谐的消费环境,上海静安区消保委于3月15日举办静安区2024年"3·15"国际消费者权 ...

  2. Windows平台下安装与配置MySQL9

    要在Windows平台下安装MySQL,可以使用图行化的安装包.图形化的安装包提供了详细的安装向导,以便于用户一步一步地完成对MySQL的安装.本节将详细介绍使用图形化安装包安装MySQL的方法. 1 ...

  3. 使用iis设置网站php版本为7.3

    内容:使用iis设置网站php版本为7.3这张图 是多少人的噩梦  早期的宝塔版本 没办法在线升级, php版本只能到7.1   默认就没有7.2以上版本   怎么办?可以在iis设置第一步: 第二步 ...

  4. 云原生爱好者周刊:揪出 Prometheus 中时间戳抖动

    开源项目推荐 O11y toolkit O11y toolkit 是一个工具集,用来维护.调试和增强你的可观测性系统,改善我们日常对指标.日志和链路追踪的使用体验.例如 oy-scrape-jitte ...

  5. 常见Linux查看文件、文本命令

    查看文件 find命令 按文件名 find 路径 -nmae "文件名" 按文件类型 find 路径 -type 类型 类型:普通文件 f 目录d 符号链接l 块设备文件b ​ 字 ...

  6. ToDesk云电脑游戏数量?高性能显卡云桌面

    玩游戏最怕遇到电脑配置跟不上,操作卡成狗不说,画面还一卡卡的,游戏体验极差. 最近被人安利了ToDesk的云电脑,可能是刚推出的,配置价格都很能打,浅用了一波拿来打APEX和荒野大镖客,体验有点惊喜到 ...

  7. Linux运行时动态库搜索路径优先级

    Windows运行时动态库搜索路径优先级: 在Windows运行时,动态库(通常指DLL文件)的搜索路径遵循一定的优先级顺序,以确保程序能够正确地加载所需的动态库.以下是对Windows运行时动态库搜 ...

  8. SpringBoot读取properties文件配置项

    使用SpringBoot开发过程中,难免需要配置相关数据项,然后在Java代码中@Autowired注入并使用. 我们应该如何读取properties文件中的配置项呢? 基于SpringBoot项目, ...

  9. TRLO: An Efficient LiDAR Odometry with 3D Dynamic Object Tracking and Removal

    arxiv | 中科院联合国科大开源 TRLO:一种结合3D动态物体跟踪与移除的高效LiDAR里程计 [TRLO: An Efficient LiDAR Odometry with 3D Dynami ...

  10. 管中窥豹----从String Intern中观察.NET Core到.NET 8 托管堆的变迁

    简介 https://www.cnblogs.com/lmy5215006/p/18494483 在此文中,研究.NET String底层结构时,我所观察到的情况与<.NET Core底层入门& ...