就vue來講:
第一步首先要下載xlsx
yarn add xlsx
yarn add xlsx-style
導入會用到的插件文件解析
yarn add worker-loader
yarn add uuid
下載好了過後,我們需要寫個解析的導入文件:命名爲xlsx.worker.js,然後需要引入到main.js中
xlsx.worker.js代碼附上:
import { read, utils } from 'xlsx'; self.onmessage = e => { const { file, id, keyMaps } = e.data; const reader = new FileReader(); reader.onload = e => { const workbook = read(e.target.result, {type: 'binary'}); const Sheets = workbook.Sheets; const list = Object.keys(Sheets).map((key, index) => { const list = utils.sheet_to_json(Sheets[key]); // 某張表的label和key的map const keyMap = keyMaps[index]; return list.map(item => { const row = {}; for (let key in item) { const column = keyMap[key]; const value = item[key]; if (column) { if (typeof column === 'string') { row[column] = value + ''; } else { const { type, key: prop } = column; if (type === 'number') { row[prop] = isNaN(value * 1) ? value : value * 1; } else { row[prop] = value; } } } else { // row[prop] = value; } } return row; }); }) self.postMessage({ id, list }); } reader.readAsArrayBuffer(file); }
把該文件引入到main.js中
import XLSXWorker from '@/workers/xlsx.worker'; Vue.prototype.$workers = { xlsx: new XLSXWorker() };
好了,這樣我們就完成引入部分了,就可以開始做導入功能了。
在.vue文件中寫導入和導出功能附上代碼:
<template> <a-modal title="商品導入" :width="1200" v-on="$listeners" :confirm-loading="loadingBtn" :visible="importVisible" @cancel="handleCancel" @ok="submitAdd"> <a-form-model :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }" style="padding: 0 0 0 20px;"> <BaseTitle title="設置商品" /> <a-row> <a-col :span="9"> <a-form-item :label-col="{ span: 4 }" :wrapper-col="{ span: 18 }"> <a-button type="link" class="right-a" @click="downloadTemplete">下載商品導入模板</a-button> <a-upload-dragger name="file" :file-list="fileList" :multiple="false" :beforeUpload="onBeforeUpload" accept=".xls,.xlsx,.xlsm" action=""> <div> <a-icon type="cloud-upload" style="font-size: 24px; color: @primary-color;" /> <p>點擊或拖拽商品文件導入</p> </div> </a-upload-dragger> </a-form-item> </a-col> </a-row> <BaseTitle title="導入結果" /> <a-row> <a-table :columns="columns" :data-source="tableData" size="small" /> </a-row> </a-form-model> </a-modal> </template> <script> import { columns } from '@/tables/goods/goodsImport'; import BaseTitle from '@/components/BaseTitle/index.vue' import {goodsService} from '@/service/index' import * as xlsx from 'xlsx'; import { v4 as uuid } from 'uuid'; const keyMaps = [ { '商品名稱(必填)': 'cnName', '倉庫id(必填)': 'warehouseId', '品牌id(必填)': 'brandId', '國家編碼(必填)': 'originCountryCode', '商品規格(必填)': 'goodsModel', '毛重(克)(必填)': { key: 'netWeight', type: 'number' }, '淨重(克)(必填)': { key: 'grossWeight', type: 'number' }, '幣種(必填)': 'currency', '條形碼(必填)': 'barCode', '到期時間(必填)': 'expirationDate', 'hsCode': 'hsCode', '銷售價格': { key: 'priceSales', type: 'number' }, '成本價格': { key: 'priceCost', type: 'number' }, '法定計量單位': 'unit', '商品配料': 'goodsComponent', '包裝類型': 'packageType' }, { '倉庫名稱': 'warehouseTitle', '倉庫編碼': 'id' }, { '品牌名稱': 'brandName', '倉庫編碼': 'brandId' }, { '國家': 'cnname', '國家編碼': 'isoNcode' }, { '幣種名稱': 'shortCnname', '幣種編碼': 'customsCode' }, { '計量單位': 'shortCnname', '計量單位編碼': 'customsCode' } ]; export default { components: { BaseTitle }, model: { prop: 'importVisible', event: 'change' }, props: { importVisible: {type: Boolean, default: false}, importData: {type:Object, default: ()=> ({})} }, data() { return { fileList: [], tableData: [], columns, rowSelection: {}, worderId: uuid(),//商品ID loadingBtn: false } }, mounted() { //導入數據解析結果監聽 this.$workers.xlsx.onmessage = res => { const { id, list } = res.data; if (id !== this.worderId) { return; } this.tableData = list[0]; } }, methods: { //下載商品導入模板 downloadTemplete() { //商品列表-sheet1 let newList = [{ '商品名稱(必填)': '', '倉庫id(必填)': '', '品牌id(必填)': '', '國家編碼(必填)': '', '商品規格(必填)': '', '毛重(克)(必填)': 0, '淨重(克)(必填)': 0, '幣種(必填)': '', '條形碼(必填)': '', '到期時間(必填)': '', 'hsCode': '', '銷售價格': 0, '成本價格': 0, '法定計量單位': '', '商品配料': '', '包裝類型': '' }] //倉庫對應編碼 const warehouseList = [] const warehouseName = { warehouseTitle: '倉庫名稱', id: '倉庫編碼' } // 轉換 if(this.importData.warehouseList.length) { this.importData.warehouseList.forEach(item=>{ let obj = {}; for(let key in item){ if(warehouseName[key]){ obj[warehouseName[key]] = item[key]; } } warehouseList.push(obj); }) } else { warehouseList.push({'倉庫名稱': '', '倉庫編碼': ''}); } //品牌對應編碼 const bransList = [] const brandName = { brandName: '品牌名稱', brandId: '品牌編碼' } // 轉換 if(this.importData.brandList.length) { this.importData.brandList.forEach(item=>{ let obj = {}; for(let key in item){ if(brandName[key]){ obj[brandName[key]] = item[key]; } } bransList.push(obj); }) } else { bransList.push({'品牌名稱': '', '品牌編碼': ''}); } //國家對應編碼 const countryList = [] const countryName = { cnname: '國家', isoNcode: '國家編碼' } // 轉換 if(this.importData.addressList.length) { this.importData.addressList.forEach(item=>{ let obj = {}; for(let key in item){ if(countryName[key]){ obj[countryName[key]] = item[key]; } } countryList.push(obj); }) } else { countryList.push({'國家': '', '國家編碼': ''}); } //幣種對應編碼 const currencyList = [] const currencyName = { shortCnname: '幣種名稱', customsCode: '幣種編碼' } // 轉換 if(this.importData.currencyList.length) { this.importData.currencyList.forEach(item=>{ let obj = {}; for(let key in item){ if(currencyName[key]){ obj[currencyName[key]] = item[key]; } } currencyList.push(obj); }) } else { currencyList.push({'幣種名稱': '', '幣種編碼': ''}); } //法定計量單位對應編碼 const unitList = [] const unitName = { shortCnname: '計量單位', customsCode: '計量單位編碼' } // 轉換 if(this.importData.unitList.length) { this.importData.unitList.forEach(item=>{ let obj = {}; for(let key in item){ if(unitName[key]){ obj[unitName[key]] = item[key]; } } unitList.push(obj); }) } else { unitList.push({'計量單位': '', '計量單位編碼': ''}); } let sheet1 = xlsx.utils.json_to_sheet(newList);//商品列表 let wscols = [ // 每列不同寬度px { wch: 15 },{ wch: 15 },{ wch: 15 }, { wch: 15 },{ wch: 15 },{ wch: 15 }, { wch: 15 },{ wch: 15 },{ wch: 15 }, { wch: 15 },{ wch: 15 },{ wch: 15 }, { wch: 15 },{ wch: 15 },{ wch: 15 }, { wch: 15 },{ wch: 15 } ]; // workbook.SheetNames[0]獲取到到是文件裏的到第一個表格 sheet1["!cols"] = wscols; let wsrows = [{ hpx: 20 }]; // 每行固定高度px for (let i = 0; i <= this.total; i++) { // total 列表條數 wsrows.push({ hpx: 20 }); } sheet1["!rows"] = wsrows; let sheet2 = xlsx.utils.json_to_sheet(warehouseList);//倉庫列表 let sheet3 = xlsx.utils.json_to_sheet(bransList);//品牌列表 let sheet4 = xlsx.utils.json_to_sheet(countryList);//國家列表 let sheet5 = xlsx.utils.json_to_sheet(currencyList);//幣種列表 let sheet6 = xlsx.utils.json_to_sheet(unitList);//法定計量單位列表 let book = xlsx.utils.book_new(); xlsx.utils.book_append_sheet(book, sheet1, "商品列表"); xlsx.utils.book_append_sheet(book, sheet2, "倉庫對應編碼"); xlsx.utils.book_append_sheet(book, sheet3, "品牌對應編碼"); xlsx.utils.book_append_sheet(book, sheet4, "國家對應編碼"); xlsx.utils.book_append_sheet(book, sheet5, "幣種對應編碼"); xlsx.utils.book_append_sheet(book, sheet6, "法定計量單位對應編碼"); xlsx.writeFile(book, `iwms_goods_import_template.xlsx`); }, //上傳處理 onBeforeUpload(file, fileList) { this.fileList = [fileList.pop()]; this.$workers.xlsx.postMessage({ id: this.worderId, keyMaps, file, }); return false; }, //保存 submitAdd() { if(!this.fileList.length){ this.$message.error('請上傳文件') } this.loadingBtn = true goodsService.goodsAddto({goodsData: this.tableData}).then(res => { this.loadingBtn = false if(res.code !== 200) return this.$message.success('導入成功') this.handleCancel() this.$emit('confirm', confirm); }) }, handleCancel() { this.$emit('cancel'); this.fileList = []; this.tableData = [] } } } </script> <style scoped lang="less"> .right-a { margin-right: 10px;} /deep/.ant-btn-link{padding:0;} </style>
下載的模板圖片:
最後圖片: