vue reads excel content

tips:

File address (modify it as needed) https://download.csdn.net/download/tdjqqq/85761940

When xlsx.js reads the date, if it is converted to js date by default, it will be 43 seconds shorter than the normal time. When setting the date to read, just convert it directly into a string, as shown in the figure below, then the converted data is String date: "2022-05-09". If you need to specify the hour, minutes and seconds, please subtract 43 seconds.

//转换数据
                    //let tempSheetData = _this.handleGetData(XLSX.utils.sheet_to_json(workSheet))
                    let tempSheetData = XLSX.utils.sheet_to_json(workSheet, {
                        defval: null            //单元格为空时的默认值
                        , raw: false            //使用w的值而不是v
                        , dateNF: 'yyyy-MM-dd'   //日期格式
                    })

1 You need to install the following dependencies, which can also export excel

npm install -S file-saver
npm install -S xlsx
npm install -S xlsx-style
npm install -D script-loader

2 Read excel content

illustrate:

  1. The excel table must have a worksheet (sheet), and the hidden worksheet will also be read together.
  2. The results are exported as objects
  3. The component I use is ant-vue
  4. Note that in your upload component method, there must be file in the parameters, el-element can be used on-change, and note that ACTIONS must be empty, otherwise it can only be read once

 The components are as follows:

<template>
    <div class="excel-reader">
        <a-upload name="avatar" class="avatar-uploader" v-loading="loading" :show-upload-list="false"
            :before-upload="handleBeforeUpload">
            <a-button title="读取Excel">
                <a-icon type="file-excel" /> Excel Reader
            </a-button>
        </a-upload>
    </div>
</template>
  
<script>
var XLSX = require('xlsx')
import { readFile } from './excelRreadFile.js'; //读取excel文件方法

export default {
    name: 'ViExcelReader',
    props: {
        allowed: {
            type: Array,
            default () {
                //类型列表
                return [
                    'xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
                    'xls', "application/vnd.ms-excel",
                    'csv', "text/csv"]
            },
        },
    },
    data () {
        return {
            loading: false
        }
    },
    // 定义引入的组件
    components: {},
    //变量监听
    watch: {},
    // 页面初始化
    created () { },
    // 页面DOM加载完成
    mounted () {

    },
    //离开页面时执行
    destroyed () { },
    // 页面方法
    methods: {
        async handleBeforeUpload (file) {
            //选择文件后
            let _this = this

            _this.showLoading(true)

            //检测文件类型
            if (!_this.checkFileType(file)) {
                _this.$common.showMsg({
                    type: 'error',
                    content: `抱歉,请选择excel文件`,
                })

                _this.showLoading(false)
                return false
            }

            //选择excel文件后,并读取其内容(文件流)
            let dataBinary = await readFile(file)
            if (dataBinary != null) {
                // 将整个文件以二进制形式读取
                let workBook = XLSX.read(dataBinary, { type: 'binary', cellDates: true })

                // 工作表数量
                let workBookLen = workBook.SheetNames.length
                
                // excel工作簿内容
                let excelBook = []

                //读取每个sheets表
                for (let i = 0; i < workBookLen; i++) {
                    let workSheet = workBook.Sheets[workBook.SheetNames[i]]
                    excelBook.push({
                        sheetName: workBook.SheetNames[i],
                        data: XLSX.utils.sheet_to_json(workSheet, {
                        defval: null            //单元格为空时的默认值
                        , raw: false            //使用w的值而不是v
                        , dateNF: 'yyyy-MM-dd'   //日期格式
                        })
                    })
                }

                _this.showLoading(false)
                console.log({
                    name: file.name,
                    length: workBookLen,
                    data: excelBook
                })
                //导出工作表内容
                _this.$emit("onChange", {
                    name: file.name,
                    length: workBookLen,
                    data: excelBook
                })

            }
        },

        showLoading (val) {
            let _this = this
            _this.loading = val
        },
        checkFileType (file) {
            let _this = this

            let flog = false

            //得到上传文件的值
            let fileName = file.name

            //取其类型
            let fileType = fileName.lastIndexOf('.')

            //返回位于String对象中指定位置的子字符串并转换为小写.
            let extension = fileName
                .substring(fileType)
                .toLowerCase()
                .replace('.', '')
            //判断允许上传的文件格式
            if (_this.allowed.includes(extension)) {
                flog = true
            } else {
                flog = false
            }

            return flog
        }
    },
}
</script>
 
<style lang="less" scoped>
.excel-reader {
    display: inline-block;
    .ant-upload-text {
    }
}
</style>

excelRreadFile.js

export const readFile = (file) => {
    return new Promise((resolve) => {
        if (window.FileReader) {
            let reader = new FileReader()
            //将文件读取为二进制码
            reader.readAsBinaryString(file)

            //文件读取成功完成时,若失败,结果为null,否则为读取的结果
            reader.onload = (ev) => {
                resolve(ev.target.result)
            }
        } else {
            //不支持,返回结果为null
            alert('抱歉,您的浏览器,无法支持读取文件功能!')
            resolve(null)
        }
    })
}

Excel with only one worksheet and results 

 

Excel with multiple worksheets and results 

 

Automatically convert data format version

<template>
    <div class="excel-reader">
        <a-upload name="avatar" class="avatar-uploader" v-loading="loading" :show-upload-list="false"
            :before-upload="handleBeforeUpload">
            <a-button title="读取Excel">
                <a-icon type="file-excel" /> Excel Reader
            </a-button>
        </a-upload>
    </div>
