package com.cinc.ecmp.utils;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List; import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile; import com.cinc.ecmp.annotation.ExcelField;
import com.cinc.ecmp.enums.BackResultEnum;
import com.cinc.ecmp.exception.BasException; import lombok.extern.slf4j.Slf4j; /**
* @author j
* 操作方式:
* 根据Excel格式编写vo,vo编写方式参照com.cinc.ecmp.demo.vo.ExcelMaterialVo
*/
@Slf4j
public class ExcelParseUtils { public static <T> List<T> parse(MultipartFile file,Class<T> clazz){
Workbook hwb=null;
InputStream in = null;
try{
if(null == file){
throw new BasException(BackResultEnum.DATAPARSEERR);
}
in = file.getInputStream();
hwb=WorkbookFactory.create(in);
Sheet sheet=hwb.getSheetAt(0);
if(sheet==null) {
return null;
}
List<T> excelVoList=new ArrayList<T>();
Field[] fields=clazz.getDeclaredFields();
for(int i=sheet.getFirstRowNum()+1;i<sheet.getPhysicalNumberOfRows();i++) {
Row row = sheet.getRow(i);
if(null==row.getCell(1)||row.getCell(1).getCellType()==CellType.BLANK) {
break;//如果这一行的第一列为空,则终止解析
}
T object = clazz.newInstance();
for(Field field:fields) {
//获取该字段的列号
ExcelField excelField=field.getAnnotation(ExcelField.class);
if(null == excelField) {
continue;
}
int index = excelField.index();
String value="";
Cell cell = row.getCell(index);
if(null == cell) {
continue;
}
CellType cellType = cell.getCellType();
switch(cellType) {
case STRING:
value = String.valueOf(cell.getRichStringCellValue());
break;
case FORMULA:
try {
value = String.valueOf(cell.getNumericCellValue());
}catch (Exception e) {
value = String.valueOf(cell.getRichStringCellValue());
}
break;
case NUMERIC:
if(HSSFDateUtil.isCellDateFormatted(cell)) {
Date date=HSSFDateUtil.getJavaDate(cell.getNumericCellValue());
value=DateUtil.getDateTimeStringToDb(date);
}else {
DecimalFormat df = new DecimalFormat();
value = df.format(cell.getNumericCellValue());
}
break;
case BLANK:
break;
default:
throw new BasException(BackResultEnum.DATAPARSEERR);
}
//非空判断
if(excelField.required()&&StringUtils.isEmpty(value)) {
log.error("【{}不能为空】",excelField.desc());
throw new BasException(BackResultEnum.DATAPARSEERR);
}
//数据合法性判断
String[] dataScopes=excelField.inList();
if(!CollectionUtils.isEmpty(Arrays.asList(dataScopes))&&!Arrays.asList(dataScopes).contains(value)) {
log.error("【{}不合法】",excelField.desc());
throw new BasException(BackResultEnum.DATAPARSEERR);
}
//字段类型设置
Class<?> typeClass=field.getType();
Method method = clazz.getMethod("set" + Character.toUpperCase(field.getName().charAt(0)) + field.getName().substring(1), typeClass);
//将字段值设置到对象中
try {
if(typeClass==Integer.class) {
method.invoke(object, value.indexOf(".")>0?Integer.parseInt(value.substring(0, value.indexOf("."))):Integer.parseInt(value));
}else if(typeClass==BigDecimal.class) {
method.invoke(object, new BigDecimal(value.indexOf(",")>0?value.replaceAll(",", ""):value));
}else {
method.invoke(object, value.indexOf(",")>0?value.replaceAll(",", ""):value);
}
}catch (Exception e) {
log.error("【{}设置错误】",excelField.desc(),e);
throw new BasException(BackResultEnum.DATAPARSEERR);
}
}
if(excelVoList.contains(object)) {
log.error("【导入失败,数据存在重复】");
throw new BasException(BackResultEnum.DATAREPEATERR);
}
excelVoList.add(object);
}
return excelVoList;
}catch (Exception e) {
log.error("【文件上传失败】",e);
throw new BasException(BackResultEnum.FILEUPLOADERR);
}finally {
if(null != hwb){
try {
hwb.close();
} catch (IOException e) {
log.error("【文件流关闭失败】",e);
}
}
if(null != in){
try {
in.close();
} catch (IOException e) {
log.error("【文件流关闭失败】",e);
}
}
}
}
}

  vo实体类的编写:

package com.cinc.ecmp.demo.vo;

import java.math.BigDecimal;

import com.cinc.ecmp.annotation.ExcelField;

import lombok.Data;

/**
* @author
* @time 2019年7月2日 下午7:59:26
*/
@Data
public class ExcelMaterialVo { @ExcelField(index=0,required=true,desc="材料名称")
private String name; @ExcelField(index=1,required=true,desc="价格")
private BigDecimal price; @ExcelField(index=2,required=true,desc="采购数量")
private Integer count;
}

