JAVA实现Excel文件的导入导出

版权声明:请勿用于任何商业用途的文章转载,转载请说明出处!

1.导入POI的JAR包

<!-- excel POI -->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi</artifactId>
                <version>3.9</version>
                <type>pom</type>
            </dependency>
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml-schemas</artifactId>
                <version>3.9</version>
            </dependency>
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>3.9</version>
            </dependency>

2.Type:字段类型枚举

public enum ExcelType {
    ALL,        //全部
    EXPORT,     //仅导出
    IMPORT;     //仅导入

    private ExcelType(){

    }
}

3.字段注解:

//描述注解的使用范围,取值于:ElementType(PACKAGE:包、TYPE:[类、接口、枚举、Annotation类型]、CONSTRUCTOR:用于描述构造器、FIELD:描述属性、METHOD:方法
@Target(value = {ElementType.FIELD})
//注解的保存级别:取值于:RetentionPolicy(SOURCE:源文件有效、CLASS:class文件有效、RUNTIME:运行时有效,为RUNTIME时可以被反射读取。
@Retention(value = RetentionPolicy.RUNTIME)
public @interface FieldType {
    //字段类型枚举:ALL:导入导出,IMPORT:仅导入,EXPORT:仅导出
    ExcelType excelType() default ExcelType.ALL;
    //excel字段标题名称
    String excelFieldName();
    //导出时的字段排序,升序!
    int fieldSort() default 0;
    //是否必填字段,用于excel导入
    boolean isRequired() default false;
}

4.自定义注解列表类:需要lmbok支持,如果没有lombok,请自行编写get、set及构造器!

@Data
@AllArgsConstructor
public class ExcelAnnotationAnalysis implements Comparable<ExcelAnnotationAnalysis>{
    private String fieldName; //属性名称
    private Class<?> fieldType; //属性类型
    private ExcelType excelType;
    private String excelFieldName;
    private boolean isRequired;
    private int fieldSort;

    /**
     * 用于文件导出
     * @param fieldName
     * @param fieldType
     * @param excelType
     * @param excelFieldName
     * @param fieldSort
     */
    public ExcelAnnotationAnalysis(String fieldName, Class<?> fieldType, ExcelType excelType, String excelFieldName, int fieldSort) {
        this.fieldName = fieldName;
        this.fieldType = fieldType;
        this.excelType = excelType;
        this.excelFieldName = excelFieldName;
        this.fieldSort = fieldSort;
    }

    /**
     * 用于文件导入
     * @param fieldName
     * @param fieldType
     * @param excelType
     * @param excelFieldName
     * @param isRequired
     */
    public ExcelAnnotationAnalysis(String fieldName, Class<?> fieldType, ExcelType excelType, String excelFieldName, boolean isRequired) {
        this.fieldName = fieldName;
        this.fieldType = fieldType;
        this.excelType = excelType;
        this.excelFieldName = excelFieldName;
        this.isRequired = isRequired;
    }

    @Override
    public int compareTo(ExcelAnnotationAnalysis annotationAnalysis) {
        //        return this.age-o.age; 升序排序
        //        return o.age-this.age; 降序排序
        return this.fieldSort - annotationAnalysis.fieldSort;
    }
}

5.excel父类:

public class BaseExcel implements Serializable {
    private static final long serialVersionUID = -3613807567180016253L;
    public static final String DEFAULT_FILE_NAME = "template";
    public static final String DEFAULT_SHEET_NAME = "sheet1";
    public static final int XLSX_MAX_ROW_NUMBER = 1048576;
    public static final int XLSX_MAX_COLUMN_NUMBER = 16384;
    public static final int XLS_MAX_ROW_NUMBER = 65536;
    public static final int XLS_MAX_COLUMN_NUMBER = 256;

    //excel的实体类注解
    @Getter
    protected List<ExcelAnnotationAnalysis> annotationAnalyses;
    @Getter
    protected Workbook workbook;
    @Getter
    protected Sheet sheet;
    //数据行集合
    @Getter
    protected List<?> dataList;
    @Setter
    @Getter
    protected String sheetName;
    @Setter
    @Getter
    protected String fileName;

}

6.ExcelException:自定义异常

public class ExcelException extends RuntimeException {
    private static final long serialVersionUID = -2584487079216503519L;

    public ExcelException() {
    }

    public ExcelException(String message) {
        super(message);
    }