</template>
  
<script>
var XLSX = require('xlsx')
import { readFile } from './excelRreadFile.js'; //读取excel文件方法

export default {
    name: 'ViExcelReader',
    props: {
        allowed: {
            type: Array,
            default () {
                //类型列表
                return [
                    'xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
                    'xls', "application/vnd.ms-excel",
                    'csv', "text/csv"]
            },
        },
        transFiled: {
            type: Object,
            default () {
                return {
                    origin: 'zh',
                    target: 'field'
                }
            }
        },
        header: {
            type: Array,
            default () {
                return [{
                    field: 'no',//字段列
                    zh: '序号',//excel的标题
                    en: 'No',//转换的列名
                },
                {
                    field: 'student_name',//字段列
                    zh: '姓名',//excel的标题
                    en: 'student name',//转换的列名
                },
                {
                    field: 'chinese',//字段列
                    zh: '语文',//excel的标题
                    en: 'chinese',//转换的列名
                },
                {
                    field: 'math',//字段列
                    zh: '数学',//excel的标题
                    en: 'math',//转换的列名
                },
                {
                    field: 'english',//字段列
                    zh: '英语',//excel的标题
                    en: 'english',//转换的列名
                },
                {
                    field: 'exam_date',//字段列
                    zh: '考试日期',//excel的标题
                    en: 'exam date',//转换的列名
                },
                ]
            },
        },
        field: {
            type: Array,
            default () {
                return []
            },
        },
    },
    data () {
        return {
            loading: false
        }
    },
    // 定义引入的组件
    components: {},
    //变量监听
    watch: {},
    // 页面初始化
    created () { },
    // 页面DOM加载完成
    mounted () {

    },
    //离开页面时执行
    destroyed () { },
    // 页面方法
    methods: {
        async handleBeforeUpload (file) {
            //选择文件后
            let _this = this

            _this.showLoading(true)

            //检测文件类型
            if (!_this.checkFileType(file)) {
                _this.$common.showMsg({
                    type: 'error',
                    content: `抱歉,请选择excel文件`,
                })

                _this.showLoading(false)
                return false
            }

            //选择excel文件后,并读取其内容(文件流)
            let dataBinary = await readFile(file)
            if (dataBinary != null) {
                // 将整个文件以二进制形式读取
                let workBook = XLSX.read(dataBinary, { type: 'binary', cellDates: true, cellText: false })

                // 工作表数量
                let workBookLen = workBook.SheetNames.length

                // excel工作簿内容
                let excelBook = []

                //读取每个sheets表
                for (let i = 0; i < workBookLen; i++) {
                    let workSheet = workBook.Sheets[workBook.SheetNames[i]]

                    //转换数据
                    let tempSheetData = []
                    if (Object.keys(_this.transFiled).length == 0 || _this.header.length == 0) {
                        //默认导出,不转换
                        tempSheetData = XLSX.utils.sheet_to_json(workSheet, {
                            defval: null            //单元格为空时的默认值
                            , raw: false            //使用w的值而不是v
                            , dateNF: 'yyyy-MM-dd'   //日期格式
                        })
                    } else {
                        //根据实际情况导出
                        tempSheetData = _this.handleGetData(XLSX.utils.sheet_to_json(workSheet, {
                            defval: null            //单元格为空时的默认值
                            , raw: false            //使用w的值而不是v
                            , dateNF: 'yyyy-MM-dd'   //日期格式
                        }))
                    }

                    excelBook.push({
                        sheetName: workBook.SheetNames[i],
                        data: tempSheetData
                    })
                }

                _this.showLoading(false)
                console.log({
                    name: file.name,
                    length: workBookLen,
                    data: excelBook
                })
                //导出工作表内容
                _this.$emit("onChange", {
                    name: file.name,
                    length: workBookLen,
                    data: excelBook
                })

            }
        },
        handleGetData (data) {
            //转换数据
            let _this = this
            if (data.length == 0) {
                return []
            }

            let resultArr = []
            data.filter(item => {
                let row = {}
                for (let i in item) {
                    for (let m = 0; m < _this.header.length; m++) {
                        let mItem = _this.header[m]
                        if (mItem[_this.transFiled.origin] == i) {
                            row[mItem[_this.transFiled.target]] = item[i]
                            break
                        }
                    }
                }
                resultArr.push(row)
            })

            return resultArr
        },
        showLoading (val) {
            let _this = this
            _this.loading = val
        },
        checkFileType (file) {
            let _this = this

            let flog = false

            //得到上传文件的值
            let fileName = file.name

            //取其类型
            let fileType = fileName.lastIndexOf('.')

            //返回位于String对象中指定位置的子字符串并转换为小写.
            let extension = fileName
                .substring(fileType)
                .toLowerCase()
                .replace('.', '')
            //判断允许上传的文件格式
            if (_this.allowed.includes(extension)) {
                flog = true
            } else {
                flog = false
            }

            return flog
        }
    },
}
</script>
 
<style lang="less" scoped>
.excel-reader {
    display: inline-block;
    .ant-upload-text {
    }
}
</style>

in conclusion:

Be sure to note that the hidden sheets will also be read out, and the converted data will appear with Chinese titles. Friends in need can convert the objects, otherwise there may be problems. 

Guess you like

Origin blog.csdn.net/tdjqqq/article/details/125099815