JAVA讀取EXCEL_自動生成實體類


代碼實現
PropertyAnno.java

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)//規定用於全局變量
@Retention(RetentionPolicy.RUNTIME)//定義為運行時注解
/**
 * excel讀取所用注解
 * @author Administrator
 *
 */
public @interface PropertyAnno {
	
	String value() default "";
	
}

  AnnoCreator.java

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
 * 注解解釋工具類
 * @author Administrator
 *
 */
public class AnnoCreator {
	
	/**
	 * 注解解釋方法
	 * @return Map<屬性名(String), 注解名(String)>
	 */
	public static Map<String, String> annoCreator(Class<?> clazz) {
		Map<String, String> map = Collections.synchronizedMap(new HashMap<>());
		for (Field field : clazz.getDeclaredFields()) {
			//獲取屬性上所有注解
			Annotation[] annotations = field.getAnnotations();
			//判斷屬性上是否存在注解
			if(annotations.length < 1) {
				continue;
			}
			//判斷屬性上是否存在需要注解
			if(annotations[0] instanceof PropertyAnno) {
				map.put(field.getName(), ((PropertyAnno)annotations[0]).value());
			}
		}
		return map;
	}

}

  ReadExcel

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
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.xssf.usermodel.XSSFWorkbook;

public class ReadExcel<T> {

    /**
     * 錯誤信息
     */
    private String errorMsg;

    /**
     * 表格數據對象
     */
    private Class<T> clazz;

    /**
     * 改寫初始化方法,將對象傳入T
     */
    @SuppressWarnings("unchecked")
    public ReadExcel() {
        @SuppressWarnings("rawtypes")
        Class clazz = getClass();
        while (clazz != Object.class) {
            Type t = clazz.getGenericSuperclass();
            if (t instanceof ParameterizedType) {
                Type[] args = ((ParameterizedType) t).getActualTypeArguments();
                if (args[0] instanceof Class) {
                    this.clazz = (Class<T>) args[0];
                    break;
                }
            }
            clazz = clazz.getSuperclass();
        }
    }

