Vue.js+element-ui+js-xlsx 解析文件内容

本文介绍了如何在Vue.js项目中,利用element-ui组件和js-xlsx库解析xlsx文件。首先通过npm安装xlsx,然后在组件中引入XLSX模块。在main.js中引入xlsx.full.min.js文件,注意正确设置文件路径。接着在vue+element的环境中定义methods进行操作。按照步骤执行,解析过程简单易懂,确保路径无误即可。

Vue.js+element-ui+js-xlsx

寄语:vue框架中上传xlsx文件,使用js-xlsx解析文件内容

1.首先执行: npm install xlsx (安装)

2.在当前页面.vue文件中引入: import XLSX from 'xlsx'

3.在main.js中引入:import XLSX from '../static/xlsx.full.min'

   注释:当安装了npm install xlsx 在node_modules>xlsx>dist 就可以找到xlsx.full.min文件,引入就OK了

              本人是直接复制这个文件到static下,所以文件在main中引入路径为 ../static/xlsx.full.min

4.vue+element

 

<div class="">
  <el-upload action="/" :on-change='onChange' :auto-upload='false' :show-file-list="false" accept=".xls, .xlsx">
   <el-button size="small" type="primary" class="upload-bom"><i class="iconfont iconxlsx iconXlSX-sty"></i>
      <span class="iconXlSX-sty-test">文件</span></el-button>
    <!--              <div slot="tip" v-if='fileData'>{{ fileData.name }}</div>-->
  </el-upload>
  <el-table :data="outputs" style="margin-top: 20px">
    <el-table-column label="姓名" prop='name'></el-table-column>
    <el-table-column label="年龄" prop='age'></el-table-column>
  </el-table>
</div>

5.methods:{ }

data() {
    return {
        outputs: [], // 保存读取出来的数据
        fileData: '', // 保存选择的文件
    }
},
// 文件选择回调
onChange(file, fileList) {
    this.fileData = file; // 保存当前选择文件
    this.readExcel() // 调用读取数据的方法
},
// 读取数据
readExcel(e) {
    let that = this;
    const files = that.fileData;
    console.log(files);
    console.log(files.size)
    if (!files) {
        //如果没有文件
        return false;
    } else if (!/\.(xls|xlsx)$/.test(files.name.toLowerCase())) {
        this.$message.error("上传格式不正确,请上传xls或者xlsx格式");
        return false;
    }
    const fileReader = new FileReader();
    fileReader.onload = ev => {
        try {
            const data = ev.target.result;
            // console.log(data)
            const workbook = XLSX.read(data, {
                type: "binary"
            });
            console.log(workbook.SheetNames)
            const wsname = workbook.SheetNames[0]; //取第一张表
            const ws = XLSX.utils.sheet_to_json(workbook.Sheets[wsname]); //生成json表格内容
            console.log(ws);
            that.outputs = []; //清空接收数据
            for (var i = 0; i < ws.length; i++) {
                var sheetData = {
                    // 键名为绑定 el 表格的关键字,值则是 ws[i][对应表头名]
                    name: ws[i]['姓名'],
                    age: ws[i]['年龄'],
                };
                that.outputs.push(sheetData);
            }
            this.$refs.upload.value = "";
        } catch (e) {
            return false;
        }
    };
    // 如果为原生 input 则应是 files[0]
    fileReader.readAsBinaryString(files.raw);
}

6.运行结果

 

总结:解析 非常容易、在引入文件切记注意路径,然后就跟着步骤走。就绝对没错。如有疑问欢迎评论交流。                  

 

 

