导出excel的两个方式:前端vue+XLSX 导出excel,vue+后端POI 导出excel,并进行分析、比较

简介: 这篇文章介绍了使用前端Vue框架结合XLSX库和后端结合Apache POI库导出Excel文件的两种方法,并对比分析了它们的优缺点。

前言

一、需求分析

1. 两个方式

导出excel有两个方式,前端导出后端导出

  1. 前端导出excel:就用 vue+XLSX(npm 包)
  2. 后端导出excel:就用 vue+POI(maven 包)

2. 对比分析

  1. 前端导出excel 相对来说简单一点,XLSX是前端 npm 包,但是如果数据量大的话,会卡顿,处理时间慢;当数据量多的时候 使用后端导出会好一点
  2. 后端导出excel 相对来说麻烦一点,但是时间短、速度快;具体操作都放在后端,也节省了前端的操作。用户效果好。

二、方式1:vue+XLSX

1. 安装 XLSX

npm install xlsx file-saver --save

2. XLSX 两个方法比较

  • 这个XLSX 方法一 和下面的XLSX 方法二 都是使用的 XLSX 模块的 方法,只是获取数据的方式和 导出excel的方式有点不一样。
  • 相比之下,还是 XLSX 方法一 会好一点,可以自定义导出的字段。

3. XLSX 方法一:

a. 按钮事件

<el-button size="small" type="primary" @click="exportSelect()">导出选中</el-button>
<el-button size="small" type="primary" @click="exportAllExcel">导出全部</el-button>

其实 上面的 二方法 可以做成一个方法,但是为了明确好分析,我写成了二个方法。

b. js 方法:导出选中 exportSelect()

      exportSelect() {
        //  导出选中
        this.$confirm("是否确认导出当前所有参赛人员数据?", "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }).then((response) => {
          //  this.selectdata 是复选框的 数据列表
          if (this.selectdata.length <= 0) {
            this.$message.info('请选择数据!');
            return false;
          }
          let tableData = [
            ['序号', '赛区名称', '参赛人', '手机号', '收件地址', "邮箱", "录入时间",  "状态"]//导出表头
          ] // 表格表头
          this.selectdata.forEach((item, index) => {
            let rowData = []
            //导出内容的字段
            rowData = [
              index + 1,
              item.matchAreaName,
              item.userName,
              item.userPhone,
              item.receiveAddress,
              item.createTime,
              item.dataFlag === 0 ? '待审核': '审核通过',
            ]
            tableData.push(rowData)
          })
          let workSheet = XLSX.utils.aoa_to_sheet(tableData);
          let bookNew = XLSX.utils.book_new();
          XLSX.utils.book_append_sheet(bookNew, workSheet, '作品名称') // 工作簿名称
          let name = '参赛人员选中' + this.timeFormat() + '.xlsx'
          XLSX.writeFile(bookNew, name) // 保存的文件名
        })
      },
      timeFormat() {
        let time = new Date();
        let year = time.getFullYear();
        let month = time.getMonth() + 1;
        let date = time.getDate();
        let hours = time.getHours();
        let minutes = time.getMinutes();
        let seconds = time.getSeconds();
        return year + '-' + this.addZero(month) + '-' + this.addZero(date) + ' ' + this.addZero(hours) + ':' + this.addZero(minutes) + ':' + this.addZero(seconds);
      },
      addZero(num) {
        return num < 10 ? '0' + num : num
      },