    /**
     * 根據文件名讀取Excel文件
     * 
     * @param filePath 文件完整路徑
     * @return Map<表名(sheet名,String), 表中的屬性(List<T>)>
     */
    public Map<String, List<T>> read(String filePath) {
        Map<String, List<T>> map = null;
        InputStream is = null;
        try {
            // 驗證文件是否正確
            if (!validateExcel(filePath)) {
                System.out.println(errorMsg);
                return null;
            }
            // 判斷文件的類型,是2003還是2007
            boolean isExcel2003 = true;
            if (isExcel2007(filePath)) {
                isExcel2003 = false;
            }
            // 創建流進行讀取
            File file = new File(filePath);
            is = new FileInputStream(file);
            // 根據版本選擇創建Workbook的方式
            Workbook workbook = null;
            if (isExcel2003) {
                workbook = new HSSFWorkbook(is);
            } else {
                workbook = new XSSFWorkbook(is);
            }
            map = readExcel(workbook);
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    // 關閉連接
                    is.close();
                } catch (IOException e) {
                    is = null;
                    e.printStackTrace();
                }
            }
        }
        return map;
    }

    /**
     * 讀取Excel表格
     */
    @SuppressWarnings("deprecation")
    private Map<String, List<T>> readExcel(Workbook workbook) {
        Map<String, List<T>> map = Collections.synchronizedMap(new HashMap<>());
        List<T> list = null;
        // 獲取表格數量
        int numberOfSheets = workbook.getNumberOfSheets();

        for (int sheetNum = 0; sheetNum < numberOfSheets; sheetNum++) {
            list = new ArrayList<>();
            // 獲取注解
            Map<String, String> creatorMap = AnnoCreator.annoCreator(clazz);
            // 獲取指定的Excel
            Sheet sheet = workbook.getSheetAt(sheetNum);
            // 獲取Excel的行數
            int totalRows = sheet.getPhysicalNumberOfRows();
            // Excel的列數
            int totalCells = 0;
            if (totalRows >= 1 && sheet.getRow(0) != null) {
                // 獲取Excel的列數
                totalCells = sheet.getRow(0).getPhysicalNumberOfCells();
            }
            List<String> li = new ArrayList<>();
            // 循環Excel的行
            for (int r = 0; r < totalRows; r++) {
                // 獲取對象
                T t = null;
                try {
                    t = clazz.newInstance();
                } catch (InstantiationException | IllegalAccessException e) {
                    e.printStackTrace();
                }
                Row row = sheet.getRow(r);
                if (row == null) {
                    continue;
                }
                // 遍歷Excel的列
                for (int c = 0; c < totalCells; c++) {
                    Cell cell = row.getCell(c);
                    String cellValue = "";
                    if (null != cell) {
                        // 判斷數據的類型
                        switch (cell.getCellType()) {
                        case HSSFCell.CELL_TYPE_NUMERIC: // 數字
                            DecimalFormat df = new DecimalFormat("0");
                            cellValue = df.format(cell.getNumericCellValue());
                            break;
                        case HSSFCell.CELL_TYPE_STRING: // 字符串
                            cellValue = cell.getStringCellValue();
                            break;
                        case HSSFCell.CELL_TYPE_BOOLEAN: // Boolean
                            cellValue = cell.getBooleanCellValue() + "";
                            break;
                        case HSSFCell.CELL_TYPE_FORMULA: // 公式
                            cellValue = cell.getCellFormula() + "";
                            break;
                        case HSSFCell.CELL_TYPE_BLANK: // 空值
                            cellValue = "";
                            break;
                        case HSSFCell.CELL_TYPE_ERROR: // 故障
                            cellValue = "非法字符";
                            break;
                        default:
                            cellValue = "未知類型";
                            break;
                        }
                    }
                    //此處可修改為自己的表格樣式,例如打印第二行第二列的數據:
                    /* if(r == 1 && c == 1){
                        System.out.println(cellValue);
                    } */
                    if (r == 0) {
                        // 存儲第一行數據(列名)
                        li.add(cellValue);
                    } else {
                        // 存儲第一行后數據
                        fill(creatorMap, li.get(c), cellValue, t);
                    }
                }
                if (r != 0) {
                    list.add(t);
                }
            }
            map.put(sheet.getSheetName(), list);
        }
        return map;

    }
    
    /**
     * 判斷是否Excel格式是否為2003
     */
    private static boolean isExcel2003(String filePath) {
        return filePath.matches("^.+\\.(?i)(xls)$");
    }

    /**
     * 判斷是否Excel格式是否為2007
     */
    private static boolean isExcel2007(String filePath) {
        return filePath.matches("^.+\\.(?i)(xlsx)$");
    }

    /**
     * 驗證Excel文件
     */
    private boolean validateExcel(String filePath) {

        // 檢查文件名格式是否正確
        if (filePath == null || !(isExcel2003(filePath) || isExcel2007(filePath))) {
            System.out.println("文件名不是Excel格式");
            return false;
        }
        // 檢查文件是否存在
        File file = new File(filePath);
        if (file == null || !file.exists()) {
            System.out.println("文件不存在");
            return false;
        }
        return true;
    }

    /**
     * 為對象進行賦值
     * 
     * @param map 注解map(注解=屬性名)
     * @param str 當前讀取到的列名
     * @param obj 當前讀到的數據
     * @param t   需要進行賦值的對象
     */
    private void fill(Map<String, String> map, String str, String obj, T t) {
        for (Entry<String, String> entry : map.entrySet()) {
            try {
                if (str.equals(entry.getValue())) {
                    // 為對象進行賦值
                    Field f = clazz.getDeclaredField(entry.getKey().trim());
                    f.setAccessible(true);
                    f.set(t, obj);
                    return;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}

  BasicsEntity.java

/**
 * excel內容實體類(示例)
 * 注意:實體類屬性需定義為String類型
 * @author Administrator
 *
 */
public class BasicsEntity {
    
    @PropertyAnno("列名")//被注解字段與excel中列名對應
    private String name;//字段名
    
    @PropertyAnno("類型")
    private String type;//字段類型
    
    @PropertyAnno("長度")
    private String length;//字段長度
    
    @PropertyAnno("小數點長度")
    private String decimal;//小數點長度
    
    @PropertyAnno("默認值")
    private String defaults;//默認值

    @PropertyAnno("備注")
    private String annotation;//備注
    
    @PropertyAnno("是否為非空(Y或N)")
    private String isNull;//是否為非空(Y或N)
    
    @PropertyAnno("是否為主鍵(Y或N)")
    private String isPrincipal;//是否為主鍵(Y或N)

    @PropertyAnno("是否啟用主鍵自增(Y或N)")
    private String isProgressive;//是否啟用主鍵自增(Y或N)

    @Override
    public String toString() {
        return "BasicsEntity [name=" + name + ", type=" + type + ", length=" + length + ", decimal=" + decimal
                + ", defaults=" + defaults + ", annotation=" + annotation + ", isNull=" + isNull + ", isPrincipal="
                + isPrincipal + ", isProgressive=" + isProgressive + "]";
    }
}

  ReadTest.java

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.myutils.entity.BasicsEntity;
/**
 * 測試類
 * @author Administrator
 */
public class ReadTest {
    
    public static void main(String[] args) {
        //調用方法時必須寫成以下格式,否則反射無法獲取到實體類
        ReadExcel<BasicsEntity> util = new ReadExcel<BasicsEntity>(){};
        //調用方法,返回實體類集合
        Map<String, List<BasicsEntity>> map = util.read("D:數據庫文檔\\測試表格.xlsx");
        for (Entry<String, List<BasicsEntity>> baMap : map.entrySet()) {
            System.out.println("表名:" + baMap.getKey().split("\\|")[0]);
            System.out.println("表備注:" + baMap.getKey().split("\\|")[1]);
            for (BasicsEntity basicsEntity : baMap.getValue()) {
                System.out.println(basicsEntity.toString());
            }
        }
    }
}

  

pom.xml文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.cn</groupId>
  <artifactId>myExcel</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <dependencies>
     <dependency>
	    <groupId>org.apache.directory.studio</groupId>
	    <artifactId>org.apache.commons.codec</artifactId>
	    <version>1.8</version>
	</dependency>
	 <dependency>
		<groupId>net.sourceforge.jexcelapi</groupId>
		<artifactId>jxl</artifactId>
		<version>2.6.12</version>
	</dependency>
	<dependency>
		<groupId>org.apache.poi</groupId>
		<artifactId>poi-ooxml</artifactId>
		<version>3.9</version>
	</dependency>
<dependency>
   <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.54</version>
</dependency>

</dependencies>
</project>

  

測試使用表格:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM