SpringBoot-EasyPoi
http://doc.wupaas.com/docs/easypoi/easypoi-1c10lpehvgv0j 官方文档
Easypoi 介绍
在项目中,有时会出现需要将数据库数据导出报表等功能,这时一般会用到poi库。poi是一个专门给Java程序提供格式文档读写功能的API接口,包括各种微软的格式文档入excel、word等。
最常用的还是处理Excel格式导入导出(其他都不咋地)。 Easypoi是在poi接口基础上进行了封装,简化了操作,基于注解的方式。
Maven
SpringBoot的Maven
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-spring-boot-starter</artifactId>
<version>4.0.0</version>
</dependency
普通项目的Maven
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-web</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-annotation</artifactId>
<version>4.1.0</version>
</dependency>
excel实体类(重点)
@Excel的各个参数可介绍
属性 | 类型 | 默认值 | 功能 |
---|
name | String | null | 列名,支持name_id | needMerge | boolean | fasle | 是否需要纵向合并单元格(用于含有list中,单个的单元格,合并list创建的多个row) | orderNum | String | “0” | 列的排序,支持name_id | replace | String[] | {} | 值得替换 导出是{a_id,b_id} 导入反过来 | savePath | String | “upload” | 导入文件保存路径,如果是图片可以填写,默认是upload/className/ IconEntity这个类对应的就是upload/Icon/ | type | int | 1 | 导出类型 1 是文本 2 是图片,3 是函数,10 是数字 默认是文本 | width | double | 10 | 列宽 | height | double | 10 | 列高,后期打算统一使用@ExcelTarget的height,这个会被废弃,注意 | isStatistics | boolean | fasle | 自动统计数据,在追加一行统计,把所有数据都和输出[这个处理会吞没异常,请注意这一点] | isHyperlink | boolean | false | 超链接,如果是需要实现接口返回对象 | isImportField | boolean | true | 校验字段,看看这个字段是不是导入的Excel中有,如果没有说明是错误的Excel,读取失败,支持name_id | exportFormat | String | “” | 导出的时间格式,以这个是否为空来判断是否需要格式化日期 | importFormat | String | “” | 导入的时间格式,以这个是否为空来判断是否需要格式化日期 | format | String | “” | 时间格式,相当于同时设置了exportFormat 和 importFormat | databaseFormat | String | “yyyyMMddHHmmss” | 导出时间设置,如果字段是Date类型则不需要设置 数据库如果是string 类型,这个需要设置这个数据库格式,用以转换时间格式输出 | numFormat | String | “” | 数字格式化,参数是Pattern,使用的对象是DecimalFormat | imageType | int | 1 | 导出类型 1 从file读取 2 是从数据库中读取 默认是文件 同样导入也是一样的 | suffix | String | “” | 文字后缀,如% 90 变成90% | isWrap | boolean | true | 是否换行 即支持\n | mergeRely | int[] | {} | 合并单元格依赖关系,比如第二列合并是基于第一列 则{0}就可以了 | mergeVertical | boolean | fasle | 纵向合并内容相同的单元格 | fixedIndex | int | -1 | 对应excel的列,忽略名字 | isColumnHidden | boolean | false | 导出隐藏列 |
下面我们创建2个用例:
package com.easypoi.pojo;
import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class User {
@Excel(name = "用户名")
private String username;
@Excel(name = "姓名")
private String name;
@Excel(name = "年龄")
private Integer age;
@Excel(name = "性别",replace = {"男_0", "女_1"})
private String sex;
@Excel(name = "籍贯")
private String address;
}
package com.easypoi.pojo;
import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Company {
@Excel(name = "公司名称",width =20)
private String name;
@Excel(name = "公司logo",width =20,type = 2,imageType = 1)
private String logo;
@Excel(name = "公司介绍",width =100)
private String dec;
}
excel样式
package com.easypoi.utils;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.afterturn.easypoi.excel.entity.params.ExcelForEachParams;
import cn.afterturn.easypoi.excel.export.styler.IExcelExportStyler;
import org.apache.poi.ss.usermodel.*;
public class ExcelStyleUtil implements IExcelExportStyler {
private static final short STRING_FORMAT = (short) BuiltinFormats.getBuiltinFormat("TEXT");
private static final short FONT_SIZE_TEN = 9;
private static final short FONT_SIZE_ELEVEN = 12;
private static final short FONT_SIZE_TWELVE = 15;
private CellStyle headerStyle;
private CellStyle titleStyle;
private CellStyle styles;
public ExcelStyleUtil(Workbook workbook) {
this.init(workbook);
}
private void init(Workbook workbook) {
this.headerStyle = initHeaderStyle(workbook);
this.titleStyle = initTitleStyle(workbook);
this.styles = initStyles(workbook);
}
@Override
public CellStyle getHeaderStyle(short color) {
return headerStyle;
}
@Override
public CellStyle getTitleStyle(short color) {
return titleStyle;
}
@Override
public CellStyle getStyles(boolean parity, ExcelExportEntity entity) {
return styles;
}
@Override
public CellStyle getStyles(Cell cell, int dataRow, ExcelExportEntity entity, Object obj, Object data) {
return getStyles(true, entity);
}
@Override
public CellStyle getTemplateStyles(boolean isSingle, ExcelForEachParams excelForEachParams) {
return null;
}
private CellStyle initHeaderStyle(Workbook workbook) {
CellStyle style = getBaseCellStyle(workbook);
style.setFont(getFont(workbook, FONT_SIZE_TWELVE, true));
return style;
}
private CellStyle initTitleStyle(Workbook workbook) {
CellStyle style = getBaseCellStyle(workbook);
style.setFont(getFont(workbook, FONT_SIZE_ELEVEN, false));
style.setFillForegroundColor(IndexedColors.SEA_GREEN.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
return style;
}
private CellStyle initStyles(Workbook workbook) {
CellStyle style = getBaseCellStyle(workbook);
style.setFont(getFont(workbook, FONT_SIZE_TEN, false));
style.setDataFormat(STRING_FORMAT);
return style;
}
private CellStyle getBaseCellStyle(Workbook workbook) {
CellStyle style = workbook.createCellStyle();
style.setBorderBottom(BorderStyle.THIN);
style.setBorderLeft(BorderStyle.THIN);
style.setBorderTop(BorderStyle.THIN);
style.setBorderRight(BorderStyle.THIN);
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setWrapText(true);
return style;
}
private Font getFont(Workbook workbook, short size, boolean isBold) {
Font font = workbook.createFont();
font.setFontName("宋体");
font.setBold(isBold);
font.setFontHeightInPoints(size);
return font;
}
}
excel导入导出工具类
package com.easypoi.utils;
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.TemplateExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.hutool.core.util.StrUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
public class ExcelUtils {
private static final Integer EXPORT_EXCEL_MAX_NUM = 10000;
public static void exportExcel(List<Map<String, Object>> list, String fileName, HttpServletResponse response) throws IOException {
defaultExport(list, fileName, response);
}
private static void defaultExport(List<Map<String, Object>> list, String fileName, HttpServletResponse response) throws IOException {
Workbook workbook = ExcelExportUtil.exportExcel(list, ExcelType.HSSF);
downLoadExcel(fileName, response, workbook);
}
private static void defaultExport(List<?> list, Class<?> pojoClass, String fileName, HttpServletResponse response, ExportParams exportParams) throws IOException {
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
downLoadExcel(fileName, response, workbook);
}
public static void exportExcel(List<?> list, Class<?> pojoClass, String fileName, ExportParams exportParams, HttpServletResponse response) throws IOException {
defaultExport(list, pojoClass, fileName, response, exportParams);
}
public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, HttpServletResponse response) throws IOException {
SimpleDateFormat formatter = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss");
String dateString = formatter.format (new Date());
fileName = fileName + dateString;
if (list == null) {
list = new ArrayList<>();
}
if (list.size() > EXPORT_EXCEL_MAX_NUM) {
title = "导出数据行数超过:" + EXPORT_EXCEL_MAX_NUM + "条,无法导出、请添加导出条件!";
list = new ArrayList<>();
}
ExportParams exportParams = new ExportParams(title, sheetName, ExcelType.XSSF);
exportParams.setStyle(ExcelStyleUtil.class);
exportParams.setHeight((short) 6);
defaultExport(list, pojoClass, fileName, response, exportParams);
}
public static void exportExcel(TemplateExportParams templatePath, Map<String, Object> map, String fileName, HttpServletResponse response) throws IOException {
Workbook workbook = ExcelExportUtil.exportExcel(templatePath, map);
downLoadExcel(fileName, response, workbook);
}
private static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) throws IOException {
try {
response.setCharacterEncoding("UTF-8");
response.setHeader("content-Type", "application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".xlsx", "UTF-8"));
workbook.setForceFormulaRecalculation(true);
workbook.write(response.getOutputStream());
} catch (Exception e) {
throw new IOException(e.getMessage());
}
}
public static <T> List<T> importExcel(MultipartFile file, Class<T> pojoClass) throws IOException {
return importExcel(file, 1, 1, pojoClass);
}
public static <T> List<T> importExcel(String filePath, Integer titleRows, Integer headerRows, Class<T> pojoClass) throws IOException {
if (StringUtils.isBlank(filePath)) {
return null;
}
ImportParams params = new ImportParams();
params.setTitleRows(titleRows);
params.setHeadRows(headerRows);
params.setNeedSave(true);
params.setSaveUrl("/excel/");
try {
return ExcelImportUtil.importExcel(new File(filePath), pojoClass, params);
} catch (NoSuchElementException e) {
throw new IOException("模板不能为空");
} catch (Exception e) {
throw new IOException(e.getMessage());
}
}
public static <T> List<T> importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class<T> pojoClass) throws IOException {
if (file == null) {
return null;
}
try {
return importExcel(file.getInputStream(), titleRows, headerRows, pojoClass);
} catch (Exception e) {
throw new IOException(e.getMessage());
}
}
public static <T> List<T> importExcel(InputStream inputStream, Integer titleRows, Integer headerRows, Class<T> pojoClass) throws IOException {
if (inputStream == null) {
return null;
}
ImportParams params = new ImportParams();
params.setTitleRows(titleRows);
params.setHeadRows(headerRows);
params.setSaveUrl("/excel/");
params.setNeedSave(true);
try {
return ExcelImportUtil.importExcel(inputStream, pojoClass, params);
} catch (NoSuchElementException e) {
throw new IOException("excel文件不能为空");
} catch (Exception e) {
throw new IOException(e.getMessage());
}
}
测试接口
package com.easypoi.controller;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import com.easypoi.pojo.Company;
import com.easypoi.pojo.User;
import com.easypoi.utils.ExcelUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
@RestController
@RequestMapping("/easypoi")
public class EasypoiController {
@RequestMapping(value = "/import", method = RequestMethod.POST)
public ResponseEntity<String> importExcel(@RequestParam("file") MultipartFile file) throws IOException {
List<User> list = ExcelUtils.importExcel(file, User.class);
return ResponseEntity.ok( "导入成功");
}
@GetMapping("/exportExcel")
public void exportExcel( HttpServletResponse response) throws IOException {
List<User> list=new ArrayList<User>(){{
add(User.builder().username("我是大白鲨").age(12).name("胡安民").sex("0").address("北京市").build());
add(User.builder().username("我是大白鲨1").age(12).name("胡安民1").sex("1").address("北京市1").build());
add(User.builder().username("我是大白鲨1").age(12).name("胡安民1").sex("男").address("北京市1").build());
}};
ExcelUtils.exportExcel(list, "用户信息统计表Title", "用户表Sheet", User.class, "用户信息统计File", response);
}
@GetMapping("/imgexport")
public void imgExport(HttpServletResponse response) throws IOException {
List<Company> list = new ArrayList<>();
list.add(new Company("百度", "E:/img/1.jpg", "百度一下你就知道"));
list.add(new Company("腾讯", "E:/img/3.jpg", "腾讯qq,交流的世界"));
list.add(new Company("阿里巴巴", "E:/img/2.jpg", "阿里巴巴,马云的骄傲"));
ExcelUtils.exportExcel(list, "图片excelTile", "图片excelSheet", Company.class, "图片excelFile", response);
}
@PostMapping("/imgimport")
public ResponseEntity imgImport(@RequestParam("file") MultipartFile file) throws IOException {
List<Company> list = ExcelUtils.importExcel(file, Company.class);
return ResponseEntity.ok("导入成功:"+list);
}
@GetMapping("/excelTemplate")
public void makeExcelTemplate(HttpServletResponse response) throws Exception {
List<User> list=new ArrayList<User>(){{
add(User.builder().username("我是大白鲨").age(12).name("胡安民").sex("0").address("北京市").build());
add(User.builder().username("我是大白鲨1").age(12).name("胡安民1").sex("1").address("北京市1").build());
add(User.builder().username("我是大白鲨1").age(12).name("胡安民1").sex("男").address("北京市1").build());
}};
TemplateExportParams templatePath = new TemplateExportParams("E:/test.xlsx");
Map<String, Object> map = new HashMap<>();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
map.put("date", sdf.format(new Date()));
map.put("user", "admin");
map.put("userList", list);
ExcelUtils.exportExcel(templatePath, map, "使用模板excel导出File", response);
}
}
application.yml
server:
port: 1011
spring:
main:
allow-bean-definition-overriding: true
datasource:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/voidme?useUnicode=true&characterEncoding=utf8&autoReconnect=true&failOverReadOnly=false&serverTimezone=UTC
username: root
password: root
hikari.idle-timeout: 60000
hikari.maximum-pool-size: 30
hikari.minimum-idle: 10
mybatis:
type-aliases-package: com.easypoi.pojo
mapper-locations: classpath:mybaitis/*Mapper.xml
configuration:
map-underscore-to-camel-case: true
启动类
package com.easypoi;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableAsync
public class EasypoiAppllication {
public static void main(String[] args) {
SpringApplication.run(EasypoiAppllication.class,args);
}
}
效果图
导出效果图
带图片的导出效果图
使用模板excel导出效果图
使用模板excel导出,@Excel注解(无效) 这个是BUG占时官方没有解决
excel模板导出规则
在上面我们已经提供了接口了, 但是excel的模板格式 和规则是什么呢???
在两个大括号里写对应的数据名称。
$fe用来遍历数据 , : list数据源 (变量默认t,不需要写)
{{$fe: maplist t.id }}
http://doc.wupaas.com/docs/easypoi/easypoi-1c10lfhut694k (官方,一般不建议使用代码操作太复杂的表格了)
点赞 -收藏-关注-便于以后复习和收到最新内容
有其他问题在评论区讨论-或者私信我-收到会在第一时间回复
如有侵权,请私信联系我
感谢,配合,希望我的努力对你有帮助^_^
|