1. 程式人生 > >【Java工具四】Java通用Excel匯入

【Java工具四】Java通用Excel匯入

package com.zhengtoon.enforcelaw.utils;

import com.zhengtoon.enforcelaw.dto.ElUserInfoDTO;
import org.apache.commons.lang3.reflect.FieldUtils;
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;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class ImportExcelFileUtil {
    private static final Logger log = LoggerFactory.getLogger(ImportExcelFileUtil.class);
    private final static String excel2003L =".xls";    //2003- 版本的excel
    private final static String excel2007U =".xlsx";   //2007+ 版本的excel

    /**
     * 拼裝單個obj  通用
     *
     * @param obj
     * @param row
     * @return
     * @throws Exception
     */
    private  static Map<String, Object> dataObj(Object obj, Row row) throws Exception {
        Class<?> rowClazz= obj.getClass();
        Field[] fields = FieldUtils.getAllFields(rowClazz);
        if (fields == null || fields.length < 1) {
            return null;
        }

        //容器
        Map<String, Object> map = new HashMap<String, Object>();

        //注意excel表格欄位順序要和obj欄位順序對齊 (如果有多餘欄位請另作特殊下標對應處理)
        for (int j = 0; j < fields.length; j++) {
            map.put(fields[j].getName(), getVal(row.getCell(j)));
        }
        return map;
    }

    /**
     * 處理val
     *
     * @param cell
     * @return
     */
    public static String getVal(Cell cell) {
        Object value = null;
        DecimalFormat df = new DecimalFormat("0");  //格式化字元型別的數字
        SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd");  //日期格式化
        DecimalFormat df2 = new DecimalFormat("0.00");  //格式化數字
        switch (cell.getCellType()) {
            case Cell.CELL_TYPE_STRING:
                value = cell.getRichStringCellValue().getString();
                break;
            case Cell.CELL_TYPE_NUMERIC:
                if ("General".equals(cell.getCellStyle().getDataFormatString())) {
                    value = df.format(cell.getNumericCellValue());
                } else if ("m/d/yy".equals(cell.getCellStyle().getDataFormatString())) {
                    value = sdf.format(cell.getDateCellValue());
                } else {
                    value = df2.format(cell.getNumericCellValue());
                }
                break;
            case Cell.CELL_TYPE_BOOLEAN:
                value = cell.getBooleanCellValue();
                break;
            case Cell.CELL_TYPE_BLANK:
                value = "";
                break;
            default:
                break;
        }
        return value.toString();
    }

    /**
     * * 讀取出filePath中的所有資料資訊
     *
     * @param filePath excel檔案的絕對路徑
     * @param obj
     * @return
     */
    public static List<Map<String, Object>> getDataFromExcel(String filePath, Object obj){

        if (null == obj) {
            return null;
        }

        List<Map<String, Object>> ret = null;
        FileInputStream fis =null;
        Workbook wookbook = null;
        int lineNum = 0;
        Sheet sheet = null;
        try{
            //獲取一個絕對地址的流
            fis = new FileInputStream(filePath);
            wookbook = getWorkbook(fis,filePath);
            //得到一個工作表
            sheet = wookbook.getSheetAt(0);
            //獲得表頭
            Row rowHead = sheet.getRow(0);
            //列數
            int rows = rowHead.getPhysicalNumberOfCells();
            //行數
            lineNum = sheet.getLastRowNum();
            if (0 == lineNum) {
                log.info("ImportExcelFileUtil中的getDataFromExcel方法匯入的Excel內沒有資料!");
                return null;
            }
            ret = getData(sheet, lineNum, rows, obj);
        } catch (Exception e){
            e.printStackTrace();
        }

        return ret;
    }

    /**
     * 封裝獲取的物件資訊
     *
     * @param sheet
     * @param lineNum
     * @param rowNum
     * @param obj
     * @return
     */
    public static List<Map<String, Object>>  getData(Sheet sheet, int lineNum, int rowNum, Object obj){
        List<Map<String, Object>> ret = null;
        try {
            //容器
            ret = new ArrayList<Map<String, Object>>();
            //獲得所有資料
            for (int i = 1; i <= lineNum; i++) {
                //獲得第i行物件
                Row row = sheet.getRow(i);
                if (row!=null) {
                    //裝載obj
                    ret.add(dataObj(obj,row));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ret;
    }

    /**
     * 描述:根據檔案字尾,自適應上傳檔案的版本
     *
     * @param inStr,fileName
     * @return
     * @throws Exception
     */
    public static Workbook getWorkbook(InputStream inStr, String fileName) throws Exception{
        Workbook wb = null;
        String fileType = fileName.substring(fileName.lastIndexOf("."));
        if (excel2003L.equals(fileType)) {
            wb = new HSSFWorkbook(inStr);  //2003-
        } else if (excel2007U.equals(fileType)) {
            wb = new XSSFWorkbook(inStr);  //2007+
        } else {
            throw new Exception("解析的檔案格式有誤!");
        }
        return wb;
    }
public static void main(String[] args) throws Exception{
    ElUserInfoDTO dto = new ElUserInfoDTO();
    //實體類的屬性要與Excel中的行數保持一致。本人之前就栽在這,我在實體類裡實現Serializable並生成了serialVersionUID,
    //和excel中的行數不一致。
    List<Map<String, Object>> dataFromExcel = getDataFromExcel("D:\\img\\測試4.xls", dto);
    for (int i = 0; i < dataFromExcel.size(); i++) {
        for (Map.Entry<String, Object> entry : dataFromExcel.get(i).entrySet()) {
            System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
        }
    }
    System.out.println(dataFromExcel);
}
}