首页 > 基础资料 博客日记
EasyPoi实现动态列的导入导出(固定列+自定义列)-横向(动态行头)+纵向-java
2024-05-10 01:00:05基础资料围观579次
本篇文章分享EasyPoi实现动态列的导入导出(固定列+自定义列)-横向(动态行头)+纵向-java,对你有帮助的话记得收藏一下,看Java资料网收获更多编程知识
导入jar包
<!-- 导入导出的工具包,可以完成Excel导出,导入,Word的导出,Excel的导出功能 -->
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
<version>4.3.0</version>
</dependency>
<!--耦合了spring-mvc 基于AbstractView,极大的简化spring-mvc下的导出功能 -->
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-web</artifactId>
<version>4.3.0</version>
</dependency>
<!-- 基础注解包,作用与实体对象上,拆分后方便maven多工程的依赖管理 -->
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-annotation</artifactId>
<version>4.3.0</version>
</dependency>
easyPoi开发文档: easyPoi开发文档
纵向导入导出:
项目需要导入导出数据,包含基本信息和规格参数List信息,最初
采用easyPoi的注解导出,实现效果如下:
其中基本信息固定, 但产品尺寸信息List根据所属平台不同数量及名称不定
实体类
TbInstallProductVo对象纵向合并所用实体类注解:
除了@Excel注解, 主要使用了
@ExcelCollection
来实现导出集合的效果, 具体实现方法可以去官网查看
导出
//设置导出参数,获得工作簿,response返回
ExportParams exportParams = new ExportParams("完美安装产品信息", "产品信息");
Workbook wb = ExcelExportUtil.exportExcel(exportParams, TbInstallProductVo.class, list);
try {
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("导出完美安装产品信息" + System.currentTimeMillis(), "UTF-8"));
wb.write(response.getOutputStream());
} catch (IOException e) {
throw new RuntimeException(e);
}
IOUtils.closeQuietly(wb);
导入
public AjaxResult importData(MultipartFile file, Boolean updateSupport) {
//设置导入参数,
ImportParams importParams = new ImportParams();
//表格标题行数,默认0
importParams.setTitleRows(1);
//表头行数,默认1
importParams.setHeadRows(2);
List<TbInstallProductVo> productVoList;
try {
productVoList = ExcelImportUtil.importExcel(file.getInputStream(), TbInstallProductVo.class, importParams);
} catch (Exception e) {
throw new RuntimeException("读取excel数据异常null");
}
if (StringUtils.isNotEmpty(productVoList)) {
//导入信息
return importProductInfoAndParamInfo(updateSupport, productVoList);
} else {
return AjaxResult.error("导入数据不能为空!");
}
}
横向动态列导入导出(行头动态生成)
现在需要按平台分类将产品规格信息的动态List的参数名称横置为列名,参数值为数据,形成不同导入导出模板,,必须采用动态列进行导入导出,实现效果如下:
解决方案
Java反射机制根据@Excel注解获取需要的参数+动态拼装ExcelExportEntity实现List动态行头
其中:基于List 的导出,ExcelExportEntity
是注解经过处理翻译成的实体类,两者几乎是一对
的,所以如果我们要动态自定义导出列,我们只要动态拼装ExcelExportEntity就可以实现不固定参数
, 由于行头的名称也是数据库读取内容, 因此需要用java反射
获取参数名称字段的内容
作为行头
模板类对象
导出
public void export(HttpServletResponse response, Long[] ids) {
try {
//业务数据查询
List<TbInstallProductVo> productVoList = tbInstallProductInfoService.selectTbInstallProductInfoListForExportV1(ids);
List<Map<String, Object>> dataList = new ArrayList<>();
//数据转为List<map>导出
if (StringUtils.isNotEmpty(productVoList)) {
for (TbInstallProductVo productVo : productVoList) {
//将相同模板的数据以<名称,数据>的格式转为map,以数据和行头匹配
dataList.add(getExportDataMap(productVo));
}
}
//构建该模板导出的行头
List<ExcelExportEntity> excelExportEntities = getExcelExportEntityList();
//数据导出
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("产品信息列表", "用户导入"), excelExportEntities, dataList);
downLoadExcel("导出完美安装产品信息" + System.currentTimeMillis(), response, workbook);
} catch (Exception e) {
throw new ServiceException("导出失败" + e);
}
}
根据类中注解通过反射构建行头
private List<ExcelExportEntity> getExcelExportEntityList() throws Exception {
Class<TbInstallProductVo> templateClass = TbInstallProductVo.class;
//获取所有Excel注解的字段
List<Field> fields = FieldUtils.getFieldsListWithAnnotation(templateClass, Excel.class);
//获取参数值字段的注解
Field parmaFiled = TbInstallParamInfoVo.class.getDeclaredField("paramName");
List<ExcelExportEntity> excelExportEntities = new ArrayList<>();
//获取基本信息导出-基本信息以Excel注解值为行头
//@ExcelTarget 这个是作用于最外层的对象,描述这个对象的id,以便支持一个对象可以针对不同导出做出不同处理
ExcelTarget etarget = (ExcelTarget) templateClass.getAnnotation(ExcelTarget.class);
String targetId = etarget == null ? null : etarget.value();
if (StringUtils.isNotEmpty(fields)) {
//循环带Excel注解的字段,获取Excel注解的name作为行头----固定的基本信息用此方式获取行头名称
for (Field field : fields) {
if (field.getAnnotation(Excel.class) != null) {
Excel excel = (Excel) field.getAnnotation(Excel.class);
String name = PoiPublicUtil.getValueByTargetId(excel.name(), targetId, (String) null);
if (StringUtils.isNotBlank(name)) {
//构建ExcelExportEntity
ExcelExportEntity excelExportEntity = this.createExcelExportEntity(field, targetId, templateClass, null, (ExcelEntity) null);
excelExportEntity.setKey(name);
excelExportEntities.add(excelExportEntity);
}
}
}
}
//根据模板动态加入需要导出的字段---动态列,行头名为数据paramName值
//获取该模板的数据(业务)
TbInstallTemplateParamInfo temParamParmas = new TbInstallTemplateParamInfo();
temParamParmas.setTemplateId(-1L);
List<TbInstallTemplateParamInfo> templateParamInfoList = tbInstallTemplateParamInfoMapper.selectTbInstallTemplateParamInfoList(temParamParmas);
if (StringUtils.isNotEmpty(templateParamInfoList)) {
//循环模板的参数
for (int i = 0; i < templateParamInfoList.size(); i++) {
//判断参数名称字段是否存在有效注解
if (parmaFiled.getAnnotation(Excel.class) != null) {
Excel excel = (Excel) parmaFiled.getAnnotation(Excel.class);
String name = PoiPublicUtil.getValueByTargetId(excel.name(), targetId, (String) null);
if (StringUtils.isNotBlank(name)) {
//存在注解,设置行头名称为参数值,并设置导出排序
ExcelExportEntity excelExportEntity = this.createExcelExportEntity(parmaFiled, targetId, TbInstallParamInfoVo.class, null, (ExcelEntity) null);
excelExportEntity.setName(templateParamInfoList.get(i).getParamName());
excelExportEntity.setOrderNum(fields.size() + i);
excelExportEntity.setKey(templateParamInfoList.get(i).getParamName());
excelExportEntities.add(excelExportEntity);
}
}
}
}
//返回固定列+该模板动态列格式
return excelExportEntities;
}
业务数据转为
List<map>
private Map<String, Object> getExportDataMap(TbInstallProductVo productVo) throws Exception {
Class<TbInstallProductVo> templateClass = TbInstallProductVo.class;
List<Field> fields = FieldUtils.getFieldsListWithAnnotation(templateClass, Excel.class);
//获取参数值字段的注解
Field parmaFiled = TbInstallParamInfoVo.class.getDeclaredField("paramName");
Map<String, Object> map = new HashMap<>();
//获取基本信息的数据
ExcelTarget etarget = (ExcelTarget) templateClass.getAnnotation(ExcelTarget.class);
String targetId = etarget == null ? null : etarget.value();
if (StringUtils.isNotEmpty(fields)) {
for (Field field : fields) {
if (field.getAnnotation(Excel.class) != null) {
Excel excel = (Excel) field.getAnnotation(Excel.class);
String name = PoiPublicUtil.getValueByTargetId(excel.name(), targetId, (String) null);
if (StringUtils.isNotBlank(name)) {
field.setAccessible(true);
map.put(name, ObjectValueUtils.getValue(field.get(productVo), field.getType()));
}
}
}
}
//根据productVo生成参数数据存入map
if (StringUtils.isNotEmpty(productVo.getParamInfoVoList())) {
for (int i = 0; i < productVo.getParamInfoVoList().size(); i++) {
if (parmaFiled.getAnnotation(Excel.class) != null) {
Excel excel = (Excel) parmaFiled.getAnnotation(Excel.class);
String name = PoiPublicUtil.getValueByTargetId(excel.name(), targetId, (String) null);
if (StringUtils.isNotBlank(name)) {
//<参数名称,参数值>
map.put(productVo.getParamInfoVoList().get(i).getParamName(), productVo.getParamInfoVoList().get(i).getParamValue());
}
}
}
}
return map;
}
导入
public AjaxResult importData(MultipartFile file, Boolean updateSupport) {
Class<TbInstallProductVo> importClass = TbInstallProductVo.class;
List<Map<String, Object>> mapList = null;
List<TbInstallProductVo> productVoList = new ArrayList<>();
try {
ImportParams importParams = new ImportParams();
importParams.setTitleRows(1);
importParams.setHeadRows(1);
//获取导入的数据,按<行头,内容>格式
mapList = ExcelImportUtil.importExcel(file.getInputStream(), Map.class, importParams);
} catch (Exception e) {
throw new RuntimeException("读取excel数据异常" + e);
}
if (StringUtils.isEmpty(mapList)) {
throw new ServiceException("导入产品数据为空!");
}
//获取固定参数
List<Field> fields = FieldUtils.getFieldsListWithAnnotation(importClass, Excel.class);
ExcelTarget etarget = (ExcelTarget) importClass.getAnnotation(ExcelTarget.class);
String targetId = etarget == null ? null : etarget.value();
//根据模板动态加入需要导出的字段
TbInstallTemplateParamInfo temParamParmas = new TbInstallTemplateParamInfo();
temParamParmas.setTemplateId(-1L);
List<TbInstallTemplateParamInfo> templateParamInfoList = tbInstallTemplateParamInfoMapper.selectTbInstallTemplateParamInfoList(temParamParmas);
try {
for (Map<String, Object> map : mapList) {
//构建导入数据List
TbInstallProductVo productVo = importClass.newInstance();
//构建固定字段-固定字段以注解为行头
if (StringUtils.isNotEmpty(fields)) {
for (Field field : fields) {
if (field.getAnnotation(Excel.class) != null) {
Excel excel = (Excel) field.getAnnotation(Excel.class);
String excelName = PoiPublicUtil.getValueByTargetId(excel.name(), targetId, (String) null);
if (StringUtils.isNotBlank(excelName)) {
//设置允许访问,并强制类型转换解决解析类型冲突
field.setAccessible(true);
//设置参数值为导入的数据
field.set(productVo, ObjectValueUtils.getValue(map.get(excelName), field.getType()));
}
}
}
}
//构建不定产品参数
if (StringUtils.isNotEmpty(templateParamInfoList)) {
List<TbInstallParamInfoVo> paramInfoVoList = new ArrayList<>();
for (TbInstallTemplateParamInfo tempParamInfo : templateParamInfoList) {
//设置参数对象以构建自定义参数List
TbInstallParamInfoVo paramInfoVo = new TbInstallParamInfoVo();
paramInfoVo.setParamName(tempParamInfo.getParamName());
paramInfoVo.setParamCode(tempParamInfo.getParamCode());
paramInfoVo.setParamValue(String.valueOf(map.get(tempParamInfo.getParamName())));
paramInfoVoList.add(paramInfoVo);
}
productVo.setParamInfoVoList(paramInfoVoList);
}
productVoList.add(productVo);
}
log.info("完美安装导入的数据=={}", productVoList);
} catch (Exception e) {
throw new RuntimeException("数据解析错误,请检查数据内容" + e);
}
//导入数据-业务逻辑
return tbInstallProductInfoServiceImpl.importProductInfoAndParamInfo(updateSupport, productVoList);
}
补充ObjectValueUtils工具类
import java.text.ParseException;
import java.util.Date;
/**
* @author Shenpeng
* @Date 2023/11/27/16:21
* @Description
*/
public class ObjectValueUtils {
/**
* description 根据类型class转换类型值
*
* @param value:
* @param type:
* @return :Object
*/
public static Object getValue(Object value, Class type) throws ParseException {
if (value != null) {
if (type.isAssignableFrom(String.class))
return toString(value);
if (type.isAssignableFrom(Integer.class) || type.isAssignableFrom(int.class))
return toInteger(value);
if (type.isAssignableFrom(Long.class) || type.isAssignableFrom(long.class))
return toLong(value);
if (type.isAssignableFrom(Boolean.class) || type.isAssignableFrom(boolean.class))
return toBoolean(value);
if (type.isAssignableFrom(Double.class) || type.isAssignableFrom(double.class))
return toDouble(value);
if (type.isAssignableFrom(Date.class))
return toDate(value);
if (type.isAssignableFrom(String[].class))
return toStringArray(value);
if (type.isAssignableFrom(Integer[].class))
return toIntegerArray(value);
}
return value;
}
private static String[] toStringArray(Object value) {
return value.toString().split(",");
}
private static Integer[] toIntegerArray(Object value) {
String[] stringArray = toStringArray(value);
Integer[] intArray = new Integer[stringArray.length];
for (int i = 0; i < stringArray.length; i++) {
intArray[i] = Integer.parseInt(stringArray[i]);
}
return intArray;
}
private static Integer toInteger(Object value) {
return Integer.parseInt(value.toString());
}
private static Long toLong(Object value) {
return Long.parseLong(value.toString());
}
private static Double toDouble(Object value) {
return Double.parseDouble(value.toString());
}
private static String toString(Object value) {
return value.toString();
}
private static Date toDate(Object value) throws ParseException {
return DateUtils.parseDate(value.toString(), DateUtils.YYYY_MM_DD);
}
private static Boolean toBoolean(Object value) {
return Boolean.parseBoolean(value.toString());
}
}
文章来源:https://blog.csdn.net/SHENMU1/article/details/134920481
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
标签: