依赖包
需要安装以下这两个依赖包 js-table2excel 用于文件导出 xlsx 用于文件导入
npm i js-table2excel
npm i xlsx
文件导出
type值 | 对应值 |
text | 文本类型 |
image | 图片类型可写宽和高 |
如果做文件的小批量导出不用转换base64 直接用http url即可 文件量或者图片过大可能会出现加载失败的情况 避免这个问题 是跑all方法去请求url资源转换成base64 再渲染就能够全部导出 转base64的时候做了一个图片压缩 不需要的可以去掉
async getphoto() {
const column = [
{
title: 'ID',
key: 'id',
type: 'text'
},
{
title: '标准图片',
key: 'img-base64',
type: 'image',
width: 200,
height: 100
},
{
title: '标准图片地址',
key: 'img',
type: 'text',
},
]
const data = _.cloneDeep(this.tableData);
var datas = await this.Format(data)
const excelName = '文件名字'
console.log(datas, 'xxxy')
table2excel(column, datas, excelName) //生成Excel表格,自动下载
},
async Format(res1) {
this.startLoading()
var list = res1
let cytlist = []
let cytlistindex = []
for (let index = 0; index < list.length; index++) {
let tp1 = list[index]["img"]
if (tp1 && tp1.includes('range_file')) {
//我这里后台给的图片路径不全需要我自己拼一下 不用拼的直接写地址就行了
cytlist.push(await this.toBase64(this.mybaseUrl + '/media/' + tp1))
list[index]["img"] = this.mybaseUrl + '/media/' + tp1
cytlistindex.push(index)
}
}
await Promise.all(cytlist).then(res => {
for (let index = 0; index < cytlistindex.length; index++) {
list[cytlistindex[index]]["img-base64"] = res[index]
}
})
return list;
},
getBase64(url, callback) {
let _that = this
var Img = new Image(),
dataURL = '';
Img.src = url + "?v=" + Math.random();
Img.setAttribute("crossOrigin", 'Anonymous')
Img.onload = function () {
var canvas = document.createElement("canvas"),
width = Img.width,
height = Img.height;
if (Math.max(width, height) > _that.maximg) {
if (width > height) {
canvas.width = _that.maximg;
canvas.height = _that.maximg * height / width
} else {
canvas.height = _that.maximg
canvas.width = _that.maximg * width / height
}
} else {
canvas.width = width;
canvas.height = height;
}
canvas.getContext("2d").drawImage(Img, 0, 0, canvas.width, canvas.height);
dataURL = canvas.toDataURL('image/jpeg');
callback ? callback(dataURL) : null;
};
},
toBase64(url) {
return new Promise((resolve, reject) => {
this.getBase64(url, (data) => {
resolve(data)
})
})
},
文件导入
代码中掺杂着文本匹配Id 的逻辑 不需要的可以忽略 #@是个人习惯 可以换成别的 表格头文本描述和字段值的分隔符
const xlsx = require("xlsx");
async onChange(file) {
/**
* 1. 使用原生api去读取好的文件
* */
// console.log("原始上传的文件", file);
// 读取文件不是立马能够读取到的,所以是异步的,使用Promise
let dataBinary = await new Promise((resolve) => {
// Web API构造函数FileReader,可实例化对象,去调用其身上方法,去读取解析文件信息
let reader = new FileReader(); // https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader
// console.log("实例化对象有各种方法", reader);
reader.readAsBinaryString(file.raw); // 读取raw的File文件
reader.onload = (ev) => {
// console.log("文件解析流程进度事件", ev);
resolve(ev.target.result); // 将解析好的结果扔出去,以供使用
};
});
// console.log(dataBinary,'xxx')
// console.log("读取出的流文件", dataBinary);
/**
* 2. 使用xlsx插件去解析已经读取好的二进制excel流文件
* */
let workBook = xlsx.read(dataBinary, { type: "binary", cellDates: true });
// excel中有很多的sheet,这里取了第一个sheet:workBook.SheetNames[0]
let firstWorkSheet = workBook.Sheets[workBook.SheetNames[0]];
// 分为第一行的数据,和第一行下方的数据
const header = this.getHeaderRow(firstWorkSheet);
// console.log("读取的excel表头数据(第一行)", header);
const data = xlsx.utils.sheet_to_json(firstWorkSheet);
const datayy = xlsx.utils.sheet_to_formulae(firstWorkSheet);
//console.log(xlsx,'看看xlsx',datayy)
//console.log("读取所有excel数据", data);
let res = []
let obj1 = Object.keys(this.viewoptions)
let res1 = []
//设置导出的模版时将表格头用#@分隔 这个看个人习惯 然后我这里还做了一个表格内容文本匹配id 不需要的可以忽略
for (let i = 0; i < data.length; i++) {
let str = {}
let notfindid = false
for (let j = 0; j < header.length; j++) {
if (header[j].includes('#@')) {
let temp = header[j].split('#@')
if (temp.length == 2) {
let idxmy = obj1.indexOf(temp[1])
if (idxmy != -1) {
let tttc = this.viewoptions[`${obj1[idxmy]}`][`${data[i][header[j]]}`]
// console.log(this.viewoptions[`${obj1[idxmy]}`], 'ycta', data[i][header[j]])
if (tttc) {
str[temp[1]] = tttc
//notfindid=false
} else {
str[temp[1]] = data[i][header[j]]
notfindid = true
}
} else {
str[temp[1]] = data[i][header[j]]
}
if (temp[1] == 'standard_pic') {
if (data[i][header[j]] == 'null' || !data[i][header[j]]) {
str[temp[1]] = undefined
}
}
} else {
continue
}
}
}
str.notfindid = notfindid
if (!notfindid) {
res1.push(str)
}
if (data.length == ansimg.length) {
//alert(1)
str.standard_pic = ansimg[i]
}
res.push(str)
}
this.tableData = res
this.resdata = res1
},
getHeaderRow(sheet) {
const headers = []; // 定义数组,用于存放解析好的数据
const range = xlsx.utils.decode_range(sheet["!ref"]); // 读取sheet的单元格数据
let C;
const R = range.s.r;
/* start in the first row */
for (C = range.s.c; C <= range.e.c; ++C) {
/* walk every column in the range */
const cell = sheet[xlsx.utils.encode_cell({ c: C, r: R })];
/* find the cell in the first row */
let hdr = "UNKNOWN " + C; // <-- replace with your desired default
//console.log(hdr, C, 'popo')
//let tempheader
if (cell && cell.t) {
hdr = xlsx.utils.format_cell(cell);
/* tempheader=hdr.split('#@')
if(tempheader.length==2){
hdr=tempheader[1]
}*/
}
headers.push(hdr);
}
return headers; // 经过上方一波操作遍历,得到最终的第一行头数据
},