• Stars
    star
    429
  • Rank 101,271 (Top 2 %)
  • Language
    Java
  • License
    Apache License 2.0
  • Created over 4 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

本项目旨在为用户提供一个便捷的 Excel 导出解决方案。基于阿里巴巴的 EasyExcel 库,结合 Spring Boot 框架,封装并优化了 Excel 文件的导出流程,帮助开发者更高效地实现数据导出功能。

excel-spring-boot-starter

此项目底层基于 Easyexcel 实现 Excel 的读写。

EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。 64M内存1分钟内读取75M(46W行25列)的Excel,当然还有急速模式能更快,但是内存占用会在100M多一点

依赖引用

  • 项目已上传至 maven 仓库,直接引入即可使用
版本 支持
3.1.0 适配 SpringBoot3.x
1.2.7 适配 SpringBoot2.x
<dependency>
  <groupId>com.pig4cloud.excel</groupId>
  <artifactId>excel-spring-boot-starter</artifactId>
  <version>${lastVersion}</version>
</dependency>

导入 Excel

  • 接口类定义List 接受表格对应的数据 使用 @RequestExcel 标记
@PostMapping("/upload")
public void upload(@RequestExcel List<DemoData> dataList, BindingResult bindingResult) {
  // JSR 303 校验通用校验获取失败的数据
  List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
}
  • 实体声明
@Data
public class Demo {
  @ExcelProperty(index = 0)
  private String username;

  @ExcelProperty(index = 1)
  private String password;
}
  • 测试表格

导出 Excel

只需要在 Controller 层返回 List 并增加 @ResponseExcel注解即可

@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ResponseExcel {
  String name() default "";
  ExcelTypeEnum suffix() default ExcelTypeEnum.XLSX;
  String password() default "";
  Sheet[] sheets() default @Sheet(sheetName = "sheet1");
  boolean inMemory() default false;
  String template() default "";
  String[] include() default {};
  String[] exclude() default {};
  Class<? extends WriteHandler>[] writeHandler() default {};
  Class<? extends Converter>[] converter() default {};
  Class<? extends HeadGenerator> headGenerator() default HeadGenerator.class;
}

基础用法

  • 返回单 sheet, 全部字段导出
@ResponseExcel(name = "test", sheets = @Sheet(sheetName = "testSheet1"))
@GetMapping("/e1")
public List<DemoData> e1() {
    List<DemoData> dataList = new ArrayList<>();
    for (int i = 0; i < 100; i++) {
        DemoData data = new DemoData();
        data.setUsername("tr1" + i);
        data.setPassword("tr2" + i);
        dataList.add(data);
    }
    return dataList;
}

// 实体对象
@Data
public class DemoData {
	private String username;
	private String password;
}

  • 自定义字段属性
@Data
public class DemoData {
    @ColumnWidth(50)  // 定义宽度
	@ExcelProperty("用户名") // 定义列名称
    @ContentStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 40)
	private String username;
	@ExcelProperty("密码")
	private String password;
}

  • 忽略部分字段
@Data
public class DemoData {
    @ColumnWidth(50)  // 定义宽度
	@ExcelProperty("用户名") // 定义列名称
    @ContentStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 40)
	private String username;
	@ExcelIgnore // 忽略这个字段
	private String password;
}

导出并加密

@ResponseExcel(name = "lengleng", password = "lengleng")
@GetMapping("/e1")
public List<DemoData> e1() {
    return list();
}

导出多sheet

@ResponseExcel(name = "lengleng", sheets = {
    @Sheet(sheetName = "第一个Sheet"), 
    @Sheet(sheetName = "第二个sheet")
})
@GetMapping("/e1")
public List<List<DemoData>> e1() {
    List<List<DemoData>> lists = new ArrayList<>();
    lists.add(list());
    lists.add(list());
    return lists;
}

导出不同的 Sheet

这里两个 sheet 导出不同类型的对象,只导出 DemoData 中的 username 属性,且将 testData 中的 number 属性排除。

@Controller
@RequestMapping("public/excel")
public class ExportMultiSheetController {

	@ResponseExcel(name = "不同Sheet的导出", sheets = {
			@Sheet(sheetName = "demoData", includes = {"username"}),
			@Sheet(sheetName = "testData", excludes = {"number"})
	})
	@GetMapping("/different-sheet")
	public List<List> multiDifferent() {
		List<List> lists = new ArrayList<>();
		lists.add(demoDatalist());
		lists.add(testDatalist());
		return lists;
	}

	private List<DemoData> demoDatalist(){
		List<DemoData> dataList = new ArrayList<>();
		for (int i = 0; i < 100; i++) {
			DemoData data = new DemoData();
			data.setUsername("tr1" + i);
			data.setPassword("tr2" + i);
			dataList.add(data);
		}
		return dataList;
	}