    public ExcelException(Throwable cause) {
        super(cause);
    }

    public ExcelException(String message, Throwable cause) {
        super(message, cause);
    }
}

7.ExcelExport:导出excel

public class ExcelExport extends BaseExcel implements Serializable {
    private static final long serialVersionUID = 5597585505462001671L;

    //表头:非必要
    @Getter
    private String title;
    //标题行,KEY:实体类field名称,VALUE:excel标题字段名称
    @Getter
    private Map<String , String> header = new LinkedHashMap<>();
    //列数量,用于表头合并单元格
    @Getter
    private int columnCount;

    public void setDataList(List<?> dataList){
        if (dataList.size() > (XLSX_MAX_ROW_NUMBER - 2)){
            throw new ExcelException("ExcelException:需要导出的记录数超出Excel的最大值!最大值:" + (XLSX_MAX_ROW_NUMBER - 2));
        }else if (EmptyUtil.isEmpty(dataList)){
            throw new ExcelException("ExcelException:没有需要导出的数据!");
        }
        this.dataList = dataList;
    }

    /**
     * 创建工作簿
     */
    public void setWorkbook(){
        this.workbook = new XSSFWorkbook();
    }

    /**
     * 创建标题行,按照列数合并单元格
     * @param rowNum 指定标题行的行号
     * @return
     */
    private void createTitle(int rowNum){
        XSSFRow titleRow = (XSSFRow) this.sheet.createRow(rowNum);
        XSSFCell titleCell = addCell(titleRow , 0 , this.title);
        if (this.columnCount > 1){
            //合并列 生成标题行
            CellRangeAddress cellRangeAddress = new CellRangeAddress(rowNum , rowNum , 1 , this.columnCount);
            this.sheet.addMergedRegion(cellRangeAddress);
        }
    }

    /**
     * 创建表头
     * @param rowNum 指定表头行的行号
     * @return
     */
    private void createHeader(int rowNum){
        XSSFRow headerRow = (XSSFRow) this.sheet.createRow(rowNum);
        int cellIndex = 0;
        for (Map.Entry<String , String> map:this.header.entrySet()
             ) {
            Cell headerCell = addCell(headerRow , cellIndex , map.getValue());
            cellIndex++;
        }
    }

    private XSSFRow createDataRow(Sheet sheet , int rowNum , Object entity){
        XSSFRow row = (XSSFRow) sheet.createRow(rowNum);
        Map<String , Object> fieldMap = new HashMap<>();
        List<Field> fieldList = ReflexUtil.getObjectFields(entity);
        int cellIndex = 0;
        for (Map.Entry<String , String> entry:this.header.entrySet()
             ) {
            String fieldName = entry.getKey();
            for (int i = 0; i < fieldList.size(); i++) {
                String fn1 = fieldList.get(i).getName();
                if (fn1.equals(fieldName)){
                    addCell(row , cellIndex , ReflexUtil.getFieldValue(entity , fn1));
                    break;
                }
            }
            cellIndex++;
        }
        return row;
    }