c. js 方法:导出全部 exportAllExcel

      // 导出 所有
      exportAllExcel() {
        this.$confirm("是否确认导出全部参赛人员数据?", "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }).then(response => {

          // 获取用户列表
          let arr = [];
          let parameter = {
            pageNo: 1,
            pageSize: 1000
          }
          getMatchUserInfoList(parameter).then(res => {
            this.loading = false;
            if (res.data.code != "1") {
              this.$message({
                type: 'info',
                message: res.data.message
              })
            } else {
              arr = res.data.data;
              console.log('----------:', JSON.stringify(arr))
              this.exportList(arr);
            }
          }).catch(err => {
            this.$message.warning("系统问题,请稍后重试!")
          })
      },
      exportList(arr){
        let tableData = [
          ['序号', '赛区名称', '参赛人', '手机号', '收件地址', "邮箱", "录入时间",  "审核状态", "是否发送豆子"]//导出表头
        ] // 表格表头
        arr.forEach((item, index) => {
          let rowData = []
          //导出内容的字段
          rowData = [
            index + 1,
            item.matchAreaName,
            item.userName,
            item.userPhone,
            item.receiveAddress,
            item.email,
            item.createTime,
            item.dataFlag === 0 ? '待审核': '审核通过',
            item.sendFlag === 1 ? '否': '是',
          ]
          tableData.push(rowData)
        })
        let workSheet = XLSX.utils.aoa_to_sheet(tableData);
        let bookNew = XLSX.utils.book_new();
        XLSX.utils.book_append_sheet(bookNew, workSheet, '作品名称') // 工作簿名称
        let name = '全部参赛人员' + this.timeFormat() + '.xlsx'
        XLSX.writeFile(bookNew, name) // 保存的文件名
      },

4. XLSX 方法二:

a. 按钮事件

<el-button size="small" type="primary" @click="exportExcel">导出当前页</el-button>

b. js 方法:导出当前页 exportExcel

这里是

// 导出当前页
      exportExcel() {
        this.$confirm("是否确认导出当前所有参赛人员数据?", "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }).then((response) => {
          const wb = XLSX.utils.table_to_book(
                  document.querySelector("#el-table")
          );
          const wbout = XLSX.write(wb, {
            bookType: "xlsx",
            bookSST: true,
            type: "array",
          });
          try {
            FileSaver.saveAs(
                    new Blob([wbout], {type: "application/octet-stream"}),
                    "参赛人员数据.xlsx"
            );
          } catch (e) {
            if (typeof console !== "undefined") console.log(e, wbout);
          }
        });
      },

二、方式2:vue+POI

这个方式也就是后端生成excel,与前端没有多大的关系,后端写好的 excel就直接writeresponse里面了。
先直接放上前端代码。

1. 前端代码

a、按钮事件

<el-button size="small" type="primary" @click="exportAllExcel">导出全部</el-button>

b、网络请求封装

// 导出全部
export function exportExcelForMatchUser(data) {
  return fetch({
    url: '/xfx/matchUser/web/exportExcelForMatchUser',
    method: 'post',
    timeout: '120000',
    responseType: 'blob',
    data
  });
}