注解的编写:

package com.cinc.ecmp.annotation;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target; @Retention(RUNTIME)
@Target(FIELD)
@Inherited
public @interface ExcelField { /**
* Excel表格列顺序,起始为0
* @return
*/
int index(); /***
* 数据范围
* @return
*/
String[] inList() default {}; /***
* 正则
* @return
*/
String pattern() default ""; /***
* 字段描述
* @return
*/
String desc() default ""; /**
* 是否是必须的
*
* @return
*/
boolean required() default false;
}

  

@Override
public List<ExcelMaterialVo> upload(MultipartFile file){
List<ExcelMaterialVo> excelMaterialVoList=ExcelParseUtils.parse(file, ExcelMaterialVo.class);
return excelMaterialVoList;
}

excel转换成实体的更多相关文章

  1. Epplus下的一个将Excel转换成List的范型帮助类

    因为前一段时间公司做项目的时候,用到了Excel导入和导出,然后自己找了个插件Epplus进行操作,自己将当时的一些代码抽离出来写了一个帮助类. 因为帮助类是在Epplus基础之上写的,项目需要引用E ...

  2. C# 将DataTable数据源转换成实体类

    using System; using System.Collections.Generic; using System.Data; using System.Reflection; /// < ...

  3. 字符串js编码转换成实体html编码的方法(防范XSS攻击)

    js代码在html页面中转换成实体html编码的方法一: <!DOCTYPE html><html> <head>    <title>js代码转换成实 ...

  4. C# DataTable转换成实体列表 与 实体列表转换成DataTable

    /// <summary> /// DataTable转换成实体列表 /// </summary> /// <typeparam name="T"&g ...

  5. sql hibernate查询转换成实体或对应的VO Transformers

    sql查询转换成实体或对应的VO Transformers //addScalar("id") 默认查询出来的id是全部大写的(sql起别名也无效,所以使用.addScalar(& ...

  6. hibernate查询部分字段转换成实体bean

    //hibernate查询部分字段转换成实体bean /** * 查询线路信息 */ @Override public List<Line> getSimpleLineListByTj(M ...

  7. How to cast List<Object> to List<MyClass> Object集合转换成实体集合

    List<Object> list = getList(); return (List<Customer>) list; Compiler says: cannot cast  ...

  8. Table转换成实体、Table转换成实体集合(可转换成对象和值类型)

    /// <summary> /// Table转换成实体 /// </summary> /// <typeparam name="T">< ...

  9. DataTable转换成实体

    public static class DataTableToEntity { /// <summary> /// 将DataTable数据源转换成实体类 /// </summary ...

随机推荐

  1. 在Swift中检查API的可用性

    http://www.cocoachina.com/swift/20150901/13283.html 本文由CocoaChina译者ALEX吴浩文翻译自Use Your Loaf博客 原文:Chec ...

  2. Gym - 101962K _ Rei do Cangaço

    题意:给予n个房间,每个房间可以的到x个金币(x可能为负数),可以进行两种操作: 右移3i个房间,并且打开除最后一个的所有房间,如在1号房间,第一次移动可以移动到4号,并且打开1,2,3三个房间. 只 ...

  3. postman post 数据格式

    postman post 数据的时候,选择raw的tab ,选择json. 然后在下面的提交json数据, {"photoPath":"bbbbbbbbbbbbbb&qu ...

  4. 枚举在switch中的运用

    Season.java package com.sxt.utils.enum2; public enum Season { 春,夏,秋,冬; } TestSeason.java package com ...

  5. 阿里云:面向5G时代的物联网无线连接服务

    在4月24日落幕的2019中国联通合作伙伴大会“5G+物联网(IoT)论坛”上,阿里云高级运营专家李茁出席圆桌对话,分享了5G时代物联网如何更好地推动行业完成生产.管理和商业模式的创新,阿里云又会以何 ...

  6. 使用DECLARE定义条件和处理程序

    定义条件和处理程序是事先定义程序执行过程中可能遇到的问题,并且可以在处理程序中定义解决这些问题的办法,可以简单理解 为异常处理,这种方式可以提前预测可能出现的问题,并提出解决办法,从而增强程序健壮性. ...

  7. uni-app设置 video开始播放进入全屏状态

    有一video标签 <video id="myVideo" :src="videoUrl"></video> 获取 video 上下文 ...

  8. Java容易搞错的知识点

    一.关于Switch 代码: Java代码 1         public class TestSwitch { 2             public static void main(Stri ...

  9. BERT-Pytorch demo初探

    https://zhuanlan.zhihu.com/p/50773178 概述 本文基于 pytorch-pretrained-BERT(huggingface)版本的复现,探究如下几个问题: py ...

  10. windows 关闭端口被占用脚本

    cmd 关闭进程java taskkill /F /IM java.exe taskkill /f /im java.exe 如何用dat批处理文件关闭某端口对应程序-Windows自动化命令 如何用 ...