Vue2 + Element-UI 中实现**动态多级表头表格的导出功能**,与 Vue3 类似,但由于使用的是 `Element-UI`(非 Element Plus)和 Vue2 的 Options API,代码结构略有不同。我们仍然结合 [SheetJS / xlsx](https://github.com/SheetJS/sheetjs) 实现前端 Excel 导出。 --- ### ✅ 功能目标: 1. 使用 `Element-UI` 的 `<el-table>` 支持任意层级的**动态多级表头** 2. 点击按钮将当前表格(含合并表头)导出为 `.xlsx` 文件 3. 表头支持跨列合并(如“个人信息”合并“年龄”“城市”两列) --- ### ✅ 所需依赖 ```bash npm install xlsx file-saver ``` > `file-saver` 用于触发文件下载(可选,`XLSX.writeFile` 已内置) --- ### ✅ 完整示例代码(Vue2 + Element-UI) ```vue <template> <div style="padding: 20px;"> <el-button type="primary" @click="exportToExcel">导出为 Excel</el-button> <el-table :data="tableData" border style="width: 100%; margin-top: 20px" ref="tableRef" > <!-- 动态渲染多级表头 --> <el-table-column v-for="col in tableColumns" :key="col.prop" :prop="col.prop" :label="col.label" :width="col.width" > <el-table-column v-for="child in col.children || []" :key="child.prop" :prop="child.prop" :label="child.label" :width="child.width" /> </el-table-column> </el-table> </div> </template> <script> import * as XLSX from 'xlsx' import { saveAs } from 'file-saver' export default { name: 'DynamicTableExport', data() { return { // 表格数据 tableData: [ { name: '张三', info_age: 25, info_city: '北京', score_chinese: 88, score_math: 92 }, { name: '李四', info_age: 27, info_city: '上海', score_chinese: 76, score_math: 98 }, { name: '王五', info_age: 24, info_city: '深圳', score_chinese: 90, score_math: 85 } ], // 多级表头定义(支持 children) tableColumns: [ { prop: 'name', label: '姓名', width: 100 }, { label: '个人信息', children: [ { prop: 'info_age', label: '年龄', width: 80 }, { prop: 'info_city', label: '城市', width: 100 } ] }, { label: '成绩信息', children: [ { prop: 'score_chinese', label: '语文', width: 80 }, { prop: 'score_math', label: '数学', width: 80 } ] } ] } }, methods: { // 展平列定义,提取每列路径和表头层级 flattenHeaders(columns) { const result = [] columns.forEach(col => { if (col.children && col.children.length > 0) { col.children.forEach(child => { result.push({ prop: child.prop, groupLabel: col.label, fieldLabel: child.label }) }) } else { result.push({ prop: col.prop, groupLabel: null, fieldLabel: col.label }) } }) return result }, // 导出为 Excel exportToExcel() { const flatCols = this.flattenHeaders(this.tableColumns) // 构建两行表头 const headerRow1 = [] // 分组行(如“个人信息”) const headerRow2 = [] // 字段行(如“年龄”、“语文”) flatCols.forEach(col => { if (col.groupLabel) { headerRow1.push(col.groupLabel) headerRow2.push(col.fieldLabel) } else { headerRow1.push(col.fieldLabel) headerRow2.push('') // 没有子列的,第二行为空 } }) // 合并单元格设置:记录第一行中相同分组的连续列进行合并 const merges = [] let lastGroup = null let startCol = 0 headerRow1.forEach((group, idx) => { if (group !== lastGroup) { // 如果上一个组存在且跨度大于1,则添加合并 if (lastGroup !== null && idx - startCol > 1) { merges.push({ s: { r: 0, c: startCol }, // start row=0, col=startCol e: { r: 0, c: idx - 1 } // end row=0, col=idx-1 }) } lastGroup = group startCol = idx } }) // 处理最后一组 if (headerRow1.length - startCol > 1 && lastGroup) { merges.push({ s: { r: 0, c: startCol }, e: { r: 0, c: headerRow1.length - 1 } }) } // 填充数据行 const dataRows = this.tableData.map(row => { return flatCols.map(col => row[col.prop] || '') }) // 创建工作表(空表开始) const worksheet = XLSX.utils.aoa_to_sheet([]) // 写入第一行(分组) XLSX.utils.sheet_add_aoa(worksheet, [headerRow1], { origin: 'A1' }) // 写入第二行(字段) XLSX.utils.sheet_add_aoa(worksheet, [headerRow2], { origin: 'A2' }) // 写入数据(从第3行开始) XLSX.utils.sheet_add_aoa(worksheet, dataRows, { origin: 'A3' }) // 设置列宽 const colWidths = flatCols.map(() => ({ wch: 12 })) worksheet['!cols'] = colWidths // 设置合并单元格 worksheet['!merges'] = merges // 创建工作簿 const workbook = XLSX.utils.book_new() XLSX.utils.book_append_sheet(workbook, worksheet, '数据表') // 导出文件 XLSX.writeFile(workbook, 'Vue2_ElementUI_多级表头导出.xlsx') } } } </script> <style scoped> .el-table { margin-top: 20px; } </style> ``` --- ### 🔍 代码解释 | 部分 | 说明 | |------|------| | `tableColumns` | 使用 `children` 字段实现二级表头,Element-UI 原生支持嵌套 `el-table-column` | | `flattenHeaders()` | 将嵌套结构展平,便于生成 Excel 表头和读取数据 | | `headerRow1` 和 `headerRow2` | 分别表示第一层(分组)和第二层(具体字段)表头 | | `merges` | 记录需要在 Excel 中合并的单元格范围(仅对第一行) | | `XLSX.utils.sheet_add_aoa` | 按二维数组方式写入指定位置 | | `worksheet['!merges']` | 设置 Excel 合并规则 | --- ### ✅ 输出效果(Excel) | 个人信息 | 成绩信息 | |----------------|--------------| | 年龄 | 城市 | 语文 | 数学 | | 25 | 北京 | 88 | 92 | | 27 | 上海 | 76 | 98 | 其中,“个人信息”跨两列合并,“成绩信息”也跨两列。 --- ### ✅ 注意事项 - **Element-UI 不支持三级以上嵌套表头**,本方案适用于最多两级。 - 若需更高层级,建议改用自定义表头模板或后端导出。 - 数据量大时避免前端导出,应由后端处理。 - 可通过 `ref="tableRef"` 获取表格 DOM,但此处无需依赖它来获取数据——因为我们自己维护了 `tableData` 和 `tableColumns`。 --- ### ✅ 扩展建议 - 抽象成混入(mixin)或封装为全局组件 - 添加导出前的确认弹窗 - 支持选择导出哪些列 - 自动调整列宽根据内容长度 ---
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值