c、js方法:导出全部 exportAllExcel

      // 导出 所有
      exportAllExcel() {
        this.$confirm("是否确认导出全部参赛人员数据?", "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }).then(response => {
          exportExcelForMatchUser().then(response => {
            const data = "参赛人员web.xlsx";
            console.log('1111111111111111111111111', JSON.stringify(response))
            let blob = new Blob([response.data], {type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=utf-8"});
            console.log('333333333333333333333333', JSON.stringify(blob))
            // for IE
            if (window.navigator && window.navigator.msSaveOrOpenBlob) {
              window.navigator.msSaveOrOpenBlob(blob, data);
            } else {
              console.log('chrome go here ')
              let downloadElement = document.createElement('a');
              let href = window.URL.createObjectURL(blob); // 创建下载的链接
              downloadElement.href = href;
              downloadElement.download = data; // 下载后文件名
              document.body.appendChild(downloadElement);
              downloadElement.click(); // 点击下载
              document.body.removeChild(downloadElement); // 下载完成移除元素
              window.URL.revokeObjectURL(href); // 释放掉blob对象
            }
          }).catch(err => {
            console.log(err)
            this.loading = false;
            this.$message.warning("对不起,下载失败");
          });
        })
      },

2. 后端代码(IMPORTANT)

a、maven 依赖

        <!-- poi -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.9</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.9</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-scratchpad -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>3.14</version>
        </dependency>

        <!--这个不属于 poi ,就是一个工具类-->
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.3.2</version>
        </dependency>

b、controller 控制器层

    /**
     * @return com.zheng.ucenter.common.constant.UcenterResult
     * @Author fengfanli
     * @Description //TODO 导出全部
     * @Date 17:40 2021/5/17
     * @Param [param, request]
     **/
    @RequestMapping(value = "/web/exportExcelForMatchUser", method = RequestMethod.POST)
    public UcenterResult exportExcelForMatchUser(HttpServletResponse response) {

        try {
            MatchUserModel model = new MatchUserModel();
            model.setStart(0);
            model.setPageSize(10000);
            List<MatchUserModel> allMatchUserModels = matchUserService.getAllMatchUserModels(model);
            // 导出 代码
            List<MatchUserResp> result = new ArrayList<>(allMatchUserModels.size());
            for (MatchUserModel matchUserModel : allMatchUserModels) {
                MatchUserResp resp = new MatchUserResp();
                BeanUtils.copyProperties(matchUserModel, resp);
                resp.setCreateTime(DateHander.dateToStr1(matchUserModel.getCreateTime()));
                result.add(resp);
            }
            if (result.size()!=0){
                ExportExcel exportExcel = new ExportExcel("参赛人员", MatchUserResp.class, 1);
                exportExcel.setDataList(result);
                String fileName = "MATCH_USER_" + DateHander.dateToStrD(new Date()) + (new Random().nextInt(100 - 10) + 10) + ".xlsx";
                exportExcel.write(response, fileName);
            }
            return new UcenterResult(UcenterResultConstant.SUCCESS);
        } catch (Exception e) {
            logger.error("MatchUserController exportExcelForMatchUser error:", e);
        }
        return new UcenterResult(UcenterResultConstant.FAILED);
    }

重点就是其中的五行:
在这里插入图片描述

c、POJO类MatchUserResp类

这里使用到了自定义的 注解类

import java.io.Serializable;
import java.util.Date;

/**
 * @ClassName MatchUserResp
 * @Description TODO
 * @Author admin
 * @Date 2021/5/14 15:36
 * @Version 1.0
 */
public class MatchUserResp implements Serializable {
    @ExcelField(title = "序号", align = 1, sort = 1)
    private Integer id;

    private Long matchMainId;
    private Long userId;

    @ExcelField(title = "是否发送豆子(2:发送,1:未发送)", align = 1, sort = 2)
    private Long sendFlag;

    @ExcelField(title = "比赛名称", align = 1, sort = 3)
    private String matchName;

    @ExcelField(title = "用户名", align = 1, sort = 4)
    private String userName;

    @ExcelField(title = "手机号", align = 1, sort = 5)
    private String userPhone;

    private String userWxHead;

    @ExcelField(title = "收件地址", align = 1, sort = 6)
    private String receiveAddress;

    @ExcelField(title = "邮箱", align = 1, sort = 7)
    private String email;

    private Long matchAreaCodeId;

    @ExcelField(title = "赛区名称", align = 1, sort = 8)
    private String matchAreaName;

    @ExcelField(title = "备注", align = 1, sort = 9)
    private String remark;

    private Integer createUserId;
    private String createUserName;

    @ExcelField(title = "创建时间", align = 1, sort = 10)
    private String createTime;

    private Integer dataFlag;
    private Integer useFlag;
    private String timeStamp;

    public Long getSendFlag() {
        return sendFlag;
    }

    public void setSendFlag(Long sendFlag) {
        this.sendFlag = sendFlag;
    }

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Long getMatchMainId() {
        return matchMainId;
    }

    public void setMatchMainId(Long matchMainId) {
        this.matchMainId = matchMainId;
    }

    public String getMatchName() {
        return matchName;
    }

    public void setMatchName(String matchName) {
        this.matchName = matchName;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserPhone() {
        return userPhone;
    }

    public void setUserPhone(String userPhone) {
        this.userPhone = userPhone;
    }

    public String getUserWxHead() {
        return userWxHead;
    }

    public void setUserWxHead(String userWxHead) {
        this.userWxHead = userWxHead;
    }

    public String getReceiveAddress() {
        return receiveAddress;
    }

    public void setReceiveAddress(String receiveAddress) {
        this.receiveAddress = receiveAddress;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Long getMatchAreaCodeId() {
        return matchAreaCodeId;
    }

    public void setMatchAreaCodeId(Long matchAreaCodeId) {
        this.matchAreaCodeId = matchAreaCodeId;
    }

    public String getMatchAreaName() {
        return matchAreaName;
    }

    public void setMatchAreaName(String matchAreaName) {
        this.matchAreaName = matchAreaName;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public Integer getCreateUserId() {
        return createUserId;
    }

    public void setCreateUserId(Integer createUserId) {
        this.createUserId = createUserId;
    }

    public String getCreateUserName() {
        return createUserName;
    }

    public void setCreateUserName(String createUserName) {
        this.createUserName = createUserName;
    }

    public String getCreateTime() {
        return createTime;
    }

    public void setCreateTime(String createTime) {
        this.createTime = createTime;
    }

    public Integer getDataFlag() {
        return dataFlag;
    }

    public void setDataFlag(Integer dataFlag) {
        this.dataFlag = dataFlag;
    }

    public Integer getUseFlag() {
        return useFlag;
    }

    public void setUseFlag(Integer useFlag) {
        this.useFlag = useFlag;
    }

    public String getTimeStamp() {
        return timeStamp;
    }

    public void setTimeStamp(String timeStamp) {
        this.timeStamp = timeStamp;
    }
}

c、其余的工具类

在这里插入图片描述
我都上传至GitHub了,可以直接拿过来用。

3. 总结

到此 后端导出excel结束了。

相关文章
|
4月前
|
JavaScript 前端开发 Java
制造业ERP源码,工厂ERP管理系统,前端框架:Vue,后端框架:SpringBoot
这是一套基于SpringBoot+Vue技术栈开发的ERP企业管理系统,采用Java语言与vscode工具。系统涵盖采购/销售、出入库、生产、品质管理等功能,整合客户与供应商数据,支持在线协同和业务全流程管控。同时提供主数据管理、权限控制、工作流审批、报表自定义及打印、在线报表开发和自定义表单功能,助力企业实现高效自动化管理,并通过UniAPP实现移动端支持,满足多场景应用需求。
439 1
|
2月前
|
Python
Excel中如何批量重命名工作表与将每个工作表导出到单独Excel文件
本文介绍了如何在Excel中使用VBA批量重命名工作表、根据单元格内容修改颜色,以及将工作表导出为独立文件的方法。同时提供了Python实现导出工作表的代码示例,适用于自动化处理Excel文档。
|
5月前
|
移动开发 前端开发 JavaScript
Vue与React两大前端框架的主要差异点
以上就是Vue和React的主要差异点,希望对你有所帮助。在选择使用哪一个框架时,需要根据项目的具体需求和团队的技术栈来决定。
350 83
|
4月前
|
JavaScript 前端开发 编译器
Vue与TypeScript:如何实现更强大的前端开发
Vue.js 以其简洁的语法和灵活的架构在前端开发中广受欢迎,而 TypeScript 作为一种静态类型语言,为 JavaScript 提供了强大的类型系统和编译时检查。将 Vue.js 与 TypeScript 结合使用,不仅可以提升代码的可维护性和可扩展性,还能减少运行时错误,提高开发效率。本文将介绍如何在 Vue.js 项目中使用 TypeScript,并通过一些代码示例展示其强大功能。
203 22
|
6月前
|
人工智能 JavaScript 前端开发
Vue 性能革命:揭秘前端优化的终极技巧;Vue优化技巧,解决Vue项目卡顿问题
Vue在处理少量数据和有限dom的情况下技术已经非常成熟了,但现在随着AI时代的到来,海量数据场景会越来越多,Vue优化技巧也是必备技能。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
2月前
|
Python
如何根据Excel某列数据为依据分成一个新的工作表
在处理Excel数据时,我们常需要根据列值将数据分到不同的工作表或文件中。本文通过Python和VBA两种方法实现该操作:使用Python的`pandas`库按年级拆分为多个文件,再通过VBA宏按班级生成新的工作表,帮助高效整理复杂数据。
|
2月前
|
数据采集 数据可视化 数据挖掘
用 Excel+Power Query 做电商数据分析:从 “每天加班整理数据” 到 “一键生成报表” 的配置教程
在电商运营中,数据是增长的关键驱动力。然而,传统的手工数据处理方式效率低下,耗费大量时间且易出错。本文介绍如何利用 Excel 中的 Power Query 工具,自动化完成电商数据的采集、清洗与分析,大幅提升数据处理效率。通过某美妆电商的实战案例,详细拆解从多平台数据整合到可视化报表生成的全流程,帮助电商从业者摆脱繁琐操作,聚焦业务增长,实现数据驱动的高效运营。
|
4月前
|
存储 安全 大数据
网安工程师必看!AiPy解决fscan扫描数据整理难题—多种信息快速分拣+Excel结构化存储方案
作为一名安全测试工程师,分析fscan扫描结果曾是繁琐的手动活:从海量日志中提取开放端口、漏洞信息和主机数据,耗时又易错。但现在,借助AiPy开发的GUI解析工具,只需喝杯奶茶的时间,即可将[PORT]、[SERVICE]、[VULN]、[HOST]等关键信息智能分类,并生成三份清晰的Excel报表。告别手动整理,大幅提升效率!在安全行业,工具党正碾压手动党。掌握AiPy,把时间留给真正的攻防实战!官网链接:https://www.aipyaipy.com,解锁更多用法!
|
2月前
|
Python
将Excel特定某列数据删除
将Excel特定某列数据删除
|
9月前
|
数据采集 数据可视化 数据挖掘
利用Python自动化处理Excel数据:从基础到进阶####
本文旨在为读者提供一个全面的指南,通过Python编程语言实现Excel数据的自动化处理。无论你是初学者还是有经验的开发者,本文都将帮助你掌握Pandas和openpyxl这两个强大的库,从而提升数据处理的效率和准确性。我们将从环境设置开始,逐步深入到数据读取、清洗、分析和可视化等各个环节,最终实现一个实际的自动化项目案例。 ####
1662 10