SpringBoot+EasyPoi实现excel导出功能

网友投稿 738 2022-12-09

SpringBoot+EasyPoi实现excel导出功能

SpringBoot+EasyPoi实现excel导出功能

在实际项目开发中,对于Excel的导入导出还是很常见的需求,比如说将数据根据模板批量导入到数据库中,以及将数据库中的数据批量导出陈Excel的形式

现有需求: 根据检索条件查询列表并将结果导出到excel

Easypoi文档:https://easypoi.mydoc.io/#text_186900

EasyPoi的主要特点

1.设计精巧,使用简单

2.接口丰富,扩展简单

3.默认值多,write less do more

4.spring mvc支持,web导出可以简单明了

实现过程

1.创建一个Spring Boot项目

快速生成链接:start.spring.io

2.引入EasyPoi的pom依赖

cn.afterturn

easypoi-base

4.3.0

cn.afterturn

easypoi-web

4.3.0

cn.afterturn

easypoi-annotation

4.3.0

easypoi-base 导入导出的工具包,可以完成Excel导出,导入,Word的导出,Excel的导出功能

easypoi-web 耦合了spring-mvc 基于AbstractView,极大的简化spring-mvc下的导出功能

easypoi-annotation 基础注解包,作用与实体对象上,拆分后方便maven多工程的依赖管理

sax 导入使用xercesImpl这个包(这个包可能造成奇怪的问题哈),word导出使用poi-scratchpad,都作为可选包了

pom.xml中的所有依赖:

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-devtools

runtime

true

org.projectlombok

lombok

true

org.springframework.boot

spring-boot-starter-test

test

com.baomidou

mybatis-plus-boot-starter

3.4.3

mysql

mysql-connector-java

qJvqcwxm runtime

com.alibaba

druid

1.1.20

com.alibaba

druid-spring-boot-starter

1.1.20

io.springfox

springfox-swagger2

2.9.2

io.swagger

swagger-models

io.springfox

springfox-swagger-ui

2.9.2

io.swagger

swagger-models

1.5.21

cn.afterturn

easypoi-base

4.3.0

cn.afterturn

easypoi-web

4.3.0

cn.afterturn

easypoi-annotation

4.3.0

com.alibaba

fastjson

1.2.71

3.编写excel工具类

package com.example.easypoiexceldemo.utils;

import cn.afterturn.easypoi.excel.ExcelExportUtil;

import cn.afterturn.easypoi.excel.entity.ExportParams;

import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;

import org.apache.commons.lang3.StringUtils;

import org.apache.poi.ss.usermodel.Workbook;

import org.springframework.beans.BeanUtils;

import javax.servlet.ServletOutputStream;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

import java.net.URLEncoder;

import java.text.SimpleDateFormat;

import java.util.ArrayList;

import java.util.Collection;

import java.util.Date;

import java.util.List;

/**

* excel工具类

* @author qzz

*/

public class ExcelUtils {

/**

* Excel导出

*

* @param response response

* @param fileName 文件名

* @param list 数据List

* @param pojoClass 对象Class

*/

public static void exportExcel(HttpServletResponse response, String fileName, Collection> list, Class> pojoClass) throws IOException {

if (StringUtils.isBlank(fileName)) {

//当前日期

SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");

fileName = df.format(new Date());

}

Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(fileName, fileName, ExcelType.HSSF), pojoClass, list);

response.setCharacterEncoding("UTF-8");

response.setHeader("content-Type", "application/vnd.ms-excel");

response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xls");

ServletOutputStream out = response.getOutputStream();

workbook.write(out);

out.flush();

}

/**

* Excel导出,先sourceList转换成List,再导出

*

* @param response response

* @param fileName 文件名

* @param sourceList 原数据List

* @param targetClass 目标对象Class

*/

public static void exportExcelToTarget(HttpServletResponse response, String fileName, Collection> sourceList, Class> targetClass) throws Exception {

List targetList = new ArrayList<>(sourceList.size());

for (Object source : sourceList) {

Object target = targetClass.newInstance();

BeanUtils.copyProperties(source, target);

targetList.add(target);

}

exportExcel(response, fileName, targetList, targetClass);

}

/**

* Excel导出----设置title---sheetName---要求Collection> list是Class> pojoClass类型的

*

* @param response response

* @param fileName 文件名

* @param list 数据List

* @param pojoClass 对象Class

*/

public static void exportExcel(HttpServletResponse response, String title, String sheetName, String fileName, Collection> list, Class> pojoClass) throws IOException {

if (StringUtils.isBlank(fileName)) {

//当前日期

SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");

fileName = df.format(new Date());

}

Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(title, sheetName, ExcelType.HSSF), pojoClass, list);

response.setCharacterEncoding("UTF-8");

response.setHeader("content-Type", "application/vnd.ms-excel");

response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xls");

ServletOutputStream out = response.getOutputStream();

workbook.write(out);

out.flush();

}

}

4.在实体类上加注解@Excel

我这边使用了lombok。getter setter和构造方法通过注解 @Data @AllArgsConstructor进行添加,不使用lombok也可手动添加。

要导出的数据可在实体类对应属性上方加**@Excel()注解**。可定义导出列的名称、宽度,以及性别可区分化(一般数据库中存储的性别为1和2),日期格式化等等。

package com.example.easypoiexceldemo.excel;

import cn.afterturn.easypoi.excel.annotation.Excel;

import lombok.Data;

import java.util.Date;

/**

* 商品

* @author qzz

*/

@Data

public class ProductExcel {

/**

* 商品id

*/

@Excel(name = "商品id")

private Integer product_id;

/**

* 商品标题

*/

@Excel(name="商品标题")

private String title;

/**

* 商品副标题

*/

@Excel(name="商品副标题")

private String sub_title;

/**

* 商品售价

*/

@Excel(name="商品售价")

private Double sale_price;

/**

* 创建者

*/

@Excel(name="创建者")

private Integer create_by;

/**

* 创建时间

*/

@Excel(name="创建时间", format = "yyyy-MM-dd")

private Date create_time;

/**

* 修改时间

*/

@Excel(name="修改时间", format = "yyyy-MM-dd")

private Date update_time;

/**

* 修改者id

*/

@Excel(name="修改者id")

private Integer update_by;

}

@Excel 作用到filed上面,是对Excel一列的一个描述

@Excel 的属性介绍:

5.Controller

/**

* excel导出

* @param response

*/

@GetMapping("/excel")

@ApiOperation("根据检索条件查询列表,导出excel")

public void export( HttpServletResponse response) throws IOException {

//根据条件检索列表

QueryWrapper queryWrapper = new QueryWrapper();

//根据条件检索商品列表

List> list = productService.selectList(queryWrapper);

//将List>结果集转换成List

List productList = MapToEntity.setList(list,ProductExcel.class);

//导出excel

ExcelUtils.exportExcel(response,null,productList, ProductExcel.class);

}

setList方法为工具类,用于将List>结果集转换成List

MapToEntity工具类:

package com.example.easypoiexceldemo.utils;

import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;

import java.math.BigDecimal;

import java.text.ParseException;

import java.text.ParsePosition;

import java.text.SimpleDateFormat;

import java.util.ArrayList;

import java.util.Date;

import java.util.List;

import java.util.Map;

/**

* List>到List数据转换

* @author qzz

*/

public class MapToEntity {

/**

* List> 到 List 数据转换

*/

public static List setList(final List> srcList, Class clazz) {

List list = new ArrayList<>();

for (int i=0;i

try {

T t = clazz.newInstance();

Field[] fields = t.getClass().getDeclaredFields();

for (Field field : fields) {

if (!"serialVersionUID".equals(field.getName())) {

//设置对象的访问权限,保证对private的属性的访问

field.setAccessible(true);

//读取配置转换字段名,并从map中取出数据

Object v = srcList.get(i).get(field.getName());

field.set(t, convert(v, field.getType()));

}

}

list.add(t);

} catch (Exception ex) {

ex.toString();

}

};

return list;

}

/**

* 字段类型转换

*/

private static T convert(Object obj, Class type) throws ParseException {

if (obj != null && StringUtils.isNotBlank(obj.toString())) {

if (type.equals(String.class)) {

return (T) obj.toString();

} else if (type.equals(BigDecimal.class)) {

return (T) new BigDecimal(obj.toString());

}else if(type.equals(Double.class)){

return (T) Double.valueOf(obj.toString());

}else if(type.equals(Integer.class)){

return (T) Integer.valueOf(obj.toString());

}else if(type.equals(Date.class)){

if(obj!=null){

String timeStr = String.valueOf(obj);

String s[] = timeStr.split("T");

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

return (T) sdf.parse(s[0]+" "+s[1]);

}else{

return null;

}

}

else{

//其他类型转换

return (T) obj.toString();

}

}

return null;

}

}

6.启动项目,进行测试

项目启动成功后,在浏览器中输入 http://localhost:8083/product/excel,进行访问:

打开导出的excel文档:

try {

T t = clazz.newInstance();

Field[] fields = t.getClass().getDeclaredFields();

for (Field field : fields) {

if (!"serialVersionUID".equals(field.getName())) {

//设置对象的访问权限,保证对private的属性的访问

field.setAccessible(true);

//读取配置转换字段名,并从map中取出数据

Object v = srcList.get(i).get(field.getName());

field.set(t, convert(v, field.getType()));

}

}

list.add(t);

} catch (Exception ex) {

ex.toString();

}

};

return list;

}

/**

* 字段类型转换

*/

private static T convert(Object obj, Class type) throws ParseException {

if (obj != null && StringUtils.isNotBlank(obj.toString())) {

if (type.equals(String.class)) {

return (T) obj.toString();

} else if (type.equals(BigDecimal.class)) {

return (T) new BigDecimal(obj.toString());

}else if(type.equals(Double.class)){

return (T) Double.valueOf(obj.toString());

}else if(type.equals(Integer.class)){

return (T) Integer.valueOf(obj.toString());

}else if(type.equals(Date.class)){

if(obj!=null){

String timeStr = String.valueOf(obj);

String s[] = timeStr.split("T");

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

return (T) sdf.parse(s[0]+" "+s[1]);

}else{

return null;

}

}

else{

//其他类型转换

return (T) obj.toString();

}

}

return null;

}

}

6.启动项目,进行测试

项目启动成功后,在浏览器中输入 http://localhost:8083/product/excel,进行访问:

打开导出的excel文档:

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java单例的写法详解
下一篇:Java并发编程之阻塞队列(BlockingQueue)详解
相关文章

 发表评论

暂时没有评论,来抢沙发吧~