Java如何使用poi做加自定义注解实现对象与Excel相互转换
这篇文章将为大家详细讲解有关Java如何使用poi做加自定义注解实现对象与Excel相互转换,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
引入依赖
maven
org.apache.poi poi 3.17
Gradle
implementationgroup:'org.apache.poi',name:'poi',version:'3.17'
代码展示
1、自定义注解类
@Retention(value=RetentionPolicy.RUNTIME) @Target(value=ElementType.FIELD) public@interfaceExcel{ Stringname();//列的名字 intwidth()default6000;//列的宽度 intindex()default-1;//决定生成的顺序 booleanisMust()defaulttrue;//是否为必须值,默认是必须的 }
2、Java的Excel对象,只展现了field,get与set方法就忽略了
publicclassGoodsExcelModel{ @Excel(name="ID_禁止改动",index=0,width=0) privateLongpicId;//picId @Excel(name="产品ID_禁止改动",index=1,width=0) privateLongproductId; @Excel(name="型号",index=3) privateStringproductName;//产品型号 @Excel(name="系列",index=2) privateStringseriesName;//系列名字 @Excel(name="库存",index=5) privateLongquantity; @Excel(name="属性值",index=4) privateStringpropValue; @Excel(name="价格",index=6) privateDoubleprice; @Excel(name="商品编码",index=7,isMust=false) privateStringouterId; @Id @GeneratedValue(strategy=GenerationType.IDENTITY) privateLongdbId;//数据库自增长id privateDatecreateTime;//记录创建时间 }
3、Excel表格与对象转换的工具类,使用时指定泛型参数和泛型的class即可
publicclassExcelUtil{ privatestaticfinalStringGET="get"; privatestaticfinalStringSET="set"; privatestaticLoggerlogger=LoggerFactory.getLogger(ExcelUtil.class); /** *将对象转换成Excel * *@paramobjList需要转换的对象 *@return返回是poi中的对象 */ publicstaticHSSFWorkbooktoExcel(ListobjList){ if(CollectionUtils.isEmpty(objList))thrownewNullPointerException("无效的数据"); ClassaClass=objList.get(0).getClass(); Field[]fields=aClass.getDeclaredFields(); HSSFWorkbookworkbook=newHSSFWorkbook(); HSSFSheetsheet=workbook.createSheet(); for(inti=0;iList excelFileToObject(MultipartFilefile,Class c)throwsIOException,IllegalAccessException,InstantiationException{ //key为反射得到的下标,value为对于的set方法 Map methodMap=newHashMap<>(); //保存第一列的值与对应的下标,用于验证用户是否删除了该列,key为下标,value为名字 Map startRowNameMap=newHashMap<>(); //用来记录当前参数是否为必须的 Map fieldIsMustMap=newHashMap<>(); //得到所有的字段 Field[]fields=c.getDeclaredFields(); for(Fieldfield:fields){ Excelexcel=field.getAnnotation(Excel.class); if(excel==null)continue; StringstartName=field.getName().substring(0,1); StringendName=field.getName().substring(1,field.getName().length()); StringmethodName=newStringBuffer(SET).append(startName.toUpperCase()).append(endName).toString(); methodMap.put(excel.index(),methodName); startRowNameMap.put(excel.index(),excel.name()); fieldIsMustMap.put(excel.index(),excel.isMust()); } StringfileName=file.getOriginalFilename(); Workbookwb=fileName.endsWith(".xlsx")?newXSSFWorkbook(file.getInputStream()):newHSSFWorkbook(file.getInputStream()); Sheetsheet=wb.getSheetAt(0); RowsheetRow=sheet.getRow(0); for(Cellcell:sheetRow){ IntegercolumnIndex=cell.getColumnIndex(); if(cell.getCellTypeEnum()!=CellType.STRING)thrownewExcelException("excel校验失败,请勿删除文件中第一行数据!!!"); Stringvalue=cell.getStringCellValue(); Stringname=startRowNameMap.get(columnIndex); if(name==null)thrownewExcelException("excel校验失败,请勿移动文件中任何列的顺序!!!"); if(!name.equals(value))thrownewExcelException("excel校验失败,【"+name+"】列被删除,请勿删除文件中任何列!!!"); } sheet.removeRow(sheetRow);//第一行是不需要被反射赋值的 List models=newArrayList<>(); for(Rowrow:sheet){ if(row==null||!checkRow(row))continue; Tobj=c.newInstance();//创建新的实例化对象 ClassexcelModelClass=obj.getClass(); startRowNameMap.entrySet().forEach(x->{ Integerindex=x.getKey(); Cellcell=row.getCell(index); StringmethodName=methodMap.get(index); if(StringUtils.isEmpty(methodName))return; List methods=Lists.newArrayList(excelModelClass.getMethods()).stream() .filter(m->m.getName().startsWith(SET)).collect(Collectors.toList()); StringrowName=startRowNameMap.get(index);//列的名字 for(Methodmethod:methods){ if(!method.getName().startsWith(methodName))continue; //检测value属性 Stringvalue=valueCheck(cell,rowName,fieldIsMustMap.get(index)); //开始进行调用方法反射赋值 methodInvokeHandler(obj,method,value); } }); models.add(obj); } returnmodels; } /** *检测当前需要赋值的value * *@paramcell当前循环行中的列对象 *@paramrowName列的名字{@linkExcel}中的name *@paramisMust是否为必须的 *@return值 */ privatestaticStringvalueCheck(Cellcell,StringrowName,BooleanisMust){ //有时候删除单个数据会造成cell为空,也可能是value为空 if(cell==null&&isMust){ thrownewExcelException("excel校验失败,【"+rowName+"】中的数据禁止单个删除"); } if(cell==null)returnnull; cell.setCellType(CellType.STRING); Stringvalue=cell.getStringCellValue(); if((value==null||value.trim().isEmpty())&&isMust){ thrownewExcelException("excel校验失败,【"+rowName+"】中的数据禁止单个删除"); } returnvalue; } /** *反射赋值的处理的方法 * *@paramobj循环创建的需要赋值的对象 *@parammethod当前对象期中一个set方法 *@paramvalue要被赋值的内容 */ privatestaticvoidmethodInvokeHandler(Objectobj,Methodmethod,Stringvalue){ Class>parameterType=method.getParameterTypes()[0]; try{ if(parameterType==null){ method.invoke(obj); return; } Stringname=parameterType.getName(); if(name.equals(String.class.getName())){ method.invoke(obj,value); return; } if(name.equals(Long.class.getName())){ method.invoke(obj,Long.valueOf(value)); return; } if(name.equals(Double.class.getName())){ method.invoke(obj,Double.valueOf(value)); } }catch(IllegalAccessExceptione){ e.printStackTrace(); }catch(InvocationTargetExceptione){ e.printStackTrace(); } } privatestaticbooleancheckRow(Rowrow){ try{ if(row==null)returnfalse; shortfirstCellNum=row.getFirstCellNum(); shortlastCellNum=row.getLastCellNum(); if(firstCellNum<0&&lastCellNum<0)returnfalse; if(firstCellNum!=0){ for(shorti=firstCellNum;i 4、导出Excel与导入Excel的示例代码
使用展示
1、选择数据
2、设置基本数据,然后导出表格
3、导出表格效果,在图片中看到A和B列没有显示出来,这是因为我将其宽度配置为了0
4、将必须参数删除后上传测试,如下图中,商品编码我设置isMust为false所以删除数据就不会出现此问题。会提示验证失败,具体错误查看图片
5、将列中值的顺序调整测试,也会提示验证失败,具体效果如下图
6、正常上传测试,具体效果下如图
关于“Java如何使用poi做加自定义注解实现对象与Excel相互转换”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。
推荐阅读
-
java fileinputstream中文乱码如何解决
javafileinputstream中文乱码如何解决今天小编给...
-
java实现点赞功能
-
java实现简单点赞功能
-
java实现收藏功能
-
java输入空行结束问题怎么解决
-
Java线程中常用的操作有哪些
-
java输入时怎么通过回车来结束输入
java输入时怎么通过回车来结束输入这篇文章主要介绍“java输入...
-
Java数据结构之线索化二叉树怎么实现
Java数据结构之线索化二叉树怎么实现这篇文章主要介绍“Java数...
-
Java中的泛型怎么理解
Java中的泛型怎么理解本篇内容介绍了“Java中的泛型怎么理解”...
-
Java字符串编码解码性能怎么提升
Java字符串编码解码性能怎么提升这篇“Java字符串编码解码性能...