poi 导入 excel (需要 jdk 1.8 版本 或者 以上。。。)

package org.dcexam.cms.core.plugin;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
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;
import java.util.function.Function;

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.dcexam.cms.module.entity.Question;

/**
 * @author 王海明
 * @createData 2017年8月15日 下午2:24:35
 * @说明 : poi 导入 导出
 */
public class PoiPlugin {

    public static void main(String[] args) throws Exception {

        // 每行的 逻辑。。。
        // String path = "E:/test1.xlsx";
        String path = "E:/question_1.xlsx";
        InputStream input = new FileInputStream(new File(path));
        Map<String, Function<Object, Object>> formaterMap = new HashMap<>();
        formaterMap.put("difficulty", value -> {
            return Integer.valueOf((String) value);
        });
        formaterMap.put("qtid", value -> {
            String typeStr = (String) value;
            int type = 0;
            if (typeStr.startsWith("单选"))
                type = 1;
            else if (typeStr.startsWith("多选"))
                type = 2;
            else if (typeStr.startsWith("判断"))
                type = 3;
            else if (typeStr.startsWith("排序"))
                type = 4;
            else if (typeStr.startsWith("填空"))
                type = 5;
            else if (typeStr.startsWith("简答"))
                type = 6;
            return type;
        });

        @SuppressWarnings("serial")
        List<Object> listFromExcel = getListFromExcel(path, input, new HashMap<String, String>() {
            {
                put("题目类型", "qtid");
            }
        }, Question.class, formaterMap);
        System.out.println(listFromExcel);

    }

    /**
     * @param filepath 文件名称(文件的全路径也可以)
     * @param in       inputStream 流
     * @param map      第一行 和 class 类 字段 对应规则 为null 则 默认对应
     * @param clazz    对应的实体类的类 文件
     * @param formater 格式化。。参数类型是 Map<Object,Function<Object,Object>>
     * @return
     * @说明 暂时 仅支持 xls,xlsx 格式 的导入
     */
    public static List<Object> getListFromExcel(String filepath, InputStream in, Map<String, String> map,
                                                @SuppressWarnings("rawtypes") Class clazz, Map<String, Function<Object, Object>> formater) {

        List<Object> list = null;

        // 创建Excel工作薄
        Workbook work = getWorkBook(filepath, in);
        if (null == work) {
            throw new RuntimeException("创建Excel工作薄为空!");
        }
        Sheet sheet = null;
        Row row = null;

        // Cell cell = null;

        list = new ArrayList<>();
        // 遍历Excel中所有的sheet
        for (int i = 0; i < work.getNumberOfSheets(); i++) {
            sheet = work.getSheetAt(i);
            if (sheet == null) {
                continue;
            }
            Row firstRow = sheet.getRow(0);
            // 遍历当前sheet中的所有行,rowNum 从 0 开始。。。以 长度 - 1 结尾。。
            for (int j = sheet.getFirstRowNum(); j <= sheet.getLastRowNum(); j++) {
                row = sheet.getRow(j);
                // 如果 row 为空。。。或者它是 第一行。。。
                if (row == null || row.getRowNum() == 0) {
                    continue;
                }
                /*
                 * System.out.println(sheet.getFirstRowNum());
                 * System.out.println(sheet.getLastRowNum());
                 */
                try {
                    Object obj = null;
                    if (clazz != null) {
                        obj = clazz.newInstance();
                    } else {
                        throw new RuntimeException("clazz 不能为空");
                    }

                    // 遍历所有的列
                    // 从0 开始 。。。以长度 结尾。。。。也就是不用 <=....
                    for (int index = row.getFirstCellNum(); index < row.getLastCellNum(); index++) {
                        // 第一列 应该全部是字符串。。。
                        String field = (String) getCellValue(firstRow.getCell(index));
                        Object cellValue = getCellValue(row.getCell(index));
                        buildObj(field, cellValue, map, clazz, obj, formater);
                    }

                    list.add(obj);

                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                }
            }
        }
        try {
            if (in != null)
                in.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return list;
    }

    private static void buildObj(String fieldstr, Object value, Map<String, String> map,
                                 @SuppressWarnings("rawtypes") Class clazz, Object obj, Map<String, Function<Object, Object>> formatter)
            throws Exception {
        Field field = null;
        if (map != null) {
            fieldstr = map.get(fieldstr) == null ? fieldstr : map.get(fieldstr);
        }

        try {
            field = clazz.getDeclaredField(fieldstr);
        } catch (NoSuchFieldException e) {
            //出现此异常,直接return
            return;
        } catch (Exception e) {
            //出现其它类型异常。。抛出
            e.printStackTrace();
            throw e;
        }
        field.setAccessible(true);
        Function<Object, Object> func = null;
        if (formatter != null) {
            func = formatter.get(fieldstr);
        }
        if (func != null) {
            Object apply = func.apply(value);
            field.set(obj, apply);
        } else {
            field.set(obj, value);
        }
    }

    /**
     * 此方法 应为 私有方法。。
     *
     * @param path
     * @param input
     * @return
     */
    private static Workbook getWorkBook(String path, InputStream input) {
        Workbook workbook = null;
        // File file = new File(path);
        if (path.endsWith(".xls"))
            try {
                workbook = new HSSFWorkbook(input);
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        else if (path.endsWith(".xlsx")) {
            try {
                workbook = new XSSFWorkbook(input);
            } catch (Exception e) {
                // TODO: handle exception
            }
        } else {
            throw new RuntimeException("不支持的文档格式");
        }

        return workbook;
    }

    @SuppressWarnings("deprecation") // 将要过时的方法
    private static Object getCellValue(Cell cell) {
        Object value = null;
        DecimalFormat df = new DecimalFormat("0"); // 格式化number String字符
        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;
    }

}
原文地址:https://www.cnblogs.com/whm-blog/p/7373850.html