一、导出
1、安装
npm install -S xlsx@0.14.1
npm install -D script-loader
npm install -S file-saver
注意:xlsx版本不要安装错了~~~
2、创建utils文件夹,里面新建excel.js文件,下面代码直接复制到excel.js文件即可
/* eslint-disable */
require('script-loader!file-saver')
import XLSX from 'xlsx'
function generateArray(table) {
var out = []
var rows = table.querySelectorAll('tr')
var ranges = []
for (var R = 0; R < rows.length; ++R) {
var outRow = []
var row = rows[R]
var columns = row.querySelectorAll('td')
for (var C = 0; C < columns.length; ++C) {
var cell = columns[C]
var colspan = cell.getAttribute('colspan')
var rowspan = cell.getAttribute('rowspan')
var cellValue = cell.innerText
if (cellValue !== '' && cellValue == +cellValue) cellValue = +cellValue
//Skip ranges
ranges.forEach(function (range) {
if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e.c) {
for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null)
}
})
//Handle Row Span
if (rowspan || colspan) {
rowspan = rowspan || 1
colspan = colspan || 1
ranges.push({
s: {
r: R,
c: outRow.length,
},
e: {
r: R + rowspan - 1,
c: outRow.length + colspan - 1,
},
})
}
//Handle Value
outRow.push(cellValue !== '' ? cellValue : null)
//Handle Colspan
if (colspan) for (var k = 0; k < colspan - 1; ++k) outRow.push(null)
}
out.push(outRow)
}
return [out, ranges]
}
function datenum(v, date1904) {
if (date1904) v += 1462
var epoch = Date.parse(v)
return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000)
}
function sheet_from_array_of_arrays(data, opts) {
var ws = {}
var range = {
s: {
c: 10000000,
r: 10000000,
},
e: {
c: 0,
r: 0,
},
}
for (var R = 0; R != data.length; ++R) {
for (var C = 0; 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
console.log(XLSX)
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[14]
cell.v = datenum(cell.v)
} else cell.t = 's'
ws[cell_ref] = cell
}
}
if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range)
return ws
}
export class Workbook {
constructor() {
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 = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xff
return buf
}
export function export_table_to_excel(id) {
var theTable = document.getElementById(id)
var oo = generateArray(theTable)
var ranges = oo[1]
/* original data */
var data = oo[0]
var ws_name = 'SheetJS'
var wb = new Workbook(),
ws = sheet_from_array_of_arrays(data)
/* add ranges to worksheet */
// ws['!cols'] = ['apple', 'banan'];
ws['!merges'] = ranges
/* add worksheet to workbook */
wb.SheetNames.push(ws_name)
wb.Sheets[ws_name] = ws
var wbout = XLSX.write(wb, {
bookType: 'xlsx',
bookSST: false,
type: 'binary',
})
saveAs(
new Blob([s2ab(wbout)], {
type: 'application/octet-stream',
}),
'test.xlsx'
)
}
export function export_json_to_excel({ header, data, filename, autoWidth = true, bookType = 'xlsx' } = {}) {
/* original data */
filename = filename || 'excel-list'
data = [...data]
data.unshift(header)
var ws_name = 'SheetJS'
var wb = new Workbook(),
ws = sheet_from_array_of_arrays(data)
if (autoWidth) {
/*设置worksheet每列的最大宽度*/
const colWidth = data.map((row) =>
row.map((val) => {
/*先判断是否为null/undefined*/
if (val == null) {
return {
wch: 10,
}
} else if (val.toString().charCodeAt(0) > 255) {
/*再判断是否为中文*/
return {
wch: val.toString().length * 2,
}
} else {
return {
wch: val.toString().length,
}
}
})
)
/*以第一行为初始值*/
let result = colWidth[0]
for (let i = 1; i < colWidth.length; i++) {
for (let j = 0; 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}`
)
}
export const renderSheetArea = (header, data, autoWidth = true) => {
data.unshift(header)
const transToSheetData = sheet_from_array_of_arrays(data)
if (autoWidth) {
/*设置worksheet每列的最大宽度*/
const colWidth = data.map((row) =>
row.map((val) => {
/*先判断是否为null/undefined*/
if (val == null) {
return {
wch: 10,
}
} else if (val.toString().charCodeAt(0) > 255) {
/*再判断是否为中文*/
return {
wch: val.toString().length * 2,
}
} else {
return {
wch: val.toString().length,
}
}
})
)
/*以第一行为初始值*/
let result = colWidth[0]
for (let i = 1; i < colWidth.length; i++) {
for (let j = 0; j < colWidth[i].length; j++) {
if (result[j]['wch'] < colWidth[i][j]['wch']) {
result[j]['wch'] = colWidth[i][j]['wch']
}
}
}
transToSheetData['!cols'] = result
}
return transToSheetData
}
/**
* @name 写入数据到excel
* @param {WorkBook} workbook
* @param {string} filename
* */
export const writeDataToExcel = (workbook, filename) => {
const workBookOut = XLSX.write(workbook, {
bookType: 'xlsx',
bookSST: false,
type: 'binary',
})
saveAs(
new Blob([s2ab(workBookOut)], {
type: 'application/octet-stream',
}),
`${filename}.xlsx`
)
}
3、前端vue代码如下(纯导出代码)
<template>
<div>
<el-button size="mini" type="primary" @click="exportTable">导出</el-button>
<el-table :data="list" :border = "true" align="center">
<el-table-column prop="index" label="序号" width="100" />
<el-table-column prop="type" label="调仓类型" />
<el-table-column prop="content" label="话术内容" />
</el-table>
</div>
</template>
<script>
import dayjs from 'dayjs'
export default {
data(){
return {
list:[{index:1,type:"调入",content:"上涨啊"},{index:2,type:"调入",content:"上涨啊"},
{index:3,type:"调出",content:"跌了"}],
}
},
methods:{
async exportTable(){
import('../utils/export2Excel').then(excel => {
const tHeader = ['调仓类型','话术内容']; //需要导出字段标题
const filterVal = ['type','content'] //需要导出的字段
const data = this.list.map((v) =>
filterVal.map((j) => {
console.log(j);
return v[j]
})
)
console.log(data);
excel.export_json_to_excel({
header:tHeader,
data,
filename:('导出记录') + dayjs().format('_YYYY-MM-DD_HH_mm_ss')
})
})
},
}
}
</script>
<style>
</style>
点击导出按钮即可导出excel表格
二、导入
1、在utils文件夹下创建util.js文件,写入以下代码,解析excel文件
import XLSX from 'xlsx'
export function readExcel(file) {
return new Promise(function (resolve, reject) {
const reader = new FileReader()
reader.readAsBinaryString(file)
reader.onload = (e) => {
try {
let data = e.target.result,workbook = XLSX.read(data,{type: 'binary'})
console.log(workbook);
const firstSheetName = workbook.SheetNames[0]
const worksheet = workbook.Sheets[firstSheetName]
const results = XLSX.utils.sheet_to_json(worksheet)
resolve(results)
}catch(e) {
console.log('进入catch');
reject(e.message)
}
}
reader.onerror = function (err) {
reject(err)
}
})
}
2、vue中导入readExcel(纯导入代码,不涉及导出)
<template>
<div>
导入excel表格
<el-upload class="upload-demo" :show-file-list="false" :before-upload="checkFileType" accept=".xlsx, .xls" action="https://jsonplaceholder.typicode.com/posts/" :http-request="uploadFile">
<el-button type="primary">导入</el-button>
<div slot="tip" class="el-upload_tip">请上传excel文件</div>
</el-upload>
<el-table :data="list" :border = "true" align="center">
<el-table-column prop="index" label="序号" width="100" type="index"/>
<el-table-column prop="type" label="调仓类型" width="200"/>
<el-table-column prop="content" label="话术内容" width="300"/>
</el-table>
</div>
</template>
<script>
import { readExcel } from '../utils/util'
export default {
data(){
return {
list:[]
}
},
methods:{
//检查是否为excel文件
checkFileType(file){
console.log('检查文件类型');
let fileName = file.name;
console.log(file);
if(['lsx','xls'].includes(fileName.slice(-3))){
console.log('格式正确');
this.uploadError = false
}else{
this.$message.error('只能上传excel文件!')
this.uploadError = true
}
},
// 上传文件
async uploadFile( { file }){
if(!file) return
try{
const fileText = await readExcel(file)
console.log(fileText);
for(const item in fileText){
let type = fileText[item]['调仓类型']
let content = fileText[item]['话术内容']
if(type && content) this.list.push({ type , content })
}
} catch(e) {
this.$message.error('上传错误')
}
}
}
}
</script>
<style>
</style>
此时导入一个excel文件,文件内容如下所示
const fileText = await readExcel(file)执行完后,打印出来的fileText格式如下所示
在此基础上进行调整,变换为需要的格式即可