导出
导入
{{ errorMsg }}
确认
varXLSX=require('xlsx')
exportdefault{
name:'ProgExportImport',
data() {return{
fullscreenLoading:false,//加载中
imFile:'',//导入文件el对象
outFile:'',//导出文件el对象
errorDialog:false,//错误信息弹窗
errorMsg:'',//错误信息内容
excelTitle: {},//excel标题
excelData: []//excel处理数据
}
},
props: {
setExportData: {
type: Function,default:function() {
console.warn('未传递获取excel导出数据方法')
}
},
getImportData: {
type: Function,default:function() {
console.warn('未传递设置excel导入数据方法')
}
}
},
mounted() {this.imFile=document.getElementById('imFile')this.outFile=document.getElementById('downlink')
},
methods: {
uploadFile:function() {//导入文件点击事件
this.imFile.click()
},
downloadFile:function() {//导出文件点击事件
let exportData= this.setExportData()this.excelTitle=exportData.excelTitlethis.excelData=exportData.excelData
let data=[{},{}]for(let kin this.excelData[0]) {//设置第1行为数据库字段行
if(this.excelData[0].hasOwnProperty(k)) {
data[0][k]=k
data[1][k]= this.excelTitle[k]//中文标题
}
}
data=data.concat(this.excelData)this.downloadExl(data, exportData.excelName|| '导出文件')
},
importFile:function() {//导入excel
this.fullscreenLoading= truelet obj= this.imFileif(!obj.files) {this.fullscreenLoading= false
return}varf=obj.files[0]varreader= newFileReader()
let $t= thisreader.οnlοad= function(e) {vardata=e.target.resultif($t.rABS) {
$t.wb=XLSX.read(btoa(this.fixdata(data)), {//手动转化
type:'base64'})
}else{
$t.wb=XLSX.read(data, {
type:'binary'})
}
let json=XLSX.utils.sheet_to_json($t.wb.Sheets[$t.wb.SheetNames[0]])
$t.dealFile($t.analyzeData(json))//analyzeData: 解析导入数据
}if(this.rABS) {
reader.readAsArrayBuffer(f)
}else{
reader.readAsBinaryString(f)
}
},
downloadExl:function(json, downName, type) {//导出到excel
let keyMap=[]//获取键
for(let kinjson[0]) {if(json[0].hasOwnProperty(k)) {
keyMap.push(k)
}
}
let tmpdata=[]//用来保存转换好的json
json.map((v, i)=>keyMap.map((k, j)=>Object.assign({}, {
v: v[k]|| '',
position: (j> 25 ? this.getCharCol(j) : String.fromCharCode(65 +j))+(i+ 1)
}))).reduce((prev, next)=>prev.concat(next)).forEach(function(v) {
tmpdata[v.position]={
v: v.v
}
})
let outputPos=Object.keys(tmpdata)//设置区域,比如表格从A1到D10
let tmpWB={
SheetNames: ['sheet'],//保存的表标题
Sheets: {'sheet': Object.assign({},
tmpdata,//内容
{'!ref': outputPos[0]+ ':' +outputPos[outputPos.length- 1]//设置填充区域
})
}
}
let tmpDown= newBlob([this.s2ab(XLSX.write(tmpWB,
{ bookType: (type|| 'xlsx'), bookSST:false, type:'binary'}//这里的数据是用来定义导出的格式类型
))], {
type:''})//创建二进制对象写入转换好的字节流
varhref=URL.createObjectURL(tmpDown)//创建对象超链接
this.outFile.download=downName+ '.xlsx' //下载名称
this.outFile.href=href//绑定a标签
this.outFile.click()//模拟点击实现下载
setTimeout(function() {//延时释放
URL.revokeObjectURL(tmpDown)//用URL.revokeObjectURL()来释放这个object URL
},100)
},
analyzeData:function(data) {//此处可以解析导入数据
data.splice(0,1)//去除第二行(中文标题行)
returndata
},
dealFile:function(data) {//处理导入的数据
this.imFile.value= ''
this.fullscreenLoading= false
if(data.length<= 0) {this.errorDialog= true
this.errorMsg= '请导入正确信息'}else{this.excelData=datathis.getImportData(data)
}
},
s2ab:function(s) {//字符串转字符流
varbuf= newArrayBuffer(s.length)varview= newUint8Array(buf)for(vari= 0; i!==s.length;++i) {
view[i]=s.charCodeAt(i)& 0xFF}returnbuf
},
getCharCol:function(n) {//将指定的自然数转换为26进制表示。映射关系:[0-25] -> [A-Z]。
let s= ''let m= 0
while(n> 0) {
m=n% 26 + 1s=String.fromCharCode(m+ 64)+s
n=(n-m)/ 26}returns
},
fixdata:function(data) {//文件流转BinaryString
varo= ''
varl= 0
varw= 10240
for(; l
o+=String.fromCharCode.apply(null,newUint8Array(data.slice(l*w, l*w+w)))
}
o+=String.fromCharCode.apply(null,newUint8Array(data.slice(l*w)))returno
}
}
}