vue springboot利用easypoi实现简单导出
vue springboot利用easypoi实现简单导出
前言
今天玩了一下vue springboot利用easypoi实现excel的导出,以前没玩过导入导出,只不过听说过看别人用过,怎么说呢,想玩就玩一下吧,毕竟结合自己业务场景需要才会考虑是否使用。先简单介绍一下easypoi。
一、easypoi是什么?
1.不太熟悉poi的
2.不想写太多重复太多的
3.只是简单的导入导出的
4.喜欢使用模板的
若poi都不知道的童鞋请自行百度。。。
Easypoi的目标不是替代poi,而是让一个不懂导入导出的快速使用poi完成Excel和word的各种操作,而不是看很多api才可以完成这样工作。
二、使用步骤
1.传送门
因为我也是第一次使用,这里还是先将easypoi的官方文档放这儿吧:
2.前端vue
咋先从前端开始吧,总要一步步来嘛,下面看代码(仔细看注释):
<template>
<div>
<!-- 这里只演示导出,导入也差不多 -->
<!-- <el-button class="el-icon-upload" type="success">导入</el-button> -->
<el-button class="el-icon-download" type="success" @click="exportExcel()">导出</el-button>
</div>
</template>
<script>
export default {
name: "importandexport",
data() {
return {
extp: this.exportExceltype,
};
},
props: ["exportExceltype"],//父组件向子传递过来的值,用于判断是那个组件过来的
methods: {
exportExcel() {
const extpurl = ""; //导出请求地址
//这里就是判断来自哪个父组件,从而发送不同的请求路径
if (this.extp == "user") {
this.extpurl = "/exportUser";
} else if (this.extp == "role") {
this.extpurl = "/exportRole";
}
this.$axios
.get(this.extpurl, { responseType: "blob" })
.then((res) => {
const blob = new Blob([res.data], { //取响应回来的数据
type: "application/vnd.ms-excel;charset=utf-8",
});
const href = window.URL.createObjectURL(blob); // 创建下载的链接
const downloadElement = document.createElement("a");
downloadElement.href = href;
downloadElement.download = decodeURI(res.headers["filename"]);
document.body.appendChild(downloadElement);
downloadElement.click(); // 点击下载
document.body.removeChild(downloadElement); // 下载完成移除元素
window.URL.revokeObjectURL(href); // 释放掉blob对象
})
.catch((fail) => {
console.error(fail);
});
},
},
};
</script>
<style scoped>
</style>
上面的是公用的子组件,还缺少父组件,看下面代码:
<template>
<div>
<el-row style="margin: 18px 0px 0px 18px ">
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/admin/dashboard' }"
>管理中心</el-breadcrumb-item
>
<el-breadcrumb-item>用户管理</el-breadcrumb-item>
<el-breadcrumb-item>用户信息</el-breadcrumb-item>
</el-breadcrumb>
</el-row>
<bulk-registration @onSubmit="listUsers()"></bulk-registration>
<el-card style="margin: 18px 2%;width: 95%">
<el-table
v-loading="loading"
:data="users.slice((currentPage-1)*pageSize,currentPage*pageSize)"
stripe
:default-sort="{ prop: 'id', order: 'ascending' }"
style="width: 100%"
:max-height="tableHeight"
>
<el-table-column type="selection" width="55"> </el-table-column>
<el-table-column prop="id" label="id" sortable width="100">
</el-table-column>
<el-table-column prop="username" label="用户名" fit> </el-table-column>
<el-table-column prop="name" label="真实姓名" fit> </el-table-column>
<el-table-column prop="phone" label="手机号" fit> </el-table-column>
<el-table-column prop="email" label="邮箱" show-overflow-tooltip fit>
</el-table-column>
<el-table-column label="状态" sortable width="100">
<template slot-scope="scope">
<el-switch
v-model="scope.row.enabled"
active-color="#13ce66"
inactive-color="#ff4949"
@change="value => commitStatusChange(value, scope.row)"
>
</el-switch>
</template>
</el-table-column>
<el-table-column label="操作" width="120">
<template slot-scope="scope">
<el-button @click="editUser(scope.row)" type="text" size="small">
编辑
</el-button>
<el-button @click="delUser(scope.row)" type="text" size="small">
移除
</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
layout="total, prev, pager, next, jumper"
@current-change="handleCurrentChange"
:page-size="pageSize"
:current-page="currentPage"
:total="total">
</el-pagination>
</el-card>
< !--放入组件,如不知道父组件如何向子组件传值的,也可以好好看看
:exportExceltype 指子组件中的 props: ["exportExceltype"]
excelobj 则就是当前父组件中的data里面的属性,并指定了固定值-->
<ImportAndExport :exportExceltype="excelobj"></ImportAndExport>
</div>
</template>
<script>
//导入导出excel
import ImportAndExport from '@/components/common/ImportAndExport'
export default {
name: "UserProfile",
components: { ImportAndExport },
data() {
return {
excelobj:'user',//指定当前组件导入导出的标识,传入子组件即导入导出组件中判断
};
},
};
</script>
<style scoped></style>
这里我只保留了需要的代码,其他代码无关紧要,详细看注释,很简单的东西我也写得很详细了。。。
至此,前端部分已经完成,现在我讲一下导出思路:由前端通过判断不同页面需要导出的请求路径,然后通过设置请求方式、参数。像后端发起请求,后端通过easypoi的工具方法、注解。生成需要的excel或者word文档,然后给前端响应返回。前端再进行接收处理,并进行下载。
如果是,实现导入的话,思路也一样,只不过后端处理稍微变化了。(实质上也就是将数据库的数据组成list或者map然后交给easypoi处理)。
3.后端springboot
首先引入easypoi所需依赖:
<!--easypoi导入导出-->
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
<version>4.1.3</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-web</artifactId>
<version>4.1.3</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-annotation</artifactId>
<version>4.1.3</version>
</dependency>
或者使用这个:
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-spring-boot-starter</artifactId>
<version>4.0.0</version>
</dependency>
3.1编写实体类(我这里是dto,也一样)
package top.wangxingjun.separate.dto;
import cn.afterturn.easypoi.excel.annotation.Excel;
import top.wangxingjun.separate.dto.base.OutputConverter;
import top.wangxingjun.separate.entity.AdminRole;
import top.wangxingjun.separate.entity.User;
import lombok.Data;
import lombok.ToString;
import java.util.List;
/**
* @author wxj
* @Date 2020/8/10
*/
@Data
@ToString
public class UserDTO implements OutputConverter<UserDTO, User> {
@Excel(name = "编号")
private int id;
@Excel(name = "账号")
private String username;
@Excel(name = "真实姓名")
private String name;
@Excel(name = "手机号")
private String phone;
@Excel(name = "邮箱")
private String email;
@Excel(name = "状态",replace = {"启用_true","禁用_false"})
private boolean enabled;
}
这里使用了 @Excel 是关键注解,必不可少,name表示指定生成的excel的对应列明,replace 则表示用来做转换的,如:数据库表的性别字段,数据库字段值使用0或1表示,而前台需要显示男或女,导出的话,格式是 replace = {“前台显示值_数据库字段值”,“前台显示值_数据库字段值”} 用 _ 隔开。如果是导出,把前台显示值与数据库字段值调换下位置就可以了~更多用法请求官方文档查看或者百度使用。
3.2控制层
直接看代码:
/**
* 用户信息导出
*/
@GetMapping("api/exportUser")
public void exportUser(HttpServletResponse response) throws Exception {
List<UserDTO> list = userService.list();
ExcelUtil.exportExcel(list, null, "sheet1", UserDTO.class, "用户信息", response);
}
没错,就这么几行代码,当然了,还要有个工具类,是我封装好的,网上也有很多的咯。下面看工具类:
package top.wangxingjun.separate.util;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import lombok.extern.log4j.Log4j2;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
/**
* @ProjectName: separate
* @Package: top.wangxingjun.separate.util
* @ClassName: ExcelUtil
* @Author: wxj
* @Description: Excel导入导出工具类
* @Date: 2020/8/25 10:07
* @Version: 1.0
*/
@Log4j2
public class ExcelUtil {
/**
* Map集合导出
*
* @param list 需要导出的数据
* @param fileName 导出的文件名
* @param response HttpServletResponse对象
*/
public static void exportExcel(List<Map<String, Object>> list, String fileName, HttpServletResponse response) throws Exception{
defaultExport(list, fileName, response);
}
/**
* 复杂导出Excel,包括文件名以及表名(不创建表头)
*
* @param list 需要导出的数据
* @param title 表格首行标题(不需要就传null)
* @param sheetName 工作表名称
* @param pojoClass 映射的实体类
* @param fileName 导出的文件名(如果为null,则默认文件名为当前时间戳)
* @param response HttpServletResponse对象
*/
public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName,
HttpServletResponse response) throws Exception{
defaultExport(list, pojoClass, fileName, response, new ExportParams(title, sheetName));
}
/**
* 复杂导出Excel,包括文件名以及表名(创建表头)
*
* @param list 需要导出的数据
* @param title 表格首行标题(不需要就传null)
* @param sheetName 工作表名称
* @param pojoClass 映射的实体类
* @param fileName 导出的文件名
* @param isCreateHeader 是否创建表头
* @param response HttpServletResponse对象
*/
public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName,
boolean isCreateHeader, HttpServletResponse response) throws Exception{
ExportParams exportParams = new ExportParams(title, sheetName);
exportParams.setCreateHeadRows(isCreateHeader);
defaultExport(list, pojoClass, fileName, response, exportParams);
}
/**
* 默认导出方法
*
* @param list 需要导出的数据
* @param pojoClass 对应的实体类
* @param fileName 导出的文件名
* @param response HttpServletResponse对象
* @param exportParams 导出参数实体
*/
private static void defaultExport(List<?> list, Class<?> pojoClass, String fileName, HttpServletResponse response,
ExportParams exportParams) throws Exception{
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
downloadExcel(fileName, workbook, response);
}
/**
* 默认导出方法
*
* @param list Map集合
* @param fileName 导出的文件名
* @param response HttpServletResponse对象
*/
private static void defaultExport(List<Map<String, Object>> list, String fileName, HttpServletResponse response)throws Exception {
Workbook workbook = ExcelExportUtil.exportExcel(list, ExcelType.HSSF);
if (null != workbook) {
downloadExcel(fileName, workbook, response);
}
}
/**
* Excel导出
*
* @param fileName Excel导出
* @param workbook Excel对象
* @param response HttpServletResponse对象
*/
public static void downloadExcel(String fileName, Workbook workbook, HttpServletResponse response) throws Exception{
try {
if (StringUtils.isEmpty(fileName)) {
throw new RuntimeException("导出文件名不能为空");
}
String encodeFileName = URLEncoder.encode(fileName, "UTF-8");
response.setHeader("content-Type", "application/vnd.ms-excel; charset=utf-8");
response.setHeader("Content-Disposition", "attachment;filename=" + encodeFileName);
response.setHeader("FileName", encodeFileName);
response.setHeader("Access-Control-Expose-Headers", "FileName");
workbook.write(response.getOutputStream());
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
/**
* 根据文件路径来导入Excel
*
* @param filePath 文件路径
* @param titleRows 表标题的行数
* @param headerRows 表头行数
* @param pojoClass 映射的实体类
* @return
*/
public static <T> List<T> importExcel(String filePath, Integer titleRows, Integer headerRows, Class<T> pojoClass) throws Exception{
//判断文件是否存在
if (StringUtils.isBlank(filePath)) {
return null;
}
ImportParams params = new ImportParams();
params.setTitleRows(titleRows);
params.setHeadRows(headerRows);
List<T> list = null;
try {
list = ExcelImportUtil.importExcel(new File(filePath), pojoClass, params);
} catch (NoSuchElementException e) {
log.error("模板不能为空", e);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return list;
}
/**
* 根据接收的Excel文件来导入Excel,并封装成实体类
*
* @param file 上传的文件
* @param titleRows 表标题的行数
* @param headerRows 表头行数
* @param pojoClass 映射的实体类
* @return
*/
public static <T> List<T> importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class<T> pojoClass) throws Exception{
if (file == null) {
return null;
}
ImportParams params = new ImportParams();
params.setTitleRows(titleRows);
params.setHeadRows(headerRows);
List<T> list = null;
try {
list = ExcelImportUtil.importExcel(file.getInputStream(), pojoClass, params);
} catch (NoSuchElementException e) {
log.error("excel文件不能为空", e);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return list;
}
/**
* 文件转List
*
* @param file
* @param pojoClass
* @param <T>
* @return
*/
public static <T> List<T> fileToList(MultipartFile file, Class<T> pojoClass) throws Exception{
if (file.isEmpty()) {
throw new RuntimeException("文件为空");
}
List<T> list = ExcelUtil.importExcel(file, 1, 1, pojoClass);
if (CollectionUtils.isEmpty(list)) {
throw new RuntimeException("未解析到表格数据");
}
return list;
}
}
excel导出所需要的都准备好了,下面来看一下我的效果:

结尾
好了今天的分享就到这里了,结束~~
vue springboot利用easypoi实现简单导出的更多相关文章
- java利用EasyPoi实现Excel导出功能
easypoi功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员 就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解和模板 语言( ...
- 使用springboot和easypoi进行的数据导出的小案例
在这个案例中使用的有springboot和easypoi进行数据导出到excel中 yml文件是这样的: server: port: 8080 spring: datasource: url: jdb ...
- SpringBoot图文教程10—模板导出|百万数据Excel导出|图片导出「easypoi」
有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1「概念+ ...
- SpringBoot使用Easypoi导出excel示例
SpringBoot使用Easypoi导出excel示例 https://blog.csdn.net/justry_deng/article/details/84842111
- 使用VUE+SpringBoot+EasyExcel 整合导入导出数据
使用VUE+SpringBoot+EasyExcel 整合导入导出数据 创建一个普通的maven项目即可 项目目录结构 1 前端 存放在resources/static 下 index.html &l ...
- 超详细,新手都能看懂 !使用SpringBoot+Dubbo 搭建一个简单的分布式服务
来自:JavaGuide Github 地址:https://github.com/Snailclimb/springboot-integration-examples 目录: 使用 SpringBo ...
- 使用 SpringBoot+Dubbo 搭建一个简单分布式服务
实战之前,先来看几个重要的概念 开始实战之前,我们先来简单的了解一下这样几个概念:Dubbo.RPC.分布式.由于本文的目的是带大家使用SpringBoot+Dubbo 搭建一个简单的分布式服务,所以 ...
- springboot利用swagger构建api文档
前言 Swagger 是一款RESTFUL接口的文档在线自动生成+功能测试功能软件.本文简单介绍了在项目中集成swagger的方法和一些常见问题.如果想深入分析项目源码,了解更多内容,见参考资料. S ...
- 学习笔记:利用GDI+生成简单的验证码图片
学习笔记:利用GDI+生成简单的验证码图片 /// <summary> /// 单击图片时切换图片 /// </summary> /// <param name=&quo ...
随机推荐
- APP UI自动化测试思路总结
python+appium自动化测试系列就要告一段落了,本篇博客咱们做个小结. 首先想要说明一下,APP自动化测试可能很多公司不用,但也是大部分自动化测试工程师.高级测试工程师岗位招聘信息上要求的,所 ...
- EFCore之SQL扩展组件BeetleX.EFCore.Extension
EFCore是.NETCore团队开发的一个ORM组件,但这个组件在执行传统SQL的时候并不方便,因此BeetleX.EFCore.Extension的设计目的是让EFCore执行传 ...
- 使用RS485串口服务器的方法
1.为什么设备使用RS-485串口通信? RS-485设备可以连接到计算机,并在网络样式配置中的多个位置进行多次丢弃.在需要中继器之前,设备可以距离最远4000英尺(1220米),最多可以连接32个节 ...
- OpenCascade拓扑对象之:拓扑对象方向继承关系
@font-face { font-family: "Times New Roman" } @font-face { font-family: "宋体" } @ ...
- [P2114] [NOI2014]起床困难综合症 (位运算)
题面 传送门:https://www.luogu.org/problemnew/show/P2114 Solution 一道很有意思的位运算题. 要做这一题,我们首先得了解一个很重要的特点 位运算过程 ...
- 【CF1443E】Long Permutation 题解(排列生成模板)
原题链接 题意简介 给定一个长度为 n 的排列 {1,2,3,...,n} .现有两种操作: 对某个区间 [l,r] 求和 将排列往后推 x 次 (按字典序) 其中 \(n,q \leq 2\time ...
- 直播软件开发关于Android、iOS中的视频采集步骤
很多人对直播软件开发还是抱有想法的,但是在这个资本冷静的市场下,直播平台该怎么玩,在直播软件开发过程中哪些功能是必须具备的,这都是值得关注的话题.今天我们给大家分享一份详细的直播软件开发关于Andro ...
- sublime中插件
AllAutocomplete Emmet
- 【译】理解Rust中的闭包
原文标题:Understanding Closures in Rust 原文链接:https://medium.com/swlh/understanding-closures-in-rust-21f2 ...
- 对于STM32F103的USART的通讯调试
USART:(Universal Synchronous/Asynchronous Receiver/Transmitter)通用同步/异步串行接收/发送器USART是一个全双工通用同步/异步串行收发 ...