	private List<TestData> testDatalist(){
		List<TestData> dataList = new ArrayList<>();
		for (int i = 0; i < 100; i++) {
			TestData data = new TestData();
			data.setStr("str" + i);
			data.setNumber(i);
			data.setLocalDateTime(LocalDateTime.now());
			dataList.add(data);
		}
		return dataList;
	}

	// 实体对象
	@Data
	public static class DemoData {
		private String username;
		private String password;
	}

	@Data
	public static class TestData {
		private String str;
		private Integer number;
		@ColumnWidth(50)  // 定义宽度
		private LocalDateTime localDateTime;
	}

}

导出不同的 Sheet

导出并自定义头信息

测试实体类:

@Data
public class SimpleData {
    @ExcelProperty("字符串标题")
    private String string;
    @ExcelProperty("日期标题")
    private Date date;
    @ExcelProperty("数字标题")
    private Integer number;
    // 忽略
    @ExcelIgnore
    private String ignore;
}

自定义头信息生成器

注意需要实现 HeadGenerator 接口,且注册为一个 spring bean.

@Component
public class SimpleDataHeadGenerator implements HeadGenerator {
    @Override
    public HeadMeta head(Class<?> clazz) {
        HeadMeta headMeta = new HeadMeta();
        headMeta.setHead(simpleDataHead());
        // 排除 number 属性
        headMeta.setIgnoreHeadFields(new HashSet<>(Collections.singletonList("number")));
        return headMeta;
    }

    private List<List<String>> simpleDataHead() {
        List<List<String>> list = new ArrayList<>();
        List<String> head0 = new ArrayList<>();
        head0.add("自定义字符串标题" + System.currentTimeMillis());
        List<String> head1 = new ArrayList<>();
        head1.add("自定义日期标题" + System.currentTimeMillis());
        list.add(head0);
        list.add(head1);
        return list;
    }
}

该头生成器,将固定返回 自定义字符串标题 和 自定义日期标题 两列头信息,实际使用时可根据业务动态处理,方便在一些权限控制时动态修改或者增删列头。

测试代码:

@RequestMapping("/head")
@RestController
public class ExcelHeadTestController {

    @ResponseExcel(name = "customHead", headGenerator = SimpleDataHeadGenerator.class)
    @GetMapping
    public List<SimpleData> multi() {
        List<SimpleData> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            SimpleData simpleData = new SimpleData();
            simpleData.setString("str" + i);
            simpleData.setNumber(i);
            simpleData.setDate(new Date());
            list.add(simpleData);
        }
        return list;
    }
}

自定义头信息

国际化的导入导出

国际化配置基于 Spring 的 MessageSource,开启国际化时,spring 容器中必须有一个 MessageSource 的 Bean。

具体 Spring

的国际化使用这里不再展开,想要了解的可以参看官方文档 Spring MessageSource 使用

以及 SpringBoot 国际化配置

首先在 resource 下,新建国际化配置文件

  • messages.properties

    DemoData.username=Username
    DemoData.age=Age
  • messages_en_US.properties

    DemoData.username=Username
    DemoData.age=Age
  • messages_zh_CN.properties

    DemoData.username=用户名
    DemoData.age=年龄

测试类的注解信息上,使用 {} 标记配置文件中的 key

@Data
public class DemoData {
	@ExcelProperty(value = "{DemoData.username}", index = 0)
	private String username;
	@ExcelProperty(value = "{DemoData.age}", index = 1)
	private Integer age;
}

**导出注解上设置 i18nHeader=true **

	@ResponseExcel(name = "i18nExport", i18nHeader = true)
	@GetMapping("excelExport")
	public List<DemoData> i18nExport() {
		List<DemoData> list = new ArrayList<>();
		for (int i = 0; i < 10; i++) {
			DemoData demoData = new DemoData();
			demoData.setUsername("username:" + i);
			demoData.setAge(i);
			list.add(demoData);
		}
		return list;
	}

使用 Postman 测试导出

请求头上使用 Accept-Language 指定当前语言区域,中文是 zh-CN, 英文是 en-US

SpringBoot 的国际化默认会读取请求头中的 Accept-Language 进行判断当前区域,可以通过定制 LocaleResolver 替换这一默认行为

导出效果

导出效果

导入 controller

注意,这里导入接受的对象如果和导出是同一个的话,由于列名是国际化配置的占位符,无法和实际上传文件进行对应,所以需要给该对象的属性指定 index,导入文件根据 index 进行数据映射。

当然,也可以使用额外的导入类来接收导入信息。

	@PostMapping("i18n")
	@ResponseBody
	public List<DemoData> importExcel(@RequestExcel List<DemoData> list) {
		return list;
	}
  • 导入获取excel 行号,实体属性增加 @ExcelLine 注解即可
/**
 * 导入时候回显行号
 */
@ExcelLine
@ExcelIgnore
private Long lineNum;

使用 Postman 测试导入

添加全局自定义转换器(Converter)

0.0.7 版本开始添加了全局自定义转换器注入的功能,你只需要将自定义的 Converter 注册成 Spring bean 即可。

示例代码如下(对 set 类型转换):

@Data
public class TestModel {
	@ExcelProperty("名称集合")
	private Set<String> nameSet;
}

/**
 * 集合转换器
 *
 * @author L.cm
 */
@Component
public class SetConverter implements Converter<Set<?>> {
	private final ConversionService conversionService;

	SetConverter() {
		this.conversionService = DefaultConversionService.getSharedInstance();
	}

	@Override
	public Class<?> supportJavaTypeKey() {
		return Set.class;
	}

	@Override
	public CellDataTypeEnum supportExcelTypeKey() {
		return CellDataTypeEnum.STRING;
	}

	@Override
	public Set<?> convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
		String[] value = StringUtils.delimitedListToStringArray(cellData.getStringValue(), ",");
		return (Set<?>) conversionService.convert(value, TypeDescriptor.valueOf(String[].class), new TypeDescriptor(contentProperty.getField()));
	}

	@Override
	public CellData<String> convertToExcelData(Set<?> value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
		return new CellData<>(StringUtils.collectionToCommaDelimitedString(value));
	}

}

高级用法模板导出

/**
 * 默认读取 classpath:excel/ 目录下的模板文件,具体模板使用参考官方文档
 *
 */
@ResponseExcel(name = "模板测试excel", sheet = "sheetName",template = "example.xlsx")
@GetMapping("/e1")
public List<DemoData> e1() {
    return list();
}

其他用法

More Repositories

1

pig

↥ ↥ ↥ 点击关注更新,基于 Spring Cloud 2023 、Spring Boot 3.3、 OAuth2 的 RBAC 权限管理系统
Java
5,775
star
2

easy-captcha

https://github.com/whvcse/EasyCaptcha增强JAVA11
Java
309
star
3

oss-spring-boot-starter

兼容S3协议的通用文件存储工具类
Java
244
star
4

multilevel-cache-spring-boot-starter

spring cache 多级缓存扩展
238
star
5

pig-ui

🚀 The best rbac web framework. base on Spring Boot 3.2、 Spring Cloud 2023、 OAuth2 . Give a star
Vue
238
star
6

idempotent-spring-boot-starter

spring boot idempotent starter
Java
138
star
7

ureport-spring-boot-starter

UReport2 是一款基于架构在 Spring 之上纯 Java 的高性能报表引擎
Java
57
star
8

nacos-datasource-plugin-dm8

nacos 达梦数据库插件
Java
27
star
9

nacos-datasource-plugin-oracle

nacos oracle 持久化数据库插件
PLSQL
16
star
10

docker-mirror

自动化搞定 Docker 镜像操作
15
star
11

nacos-datasource-plugin-pg

nacos postgresql 数据库插件
Java
13
star
12

pig-ui-electron

pig-ui的 electron 移植版(或者叫增强,因为他们并不冲突)
Vue
12
star
13

nacos-datasource-plugin-kingbase

nacos 人大金仓数据库存储插件
Java
11
star
14

fastdfs-spring-boot-starter

fastdfs spring boot start
Java
10
star
15

RuoYi-Vue

若依v3.8 前后端分离 适配PIGX v4.6 单点登录示例
Java
8
star
16

anti-reptile-spring-boot-starter

反爬组件
Java
7
star
17

pigx-mini-login

pigx 整合小程序登录示例源码
JavaScript
6
star
18

Ruoyi-vue-pig

pig 3.6 整合 ruoyi 3.8 前后端分离示意项目
Java
5
star
19

spring-cloud-pig-mesh

自己实现一套 spring cloud
Java
5
star
20

aliyun-sms-spring-boot-starter

阿里云短信发送工具
Java
4
star
21

CGTM

Code Generation Template Marketplace
Vue
3
star
22

beanstalkd-spring-boot-starter

Beanstalkd分布式内存队列系统 的 spring boot starter 封装
Java
2
star
23

rocketmq-spring-boot3-starter

RocketMQ SpringBoot 3.0 Starter
2
star
24

nacos-datasource-plugin-highgo

nacos 瀚高数据库存储插件
Java
2
star
25

jeesite5

pig 3.6 整合 jeesite 5.x 前后端分离示意项目
JavaScript
1
star
26

start-spring-io-default-val-extension

Chrome 插件 start.spring.io 创建项目时指定一些默认值
JavaScript
1
star
27

aj-captcha

Java
1
star
28

docker-ocr-image

Dockerfile
1
star