    public ExcelExport(HttpServletResponse response,List<?> dataList , Class<?> clazz , String... args){
        try {
            setDataList(dataList);
            setAnnotationAnalyses(clazz);
            if (this.annotationAnalyses.size() == 0){
                throw new ExcelException("Excel Exception:annotationAnalyses is null");
            }
            setFileAttribute(args);
            response.reset();
            response.setContentType("application/octet-stream; charset=utf-8");
            response.setHeader("Content-Disposition", "attachment; filename=" + this.fileName + ".xlsx");
            createWorkbook();
            OutputStream os = response.getOutputStream();
            this.workbook.write(os);
            os.flush();
            os.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private void setFileAttribute(String... args){
        String fileName = ExcelExport.DEFAULT_FILE_NAME;
        String sheetName = ExcelExport.DEFAULT_SHEET_NAME;
        if (args.length > 3){
            throw new ExcelException("ExcelException:传入的参数过多!");
        }
        if (args.length == 1 && EmptyUtil.isNoEmpty(args[0])){
            fileName = args[0];
        }
        if (args.length >= 2){
            fileName = EmptyUtil.isNoEmpty(args[0])?args[0]:fileName;
            sheetName = EmptyUtil.isNoEmpty(args[1])?args[1]:sheetName;
        }
        if (args.length == 3 && EmptyUtil.isNoEmpty(args[2])){
            setTitle(args[2]);
        }

        setFileName(fileName);
        setSheetName(sheetName);
    }

    private void createWorkbook(){
        setHeader();
        setWorkbook();
        setSheet();
        int rowIndex = 0;
        // 创建标题行
        if (EmptyUtil.isNoEmpty(this.title)){
            createTitle(rowIndex);
            rowIndex++;
        }
        // 创建表头行
        createHeader(rowIndex);
        //插入数据明细
        rowIndex++;
        for (int i = 0; i < this.dataList.size(); i++) {
            createDataRow(this.sheet , rowIndex , this.dataList.get(i));
            rowIndex++;
        }
    }

    public void setSheet(){
        this.sheet = this.workbook.createSheet(sheetName);
    }

    /**
     * 获取实体类中的注解,如果需要生成导入模板,可以重写该方法。
     * @param clazz
     */
    public void setAnnotationAnalyses(Class<?> clazz){
        this.annotationAnalyses = ExcelUtil.getAnnotationAnalyses(clazz , ExcelType.EXPORT);
        if (this.annotationAnalyses.size() > ExcelExport.XLSX_MAX_COLUMN_NUMBER){
            throw new ExcelException("ExcelException:需要导出的数据列超出Excel允许的最大范围!最大值:" + ExcelExport.XLSX_MAX_COLUMN_NUMBER);
        }
    }

    public void setTitle(String title){
        this.title = title;
    }

    public void setHeader(){
        for (ExcelAnnotationAnalysis en:this.annotationAnalyses
             ) {
            this.header.put(en.getFieldName() , en.getExcelFieldName());
        }
    }

    public void setColumnCount(){
        this.columnCount = this.annotationAnalyses.size();
    }

    private XSSFCell addCell(XSSFRow row , int column , Object val){
        XSSFCell cell = row.createCell(column);
        if (EmptyUtil.isEmpty(val)){
            cell.setCellValue("");
        }else if (val instanceof Integer){
            cell.setCellValue((double)(Integer)val);
        }else if (val instanceof Long){
            cell.setCellValue((double)(Long)val);
        }else if (val instanceof Double){
            cell.setCellValue((Double)val);
        }else if (val instanceof Float){
            cell.setCellValue((double)(Float)val);
        }else if (val instanceof Date){
            cell.setCellValue((Date)val);
        }else if (val instanceof String){
            cell.setCellValue(String.valueOf(val));
        }
        else {
            cell.setCellValue(String.valueOf(val));
        }
        return cell;
    }
}

8.ExcelImport:导入excel

public class ExcelImport extends BaseExcel implements Serializable {
    private static final long serialVersionUID = 7085381286559343720L;
    @Getter
    private Map<Integer , String> header = new LinkedHashMap<>();


    public void setHeader(Sheet sheet , int headerRowNum , Class<?> clazz){
        //获取实体类注解属性
        setAnnotationAnalyses(clazz);
        Row row = sheet.getRow(headerRowNum);
        int firstCellIndex = row.getFirstCellNum();
        int lastCellIndex = row.getLastCellNum();

        for (ExcelAnnotationAnalysis annotationAnalysis:this.annotationAnalyses
             ) {
            String excelFieldName = annotationAnalysis.getExcelFieldName();
            ExcelType excelType = annotationAnalysis.getExcelType();
            if (excelType == ExcelType.ALL || excelType == ExcelType.IMPORT){
                boolean isRequired = annotationAnalysis.isRequired();
                boolean flag = false;
                for (int i = firstCellIndex; i < lastCellIndex; i++) {
                    String cellValue = String.valueOf(getCellValue(row , i));
                    if (EmptyUtil.isEmpty(cellValue)){
                        throw new ExcelException("ExcelException:导入的excel文件,标题行存在空值,column num = " + i);
                    }
                    if (EmptyUtil.isNoEmpty(cellValue) && cellValue.equals(excelFieldName)){
                        flag = true;
                        this.header.put(i , cellValue);
                        break;
                    }
                }
                if (isRequired && flag != true){
                    throw new ExcelException("ExcelException:导入的excel文件缺少必填字段:" + excelFieldName);
                }
            }
        }
        if (EmptyUtil.isEmpty(this.header)){
            throw new ExcelException("ExcelException:没有可用于导入的数据,请确认!");
        }
    }

    private Object getCellValue(Row row , int column){
        Object val = "";
        try {
            Cell cell = row.getCell(column);
            if (cell != null){
                if (cell.getCellType() == 0){
                    val = cell.getNumericCellValue();
                    if (HSSFDateUtil.isCellDateFormatted(cell)){
                        val = DateUtil.getJavaDate((Double) val);
                    }else {
                        val = new DecimalFormat("0").format(val);
                    }
                }else if (cell.getCellType() == 1){
                    val = cell.getStringCellValue();
                }else if (cell.getCellType() == 2){
                    try {
                        val = cell.getStringCellValue();
                    }catch (Exception e1){
                        FormulaEvaluator evaluator = cell.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
                        evaluator.evaluateFormulaCell(cell);
                        CellValue cellValue = evaluator.evaluate(cell);
                        switch(cellValue.getCellType()) {
                            case 0:
                                val = cellValue.getNumberValue();
                                break;
                            case 1:
                                val = cellValue.getStringValue();
                                break;
                            case 2:
                            case 3:
                            default:
                                val = cell.getCellFormula();
                                break;
                            case 4:
                                val = cellValue.getBooleanValue();
                                break;
                            case 5:
                                val = ErrorEval.getText(cellValue.getErrorValue());
                        }
                    }
                }else if (cell.getCellType() == 4){
                    val = cell.getBooleanCellValue();
                }else if (cell.getCellType() == 5){
                    val = cell.getErrorCellValue();
                }
            }
            return val;
        }catch (Exception e){
            return val;
        }
    }

    /**
     * 读取excel中的工作表
     * @param fileName
     * @param in
     */
    public void setWorkbook(String fileName , InputStream in){
        try {
            if (fileName.endsWith("xls")){
                this.workbook = new HSSFWorkbook(in);
            }else if (fileName.endsWith("xlsx")){
                this.workbook = new XSSFWorkbook(in);
            }else {
                throw new ExcelException("ExcelException:导入的文档格式不正确,必须是xls或者xlsx文件!");
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 读取excel中指定的sheet
     * @param wb
     * @param sheetIndexOrName 指定的sheet索引,当为数字时,按sheet序号读取sheet,sheet下标从0开始
     */
    public void setSheet(Workbook wb , Object sheetIndexOrName){
        if (sheetIndexOrName instanceof Integer || sheetIndexOrName instanceof Long){
            Long index = ((Number) sheetIndexOrName).longValue();
            this.sheet = this.workbook.getSheetAt(index.intValue());
        }else {
            this.sheet = this.workbook.getSheet(String.valueOf(sheetIndexOrName));
        }

        if (this.sheet == null){
            throw new ExcelException("ExcelException:没有找到" + sheetIndexOrName + "工作表!");
        }
    }


    private  <E>E getRowData(Row row , Class<E> clazz){
        try {
            E entity = clazz.newInstance();
            for (Map.Entry<Integer , String> map:this.header.entrySet()
                 ) {
                String excelFieldName = map.getValue();
                Integer columnIndex = map.getKey();
                for (ExcelAnnotationAnalysis annotationAnalysis:this.annotationAnalyses
                     ) {
                    if (excelFieldName.equals(annotationAnalysis.getExcelFieldName())){
                        Object val = getCellValue(row , columnIndex);
                        ReflexUtil.setFieldValue(entity , annotationAnalysis.getFieldName() , val);
                        break;
                    }
                }
            }
            return entity;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    public <E>List<E> readExcel2List(MultipartFile file , Object sheetIndexOrName , Class<E> clazz , int headerRowNum){
        try {
            setWorkbook(file.getOriginalFilename() , file.getInputStream());
            return getDataList(sheetIndexOrName, clazz, headerRowNum);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    public <E>List<E> readExcel2List(File file , Object sheetIndexOrName , Class<E> clazz , int headerRowNum){
        try {
            setWorkbook(file.getName() , new FileInputStream(file));
            return getDataList(sheetIndexOrName, clazz, headerRowNum);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    private <E>List<E> getDataList(Object sheetIndexOrName, Class<E> clazz, int headerRowNum) {
        try {
            setSheet(this.workbook , sheetIndexOrName);
            setHeader(this.sheet , headerRowNum , clazz);
            int dataRowNumIndex = headerRowNum + 1;
            // 最后一行 行号
            int dataLastRowNum = this.sheet.getLastRowNum();
            if (dataLastRowNum < dataRowNumIndex){
                throw new ExcelException("ExcelException:没有可导入的数据!");
            }

            List<E> list = new ArrayList<>();
            for (int i = dataRowNumIndex; i <= dataLastRowNum; i++) {
                E entity = getRowData(this.sheet.getRow(i) , clazz);
                list.add(entity);
            }
            return list;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取实体类中的注解
     * @param clazz
     */
    private void setAnnotationAnalyses(Class<?> clazz){
        try {
            this.annotationAnalyses = ExcelUtil.getAnnotationAnalyses(clazz , ExcelType.IMPORT);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

9.用到的工具类:

9.1 Excel工具类

public class ExcelUtil implements Serializable {
    private static final long serialVersionUID = 5952245122807291623L;

    public static List<ExcelAnnotationAnalysis> getAnnotationAnalyses(Class<?> clazz , ExcelType type){
        List<ExcelAnnotationAnalysis> annotationAnalyses = new ArrayList<>();
        List<Field> fieldList = ReflexUtil.getObjectFields(clazz);
        for (Field f1:fieldList
        ) {
            FieldType fieldType = f1.getAnnotation(FieldType.class);
            if (EmptyUtil.isNoEmpty(fieldType) && (fieldType.excelType() == type || fieldType.excelType() == ExcelType.ALL)){
                ExcelAnnotationAnalysis annotationAnalysis;
                if (type == ExcelType.EXPORT){
                    annotationAnalysis   = new ExcelAnnotationAnalysis(f1.getName() , f1.getType() , fieldType.excelType() , fieldType.excelFieldName() , fieldType.fieldSort());
                }else if (type == ExcelType.IMPORT){
                    annotationAnalysis = new ExcelAnnotationAnalysis(f1.getName() , f1.getType() , fieldType.excelType() , fieldType.excelFieldName() , fieldType.isRequired());
                }else {
                    throw new ExcelException("ExcelException:不可预知的动作,请确认具体操作:导入 or 导出!");
                }
                annotationAnalyses.add(annotationAnalysis);
            }
        }
        // list 排序
        Collections.sort(annotationAnalyses);
        return annotationAnalyses;
    }

    /**
     * 文件导出
     * @param response
     * @param dataList
     * @param clazz
     * @param args 定义一组文件属性,允许为空,最大允许长度:3个参数。0:fileName,1:sheetName,2:顶端标题,默认没有标题行
     */
    public static void export4List(HttpServletResponse response, List<?> dataList , Class<?> clazz , String... args){
        new ExcelExport(response , dataList , clazz , args);
    }

    /**
     * MultipartFile方式导入文件
     * @param file
     * @param sheetIndexOrName
     * @param clazz
     * @param headerRowNum
     * @param <E>
     * @return
     */
    public static <E>List<E> import2List(MultipartFile file , Object sheetIndexOrName , Class<E> clazz , int headerRowNum){
        ExcelImport excelImport = new ExcelImport();
        return excelImport.readExcel2List(file , sheetIndexOrName , clazz , headerRowNum);
    }

    /**
     * File方式导入文件
     * @param file
     * @param sheetIndexOrName
     * @param clazz
     * @param headerRowNum
     * @param <E>
     * @return
     */
    public static <E>List<E> import2List(File file , Object sheetIndexOrName , Class<E> clazz , int headerRowNum){
        ExcelImport excelImport = new ExcelImport();
        return excelImport.readExcel2List(file , sheetIndexOrName , clazz , headerRowNum);
    }
}

9.2:反射工具类: 

public class ReflexUtil {

    /**
     * 返回 entity 对象的所有属性,包含父类
     * @param obj
     * @return
     */
    public static List<Field> getObjectFields(Object obj){
        Class clazz = obj.getClass();
        List<Field> fieldList = new ArrayList<>() ;
        while (clazz != null) {//当父类为null的时候说明到达了最上层的父类(Object类).
            fieldList.addAll(Arrays.asList(clazz .getDeclaredFields()));
            clazz = clazz.getSuperclass(); //得到父类,然后赋给自己
        }
        return fieldList;
    }

    public static List<Field> getObjectFields(Class<?> clazz){
        List<Field> fieldList = new ArrayList<>() ;
        while (clazz != null){
            fieldList.addAll(Arrays.asList(clazz .getDeclaredFields()));
            clazz = clazz.getSuperclass(); //得到父类,然后赋给自己
        }
        return fieldList;
    }

    /**
     * 判断 Class entity 是否存在名称为 fieldName 的属性
     * @param fieldName
     * @param entity
     * @return
     */
    public static Boolean isField(String fieldName , Object entity){
        List<Field> fieldList = getObjectFields(entity);
        for (Field f1:fieldList
        ) {
            if (fieldName.equals(f1.getName()))
                return true;
        }
        return false;
    }

    /**
     * 返回 entity 对象中的所有方法,包含父类
     * @param entity
     * @return
     */
    public static List<Method> getObjectMethods(Object entity){
        Class<?> clazz = entity.getClass();
        List<Method> methods = new ArrayList<>();
        while (clazz != null && clazz != Object.class) {//当父类为null的时候说明到达了最上层的父类(Object类).
            methods.addAll(Arrays.asList(clazz .getDeclaredMethods()));
            clazz = clazz.getSuperclass(); //得到父类,然后赋给自己
        }
        return methods;
    }

    public static List<Method> getObjectMethods(Class<?> clazz){
        List<Method> methods = new ArrayList<>();
        while (clazz != null && clazz != Object.class) {//当父类为null的时候说明到达了最上层的父类(Object类).
            methods.addAll(Arrays.asList(clazz .getDeclaredMethods()));
            clazz = clazz.getSuperclass(); //得到父类,然后赋给自己
        }
        return methods;
    }

    /**
     * 判断 Class entity 是否存在名称为 methodName 的方法
     * @param methodName
     * @param entity
     * @return
     */
    public static Boolean isMethod(String methodName , Object entity){
        List<Method> methods = getObjectMethods(entity);
        for (Method m1:methods
        ) {
            if (methodName.equals(m1.getName()))
                return true;
        }
        return false;
    }

    /**
     * 循环向上转型, 获取对象的 DeclaredMethod
     * @param obj
     * @param methodName
     * @param parameterTypes  方法参数类型
     * @return
     */
    public static Method getDeclaredMethod(Object obj , String methodName , Class<?>...parameterTypes) {
        for (Class<?> clazz = obj.getClass(); clazz != Object.class && clazz != null; clazz = clazz.getSuperclass()) {
            try {
                return clazz.getDeclaredMethod(methodName, parameterTypes);
            } catch (Exception e) {
                // 这里甚么都不要做!并且这里的异常必须这样写,不能抛出去。
                // 如果这里的异常打印或者往外抛,则就不会执行clazz=clazz.getSuperclass(),最后就不会进入到父类中了
            }
        }
        return null;
    }

    public static Object invoke(Object object, String methodName, Class<?>[] parameterTypes,
                                Object[] parameters){
        Method method = getDeclaredMethod(object, methodName, parameterTypes);
        try {
            if (method != null){
                method.setAccessible(true);
                // 调用object 的 method 所代表的方法,其方法的参数是 parameters
                return method.invoke(object, parameters);
            }
        }catch (Exception e1){
            e1.printStackTrace();
        }
        return null;
    }

    /**
     * 循环向上转型, 获取对象的 DeclaredField
     *
     * @param object
     *            : 子类对象
     * @param fieldName
     *            : 父类中的属性名
     * @return 父类中的属性对象
     */

    public static Field getDeclaredField(Object object, String fieldName) {
        Field field = null;

        Class<?> clazz = object.getClass();

        for (; clazz != Object.class && clazz != null; clazz = clazz.getSuperclass()) {
            try {
                field = clazz.getDeclaredField(fieldName);
                return field;
            } catch (Exception e) {
                // 这里甚么都不要做!并且这里的异常必须这样写,不能抛出去。
                // 如果这里的异常打印或者往外抛,则就不会执行clazz = clazz.getSuperclass(),最后就不会进入到父类中了

            }
        }

        return null;
    }

    /**
     * 直接设置对象属性值, 忽略 private/protected 修饰符, 也不经过 setter
     *
     * @param object
     *            : 子类对象
     * @param fieldName
     *            : 父类中的属性名
     * @param value
     *            : 将要设置的值
     */

    public static void setFieldValue(Object object, String fieldName, Object value) {

        // 根据 对象和属性名通过反射 调用上面的方法获取 Field对象
        Field field = getDeclaredField(object, fieldName);

        if (field != null){
            // 抑制Java对其的检查
            field.setAccessible(true);
            try {
                // 将 object 中 field 所代表的值 设置为 value
                field.set(object, value);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 直接读取对象的属性值, 忽略 private/protected 修饰符, 也不经过 getter
     *
     * @param object
     *            : 子类对象
     * @param fieldName
     *            : 父类中的属性名
     * @return : 父类中的属性值
     */

    public static Object getFieldValue(Object object, String fieldName) {
        // 根据 对象和属性名通过反射 调用上面的方法获取 Field对象
        Field field = getDeclaredField(object, fieldName);

        if (field != null){
            // 抑制Java对其的检查
            field.setAccessible(true);
            try {
                // 获取 object 中 field 所代表的属性值
                return field.get(object);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }


}

9.3判空工具类 

public class EmptyUtil {
    //Suppress default constructor for noninstantiability
    private EmptyUtil(){
        throw new AssertionError();
    }

    public static boolean isEmpty(Object object){
        if (object == null){
            return true;
        }
        if (object instanceof int[]){
            return ((int[]) object).length == 0;
        }
        if (object instanceof double[]){
            return ((double[]) object).length == 0;
        }
        if (object instanceof long[]){
            return ((long[]) object).length == 0;
        }
        if (object instanceof byte[]){
            return ((byte[]) object).length == 0;
        }
        if (object instanceof short[]){
            return ((short[]) object).length == 0;
        }
        if (object instanceof float[]){
            return ((float[]) object).length == 0;
        }
        if (object instanceof char[]){
            return ((char[]) object).length == 0;
        }
        if (object instanceof Object[]){
            return ((Object[]) object).length == 0;
        }
        if (object instanceof CharSequence) {
            return ((CharSequence) object).length() == 0;
        }
        if (object instanceof Collection ){
            return ((Collection) object).isEmpty();
        }
        if (object instanceof Map){
            return ((Map) object).isEmpty();
        }
        return false;
    }

    public static boolean isNoEmpty(Object object){
        return !isEmpty(object);
    }

}

10.使用范例:

10.1实体类:

@Data
@ToString(callSuper = true)
@NoArgsConstructor
@EqualsAndHashCode(callSuper = false)
@TableName(value = "goods")
public class Goods extends PageEntity<Goods> {
    private static final long serialVersionUID = -5648682279628349903L;
    @NonNull
    @FieldType(excelType = ExcelType.ALL , excelFieldName = "代码" , fieldSort = 0)
    private String code;
    @NonNull
    @FieldType(excelType = ExcelType.IMPORT , isRequired = true , excelFieldName = "名称")
    private String name;
}

7.2 controller层:

/**
     * 导出excel演示
     * @param request
     * @param resp
     */
    @RequestMapping(value = "/fileDownload" , method = RequestMethod.GET)
    public void fileDownload(HttpServletRequest request, HttpServletResponse resp){
        try {
            List<Goods> goodsList = goodsService.list();
            ExcelUtil.export4List(resp , goodsList , Goods.class , "exportFileName" , "exportSheetName" , "测试Excel文件导出");
        }catch (Exception e){
            e.getMessage();
        }
    }

    /**
     * 导入excel演示
     * @param file
     */
    @RequestMapping(value = "/excelImport")
    @ResponseBody
    public void excelImport(@RequestParam("file") MultipartFile file){
        List<Goods> goodsList = ExcelUtil.import2List(file , 0 , Goods.class , 1);
        for (Goods goods:goodsList
             ) {
            System.out.println("导入数据 = " + goods);
        }
    }

8.前端:

                        <button type="button" class="btn" id="download" >下载</button>
                        <form method="post" id="importForm" enctype="multipart/form-data">
                            <input type="file" name="file"><br>
                            <button type="button" class="btn" onsubmit="return false" id="import" >导入</button>
                        </form>

//强调一下:不要使用ajax方式请求下载文件!!!!!

//JS部分:
$(document).on('click' , function (event) {
                let targetId = event.target.id;
                if (targetId == 'download'){
                    window.location.href = "/a/goods/fileDownload";
                }
if (targetId == 'import'){
                    $.ajax({
                        type:'POST',
                        url:'/a/goods/excelImport',
                        dataType:'JSON',
                        cache:false,
                        processData: false,
                        contentType: false,
                        data:new FormData($('#importForm')[0]),
                        async:false,
                        success:function (result) {

                        },
                        error:function () {

                        }
                    });
                    return false;
                }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值