ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

前端使用xlsx导出导入文件

2022-05-13 11:00:39  阅读:134  来源: 互联网

标签:xlsx const 必填 导出 item 导入 key wch 15


就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>
View Code

下载的模板图片:

 

 

最后图片:

 

标签:xlsx,const,必填,导出,item,导入,key,wch,15
来源: https://www.cnblogs.com/bertha-zm/p/16265837.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有