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 ...
随机推荐
- Redis集群环境搭建实践
0 Redis集群简介 Redis集群(Redis Cluster)是Redis提供的分布式数据库方案,通过分片(sharding)来进行数据共享,并提供复制和故障转移功能.相比于主从复制.哨兵模式, ...
- SQL SERVER迁移--更换磁盘文件夹
默认情况下SQL SERVER的安装路径与数据库的默认存放路径是在C盘的--这就很尴尬. 平时又不注意,有天发现C盘的剩余空间比较吃紧了,于是着手想办法迁移文件夹. 一.环境准备 数据库版本--SQL ...
- JUC---13各种锁
一.公平锁与非公平锁 公平锁:加锁前检查是否有排队等待的线程,优先排队等待的线程,先来先得 非公平锁:加锁时不考虑排队等待问题,直接尝试获取锁,获取不到自动到队尾等待 非公平锁性能比公平锁高5~10倍 ...
- C#基础访问修饰符概述
前言: 在编写面向对象语言时我们时长离不开相关类型和成员的相关访问性,而访问性的关键则是取决于访问修饰符的声明,其作用是用于指定类型或成员的可访问性. 访问修饰符的六种可访问性级别: public:共 ...
- python框架Django中MTV框架之VIew(业务控制器)
MTV框架之VIew(业务控制器) 关注公众号"轻松学编程"了解更多. 1.什么是视图 视图层=路由表(urls.py)+视图函数(views.py) 其角色相当于MVC中的Con ...
- 【Java GC系列】垃圾收集简介(1)
说明: 在本文中, Garbage Collection 翻译为 "垃圾收集", garbage collector 翻译为 "垃圾收集器"; 一般认为, 垃圾 ...
- 我的 Redis 被入侵了
好吧,我也做了回标题党,像我这么细心的同学,怎么可能让服务器被入侵呢? 其实是这样的,昨天我和一个朋友聊天,他说他自己有一台云服务器运行了 Redis 数据库,有一天突然发现数据库里的数据全没了,只剩 ...
- DP百题练(二)
目录 DP百题练(二) 区间 DP NOI1995 石子合并 IOI1998 Polygon CH5302 金字塔 USACO06FEB Treats for the Cows G/S LG1043 ...
- 使用 c++ 模板显示实例化解决模板函数声明与实现分离的问题
问题背景 开始正文之前,做一些背景铺垫,方便读者了解我的工程需求.我的项目是一个客户端消息分发中心,在连接上消息后台后,后台会不定时的给我推送一些消息,我再将它们转发给本机的其它桌面产品去做显示.后台 ...
- SQL存储过程返回值
1 SQL存储过程返回值有3种 1.1 直接return返回(例如 return 1): 1.2 通过参数output返回(例如字符串类型): 1.3 直接返回程序集(Dataset程序集). 2 用 ...