将 JsonArray 类型的数据导出到Excel文件里的两种方式
说明:本文介绍如何将 JSONArray 类型的对象数据导出到 Excel 文件中
场景
我有个 excel 导出对象,如下:
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ContentStyle;
import com.alibaba.excel.enums.poi.HorizontalAlignmentEnum;
import com.alibaba.excel.enums.poi.VerticalAlignmentEnum;
import com.alibaba.fastjson.JSONArray;
import lombok.*;@Data
@AllArgsConstructor
@NoArgsConstructor
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, verticalAlignment = VerticalAlignmentEnum.CENTER)
public class StudentExcel {@ExcelProperty("姓名")private String name;@ExcelProperty("年龄")private Integer age;@ExcelProperty("性别")private String gender;@ExcelProperty("家庭住址")private JSONArray address;
}
其中家庭住址是 JSONArray 类型,格式如下:
["上海市","浦东新区"
]
对应的 excel 模板如下:
使用 EasyExcel 将数据导出到 excel 文件中,如果是对象集合,可以使用 {集合变量名.对象属性名称}
可以把数据填充到 excel 模板中,但不适用于JSONArray 类型的属性,如果是单个属性,可以直接使用 {属性名}
填充,但这会把下面这种错误,说类型不匹配,找不到转换器
基于这个场景,本文介绍两种解决方式,
方式一
方式一,手动转为字符类型,如下:
public String excel6() {String fileName = "学生信息6.xlsx";String templatePath = FileUtil.getWebRoot().getPath() + "/src/main/resources/template/excel/full/学生信息模板-填充.xlsx";try (ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templatePath).build()) {WriteSheet writeSheet = EasyExcel.writerSheet().build();List<StudentExcel> data = selectData(10);// 填充集合数据excelWriter.fill(data, writeSheet);Map<String, Object> dataMap = new HashMap<>();// 将 JsonArray 转为 StringdataMap.put("address", data.get(0).getAddress().toString());excelWriter.fill(dataMap, writeSheet);}return "success";}
其中 selectData 是成员方法,生成 excel 导出的 mock 数据,如下:
/*** 查询数据* @param batch 批次* @return 数据*/private List<StudentExcel> selectData(Integer batch) {List<StudentExcel> list = ListUtils.newArrayList();JSONArray address = new JSONArray();address.add("上海市");address.add("浦东新区");for (int i = 0; i < batch; i++) {list.add(new StudentExcel("张三" + i, 18 + i, "男", address));}return list;}
效果如下,换成字符串肯定是可以的,问题是我这的家庭住址是结构化的数据,拼接问题不大,但有些表示附件名称列表的属性,能否拼接展示就要看业务上是否支持。
另外,如果是不用模板导出的,可以直接在属性上指定一个转换器,导出就不用手动 toString
JSONArray 转换器
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.fastjson.JSONArray;/*** JSONArray 转换器*/
public class AddressConverter implements Converter<JSONArray> {/*** javaBean 转 excel*/@Overridepublic WriteCellData<?> convertToExcelData(JSONArray value, ExcelContentProperty contentProperty,GlobalConfiguration globalConfiguration) {return new WriteCellData<>(value.toString());}
}
不用模板的导出
@GetMapping("/no-template/one")public String excel1() {String fileName = "学生信息1.xlsx";try (ExcelWriter excelWriter = EasyExcel.write(fileName, StudentExcel.class).build()) {WriteSheet writeSheet = EasyExcel.writerSheet("模板").build();excelWriter.write(selectData(10), writeSheet);}return "success";}
导出效果
方式二
方式二,将 JSONArray 转成集合对象,创建一个对象来接收 JSONArray 对象,如下:
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;/*** 家庭住址*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Address {/*** 家庭住址*/private String add;/*** 根据String集合返回对象集合* @param strings string集合* @return 对象集合*/public static List<Address> listOf(List<String> strings) {return strings.stream().map(Address::new).collect(Collectors.toCollection(ArrayList::new));}@Overridepublic String toString() {return add;}
}
注意重写 toString()
方法,不然后面调用集合的 toString() 会额外增加一些内容,使用这边就当集合对象用就行了。
@GetMapping("/template/full/json-array")public String excel6() {String fileName = "学生信息6.xlsx";String templatePath = FileUtil.getWebRoot().getPath() + "/src/main/resources/template/excel/full/学生信息模板-填充.xlsx";try (ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templatePath).build()) {WriteSheet writeSheet = EasyExcel.writerSheet().build();// 填充集合数据List<StudentExcel> data = selectData(10);List<Address> addresses = Address.listOf(data.get(0).getAddress().toJavaList(String.class));excelWriter.fill(addresses, writeSheet);}return "success";}
模板如下,我这里去掉了其他内容,只留下了 JSONArray 字段
填充效果
总结
本文介绍了 EasyExcel 中将 JsonArray 类型的数据导出到 Excel 文件里的两种方式