jquickexcel 作为一款高效的 Java Excel 处理工具,不仅简化了导出流程,更在数据导入环节提供了全面支持。本文将按照「导入 - 导出」全流程,详细介绍各核心功能的具体用法,助你轻松应对各类 Excel 处理场景。
一、导入功能:从 Excel 到数据对象的无缝转换
1. 环境准备:快速安装依赖
Maven 配置:
xml
<dependency>
<groupId>io.github.paohaijiao</groupId>
<artifactId>jquick-excel</artifactId>
<version>1.3.0</version> <!-- 使用最新版本 -->
</dependency>
Gradle 配置:
groovy
implementation 'io.github.paohaijiao:jquick-excel:1.3.0'
2. 字段映射:
导入时首先需要解决「Excel 列标题」与「字段」的对应关系
方式一:字段映射
java
IMPORT WITH HEADER=true,MAPPING = {
"学号": "no",
"姓名": "name",
"性别": "sex",
"年龄": "age",
"出生日期": "birthday"
}
JQuickExcelCommonImportExecutor executor=new JQuickExcelCommonImportExecutor();
JExcelImportModel model= (JExcelImportModel)executor.execute(rule);
InputStream is = JMappingTest.class.getClassLoader().getResourceAsStream("templates/student.xlsx");
XSSFWorkbook workbook=new XSSFWorkbook(is);
JExcelImportHandler handler=new JExcelImportHandler(workbook);
List<Map<String, Object>> list= handler.importData(model);
方式二:字段转换(动态场景)
IMPORT WITH HEADER=true,SHEET='Sheet1',MAPPING = {
"学号": "no",
"姓名": "name",
"性别": "sex",
"年龄": "age",
"出生日期": "birthday"
},
TRANSFORM={
"sex":trans(${dict}, ${sex}),
"birthday":dateFormat(${birthday},'yyyy-MM-dd')
}
JQuickExcelCommonImportExecutor executor=new JQuickExcelCommonImportExecutor();
JExcelImportModel model= (JExcelImportModel)executor.execute(rule);
InputStream is = JMappingTest.class.getClassLoader().getResourceAsStream("templates/student.xlsx");
XSSFWorkbook workbook=new XSSFWorkbook(is);
Map<String,Object> sex=new HashMap<>();
sex.put("男","1");
sex.put("女","2");
JContext context = new JContext();
context.put("dict",sex);
JExcelImportHandler handler=new JExcelImportHandler(workbook,context);
List<Map<String, Object>> list= handler.importData(model);
3. 导入数据验证
支持的验证规则如下
-
boolean:验证值是否为布尔类型
-
date_format:验证字符串是否匹配指定的日期格式(参数:format)
-
max_date:验证日期是否不晚于指定的最大日期(参数:maxDate、format)
-
min_date:验证日期是否不早于指定的最小日期(参数:minDate、format)
-
integer:验证值是否为整数
-
decimal:验证值是否为十进制数
-
max_value:验证数值是否不大于指定的最大值(参数:maxValue)
-
min_value:验证数值是否不小于指定的最小值(参数:minValue)
-
dict:验证值是否存在于提供的字典中(参数:key-value pairs)
-
email:验证字符串是否为格式正确的电子邮件地址
-
mobile:验证字符串是否为有效的手机号码格式(中国标准)
-
max_length:验证字符串长度是否不超过指定的最大长度(参数:maxLength)
-
min_length:验证字符串长度是否达到或超过指定的最小长度(参数:minLength)
-
regex:验证字符串是否匹配指定的正则表达式模式(参数:pattern)
-
start_with:验证字符串是否以指定的子字符串开头(参数:startWith)
-
not_start_with:验证字符串是否不以指定的子字符串开头(参数:notStartWith)
-
end_with:验证字符串是否以指定的子字符串结尾(参数:endWith)
-
not_end_with:验证字符串是否不以指定的子字符串结尾(参数:notEndWith)
-
contain:验证字符串是否包含指定的子字符串(参数:contains)
-
not_contain:验证字符串是否不包含指定的子字符串(参数:notContain)
IMPORT WITH HEADER=true,SHEET='Sheet1',MAPPING = { "学号": "no", "姓名": "name", "性别": "sex", "年龄": "age", "出生日期": "birthday" },V ALIDATION={
C2:C4:{ boolean{required:true,msg:'性别非法',map:{'1':'男','2':'女'} } }HashMap<String,Object> map = new HashMap<>(); map.put("1","男"); map.put("2","女"); JQuickExcelCommonImportExecutor executor=new JQuickExcelCommonImportExecutor(); JExcelImportModel model= (JExcelImportModel)executor.execute(input); InputStream is = JMappingTest.class.getClassLoader().getResourceAsStream("templates/student.xlsx"); XSSFWorkbook workbook=new XSSFWorkbook(is); JExcelImportHandler handler=new JExcelImportHandler(workbook); List<Map<String, Object>> list= handler.importData(model);
二、导出功能:从数据到精美报表的一站式解决方案
1. 格式化:统一数据展示格式
通过格式化配置,让日期、数字等类型数据以规范格式呈现:
EXPORT WITH
SHEET="学生表",
HEADER=true,
MAPPING={
"id":"主键",
"name":"姓名",
"gender":"性别",
"age":"年龄",
"enrollmentDate":"入学时间",
"className":"班级",
"ignoreField":"是否忽略"
},FORMAT={"enrollmentDate":"yyyy-MM-dd"}
List<Map<String, Object>> data = JObjectConverter.convert(getData());
FileOutputStream fileOutputStream=new FileOutputStream("d://test//format.xlsx");
JQuickExcelCommonExportExecutor executor = new JQuickExcelCommonExportExecutor();
JExcelExportModel config = (JExcelExportModel) executor.execute(input);
JExcelExportHandler handler = new JExcelExportHandler(config,data);
Workbook workbook=handler.getWorkBook();
workbook.write(fileOutputStream);
2. 字段映射:自定义导出列名与顺序
灵活控制导出的列顺序和显示名称,无需修改实体类:
EXPORT WITH
SHEET="学生表",
HEADER=true,
MAPPING={
"id":"主键",
"name":"姓名",
"gender":"性别",
"age":"年龄",
"enrollmentDate":"入学时间",
"className":"班级",
"ignoreField":"是否忽略"
}
public static List<JStudentModel> getData() {
List<JStudentModel> students = new ArrayList<>();
students.add(new JStudentModel("1001", "张三", 1, 20, new Date(), "计算机1班", "true"));
students.add(new JStudentModel("1002", "李四", 0, 21, new Date(), "计算机2班", "true"));
students.add(new JStudentModel("1003", "王五", 1, 22, new Date(), "计算机3班", "true"));
return students;
}
List<Map<String, Object>> data = JObjectConverter.convert(getData());
FileOutputStream fileOutputStream=new FileOutputStream("d://test//format.xlsx");
JQuickExcelCommonExportExecutor executor = new JQuickExcelCommonExportExecutor();
JExcelExportModel config = (JExcelExportModel) executor.execute(input);
JExcelExportHandler handler = new JExcelExportHandler(config,data);
Workbook workbook=handler.getWorkBook();
workbook.write(fileOutputStream);
3. 数据转换:让导出数据更易读
在复杂业务场景中,Excel 数据转换往往需要灵活的逻辑处理 —— 从简单的字符串拼接,到复杂的多字段运算,甚至调用外部服务获取数据。jquickexcel 通过JEvalue 动态表达式和插件扩展机制,让这些需求都能通过极简配置实现,无需编写大量冗余代码。本示例只以trans,dateFormat和toUpper 为例子,更多函数请移步javelin 的JEvalue 部分
EXPORT WITH
SHEET="学生表",
HEADER=true,
MAPPING={
"id":"主键",
"name":"姓名",
"gender":"性别",
"age":"年龄",
"enrollmentDate":"入学时间",
"className":"班级",
"ignoreField":"是否忽略"
},FORMAT={ "enrollmentDate":"yyyy-MM-dd"
},
TRANSFORM={
"name": toUpper(${name}),
"enrollmentDate": dateFormat(${enrollmentDate},'yyyy-MM-dd'),
"gender": trans(${dict},${gender})
}
List<Map<String, Object>> data = JObjectConverter.convert(getData());
FileOutputStream fileOutputStream=new FileOutputStream("d://test//transform.xlsx");
JQuickExcelCommonExportExecutor executor = new JQuickExcelCommonExportExecutor();
JExcelExportModel config = (JExcelExportModel) executor.execute(input);
HashMap<String,Object> map = new HashMap<>();
map.put("1","男");
map.put("0","女");
JContext context = new JContext();
context.put("dict",map);
JExcelExportHandler handler = new JExcelExportHandler(config,context,data);
Workbook workbook=handler.getWorkBook();
workbook.write(fileOutputStream);
4. Excel 公式:自动计算统计数据
一、字符串处理公式
TO_UPPER(text):将文本转换为大写形式TO_LOWER(text):将文本转换为小写形式TRIM(text):去除文本前后的空格LEN(text):计算文本的长度CONCAT(text1, text2, ...):拼接多个文本字符串SUBSTR(text, start, length):从指定位置截取指定长度的子字符串REPLACE(text, old, new):替换文本中的指定字符或子串
二、日期时间公式
DATE(year, month, day):根据年、月、日创建日期NOW():获取当前日期和时间TODAY():获取当前日期(不含时间)DATE_ADD(date, number, unit):对日期进行加减运算(unit 支持 YEAR、MONTH、DAY、HOUR、MINUTE、SECOND)DATE_DIFF(date1, date2, unit):计算两个日期之间的差值FORMAT_DATE(date, pattern):将日期格式化为指定字符串(如 "yyyy-MM-dd")PARSE_DATE(text, pattern):将字符串解析为日期对象
三、数学计算公式
SUM(number1, number2, ...):计算多个数值的总和AVERAGE(number1, number2, ...):计算多个数值的平均值MAX(number1, number2, ...):获取多个数值中的最大值MIN(number1, number2, ...):获取多个数值中的最小值ROUND(number, decimalPlaces):将数值四舍五入到指定小数位数ABS(number):获取数值的绝对值MOD(number, divisor):计算两数相除的余数POWER(number, power):计算数值的指定次方
四、逻辑判断公式
IF(condition, valueIfTrue, valueIfFalse):根据条件返回不同的值AND(condition1, condition2, ...):判断多个条件是否同时成立OR(condition1, condition2, ...):判断多个条件是否至少有一个成立NOT(condition):对条件进行取反操作EQ(value1, value2):判断两个值是否相等NE(value1, value2):判断两个值是否不相等GT(value1, value2):判断 value1 是否大于 value2LT(value1, value2):判断 value1 是否小于 value2GE(value1, value2):判断 value1 是否大于等于 value2LE(value1, value2):判断 value1 是否小于等于 value2
五、数据处理公式
DEFAULT(value, defaultValue):如果值为 null 则返回默认值MAP(value, mapJson):根据映射关系转换值(mapJson 为 JSON 格式的键值对)IN(value, array):判断值是否在指定数组中SWITCH(value, case1, result1, case2, result2, ..., defaultResult):多条件分支判断FORMAT_NUMBER(number, pattern):将数字格式化为指定样式(如 "#,##0.00")
直接在导出时配置公式,避免手动计算:
EXPORT WITH
SHEET="学生表",
HEADER=true,
MAPPING={
"id":"主键",
"name":"姓名",
"gender":"性别",
"age":"年龄",
"enrollmentDate":"入学时间",
"className":"班级",
"ignoreField":"是否忽略"
},
FORMULAS={
D5:'ABS(D2)'
}
5. 样式美化:打造专业报表外观
通过样式配置美化 Excel,支持字体、颜色、对齐方式等设置:具体样式值请参考文档
EXPORT WITH
SHEET="学生表",
HEADER=true,
MAPPING={
"id":"主键",
"name":"姓名",
"gender":"性别",
"age":"年龄",
"enrollmentDate":"入学时间",
"className":"班级",
"ignoreField":"是否忽略"
},
FORMULAS={
D5:'ABS(D2)'
},
STYLE={
ROW 1: {
fontName: Arial,
fontHeightInPoints: 12,
italic: true,
color: yellow,
bold: true
}}
List<Map<String, Object>> data = JObjectConverter.convert(getData());
FileOutputStream fileOutputStream=new FileOutputStream("d://test//style.xlsx");
JQuickExcelCommonExportExecutor executor = new JQuickExcelCommonExportExecutor();
JExcelExportModel config = (JExcelExportModel) executor.execute(rule);
HashMap<String,Object> map = new HashMap<>();
map.put("1","男");
map.put("0","女");
JContext context = new JContext();
context.put("dict",map);
JExcelExportHandler handler = new JExcelExportHandler(config,context,data);
Workbook workbook=handler.getWorkBook();
workbook.write(fileOutputStream);
6. 单元格合并:制作汇总报表
支持9种2合并策略
-
MERGE_WITH_FIRST:保留第一个单元格的值
-
MERGE_WITH_LAST:保留最后一个单元格的值
-
MERGE_WITH_SUM:计算所有单元格值的总和
-
MERGE_WITH_AVG:计算所有单元格值的平均值
-
MERGE_WITH_MAX:保留所有单元格中的最大值
-
MERGE_WITH_MIN:保留所有单元格中的最小值
-
MERGE_WITH_VALUE:保留固定值
-
MERGE_WITH_CONCAT:拼接所有单元格的值
-
MERGE_WITH_COUNT:统计非空单元格的数量
支持按规则合并单元格,适合制作分组汇总报表:
EXPORT WITH MERGE: {
ROWS 1 WITH MERGE_WITH_MAX,
ROWS 2..3 WITH MERGE_WITH_MIN
}
public static List<JDataModel> getData() {
List<JDataModel> students = new ArrayList<>();
students.add(new JDataModel(1, 22, 3, 4, 5, 6, 1));
students.add(new JDataModel(2, 0, 1, 1, 1, 1, 1));
students.add(new JDataModel(3, -1, 1, 1, 1, 1, 1));
students.add(new JDataModel(4, 1, 1, 1, 1, 1, 1));
students.add(new JDataModel(5, 1, 1, 1, 1, 1, 1));
students.add(new JDataModel(6, 1, 1, 1, 1, 1, 1));
students.add(new JDataModel(7, 1, 1, 1, 1, 1, 1));
students.add(new JDataModel(8, 1, 1, 1, 1, 1, 1));
students.add(new JDataModel(9, 1, 1, 1, 1, 1, 1));
students.add(new JDataModel(10, 1, 1, 1, 1, 1, 1));
students.add(new JDataModel(11, 1, 1, 1, 1, 1, 1));
students.add(new JDataModel(12, 1, 1, 1, 1, 1, 1));
students.add(new JDataModel(13, 1, 1, 1, 1, 1, 1));
students.add(new JDataModel(14, 1, 1, 1, 1, 1, 1));
return students;
}
@Test
public void max() throws IOException {
String rule = "EXPORT WITH MERGE: {\n" +
" ROWS 1 WITH MERGE_WITH_MAX,"+
" ROWS 2..3 WITH MERGE_WITH_MIN"+
"}";
System.out.println(rule);
List<Map<String, Object>> data = JObjectConverter.convert(getData());
FileOutputStream fileOutputStream=new FileOutputStream("d://test//merge.xlsx");
JQuickExcelCommonExportExecutor executor = new JQuickExcelCommonExportExecutor();
JExcelExportModel config = (JExcelExportModel) executor.execute(rule);
HashMap<String,Object> map = new HashMap<>();
map.put("1","男");
map.put("0","女");
JContext context = new JContext();
context.put("dict",map);
JExcelExportHandler handler = new JExcelExportHandler(config,context,data);
Workbook workbook=handler.getWorkBook();
workbook.write(fileOutputStream);
}
7. 图表生成:数据可视化一键完成
直接在导出时生成图表,支持8种图表类型:
-
COLUMN:垂直柱状图
-
BAR/BAR3D:水平条形图
-
LINE:折线图
-
PIE:饼图
-
AREA/AREA3D:面积图
-
SCATTER:散点图
-
RADAR:雷达图
-
SURFACE:3D 曲面图
EXPORT WITH GRAPH = { TYPE = COLUMN, TITLE = "销售数据统计", CATEGORY_AXIS = "产品", VALUE_AXIS = "销量", CATEGORIES = ["产品A", "产品B", "产品C", "产品D"], SERIES = [{ NAME = "第一季度", DATA = [120, 200, 150, 180] }, { NAME = "第二季度", DATA = [180, 210, 190, 220] }] }
JChartData chartData = new JChartData(); chartData.setTitle("销售数据统计"); chartData.setCategoryAxisTitle("产品"); chartData.setValueAxisTitle("销量"); chartData.setCategories(Arrays.asList("产品A", "产品B", "产品C", "产品D")); JSeriesData series1 = new JSeriesData(); series1.setName("第一季度"); series1.setData(Arrays.asList(120, 200, 150, 180)); JSeriesData series2 = new JSeriesData(); series2.setName("第二季度"); series2.setData(Arrays.asList(180, 210, 190, 220)); chartData.setSeries(Arrays.asList(series1, series2)); XSSFWorkbook workbook = JExcelChartFactory.createWorkbookWithChart( chartData, JExcelChartType.COLUMN, "销售报表"); try (FileOutputStream out = new FileOutputStream("D://test//SalesReport.xlsx")) { JExcelChartFactory.writeWorkbookToStream(workbook, out); } catch (IOException e) { e.printStackTrace(); }
8. 页脚设置:添加页码与版权信息
为报表添加页脚,支持动态页码和固定文本:
EXPORT WITH FOOTER="Generated by JQuickExcel on ${current_date()}"
总结
jquickexcel 通过「注解 + 规则配置」的双重方式,实现了 Excel 处理的全场景覆盖。无论是简单的数据导入导出,还是复杂的报表生成,都能通过简洁的代码完成。其底层基于 POI 但又简化了 80% 的冗余代码,让开发者从繁琐的 Excel 操作中解放出来。
更多高级用法和示例代码,请参考官方文档:github.com/paohaijiao/…,如果觉得好用,欢迎给项目点个 Star 支持!