Java poi导入 excel文件

文章介绍了如何使用ApachePOI库在Java中读取Excel文件,包括添加Maven依赖、处理不同类型的Excel文件(.xls和.xlsx)、抽象类的设计以及数据操作的方法。示例代码展示了从Excel文件中提取数据并映射到自定义实体类的过程。
摘要由CSDN通过智能技术生成

Java 导入 excel文件

这个根据我这边的业务有一些参数是定值;可以参考一下大概逻辑吧

maven 导包
<dependency>
   <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.1.2</version>
</dependency>
导包
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.math.RoundingMode;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.FileMagic;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
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 com.google.common.collect.Lists;
抽象类
public abstract class ExcelAbstract<T> {

	public abstract Class<T> getGenericClazz();
	
	/**
	 * 操作数据
	 * @param t 实体类
	 * @param o 冗余参数
	 * @return
	 */
	public abstract void checkData(T t, Object o);
	
	/**
	 * 表头
	 * key 表头, value 实体类字段
	 * @return
	 */
	public abstract Map<String, String> getTitle();
	
	/**
	 * 
	 * @param is 文件输入流
	 * @param isCheck 是否 操作数据
	 * @return
	 * @throws Exception
	 */
	public List<T> read(InputStream is, boolean isCheck, Object o) throws Exception {
		
		InputStream stream = FileMagic.prepareToCheckMagic(is);
		FileMagic fm = FileMagic.valueOf(stream);
		switch (fm) {
			case OLE2:
				return readXls(stream, isCheck, o);
			case OOXML:
				return readXlsx(stream, isCheck, o);
			default:
				throw new IOException("excel文件格式错误!");
		}
	}
	
	private List<T> readXls(InputStream stream, boolean isCheck, Object o) throws Exception {
		try (Workbook wk = new HSSFWorkbook(stream)) {
			return getDataList(wk, isCheck, o);
		}
	}
	
	private List<T> readXlsx(InputStream stream, boolean isCheck, Object o) throws Exception {
		try (Workbook wk = new XSSFWorkbook(stream)) {
			return getDataList(wk, isCheck, o);
		}
	}
	
	private List<T> getDataList(Workbook wk, boolean isCheck, Object o) throws Exception {
		List<T> list = Lists.newArrayList();
		Map<String, String> titleMaps = getTitle();
		Class<T> clazz= getGenericClazz();
		
		// 只解析第一页的数据
		Sheet sheet = wk.getSheetAt(0);
		// 第一行是标题
		Row titles = sheet.getRow(0);
		Map<Integer, String> titMap = new HashMap<>();
		Iterator<Cell> tit = titles.cellIterator();
		while (tit.hasNext()) {
			Cell cell = tit.next();
			String s = String.valueOf(getCellValue(sheet, cell));
			if (StringUtils.isNotBlank(s) && StringUtils.isNotBlank(titleMaps.get(s))) {
				titMap.put(cell.getColumnIndex(), titleMaps.get(s));
			}
		}
		
		Iterator<Row> rit = sheet.rowIterator();
		while (rit.hasNext()) {
			Row row = rit.next();
			if (row.getRowNum() == 0) {
				// 表头跳过
				continue;
			}
			Iterator<Cell> cit = row.cellIterator();
			T t = clazz.newInstance();
			while (cit.hasNext()) {
				Cell cell = cit.next();
				setValue(t, titMap.get(cell.getColumnIndex()), String.valueOf(getCellValue(sheet, cell)));
			}

            if (isCheck) {
            	checkData(t, o);
            }
			list.add(t);
		}
		return list;
	}
	
	private static Object getCellValue(Sheet sheet, Cell cell) {
        Object cellValue = "";
        // 以下是判断数据的类型
        switch (cell.getCellType()) {
            case NUMERIC: // 数字
                if (DateUtil.isCellDateFormatted(cell)) {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    cellValue = sdf.format(DateUtil.getJavaDate(cell.getNumericCellValue()));
                } else {
                    //解决当读取的单元格的内容,被自动加上".0"后缀
                    cell.setCellType(CellType.STRING); //若读取的单元格的值没有".0",则可吧把cell类型转为String,则惠去掉".0"
                    cellValue = cell.getStringCellValue();
                }
                break;
            case STRING: // 字符串
                cellValue = cell.getStringCellValue();
                break;
            case BOOLEAN: // Boolean
                cellValue = cell.getBooleanCellValue();
                break;
            case FORMULA: // 公式
                cellValue = getExcelForFORMULAEva(sheet,cell);
                break;
            case BLANK: // 空值
                break;
            case ERROR: // 故障
                break;
            default:
                break;
        }
        return cellValue;
    }
	
	private static Object getExcelForFORMULAEva(Sheet sheet,Cell cell) {
        Object cellValue = "";
        FormulaEvaluator evaluator = sheet.getWorkbook().getCreationHelper().createFormulaEvaluator();
        cell = evaluator.evaluateInCell(cell);   //计算结果的类型替换单元格的类型
        cellValue = getCellValue(sheet, cell);
        return cellValue;
    }

	private void setValue(T t, String name, String value) throws Exception {
		Method[] m = t.getClass().getMethods();
    	Class<?> typeCal = null;
        for (int i = 0; i < m.length; i++) {
        	if (("get" + name).toLowerCase().equals(m[i].getName().toLowerCase())) {
        		typeCal = m[i].getReturnType();
        		break;
        	}
        }
    	for (int i = 0; i < m.length; i++) {
            if (("set" + name).toLowerCase().equals(m[i].getName().toLowerCase())) {
            	Object v = typeConversion(value, typeCal);
                m[i].invoke(t, v);
                break;
            }
        }
    }
	
	private static Object typeConversion(String value, Class<?> typeCalzz) throws Exception {
		Object v = value; 
    	if (Date.class.equals(typeCalzz)) {
    		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    		v = sdf.parse(value);
    	}
    	if (Integer.class.equals(typeCalzz)) {
    		v = Integer.valueOf(value);
    	}
    	if (Long.class.equals(typeCalzz)) {
    		v = Long.valueOf(value);
    	}
    	if (Float.class.equals(typeCalzz)) {
    		v = Float.valueOf(value);
    	}
    	if (Double.class.equals(typeCalzz)) {
    		v = Double.valueOf(value);
    	}
    	if (Boolean.class.equals(typeCalzz)) {
    		v = Boolean.valueOf(value);
    	}
    	if (Short.class.equals(typeCalzz)) {
    		v = Short.valueOf(value);
    	}
    	return v;
	}
}
测试
测试实体
@Data
public class TestEntity {
	private String uuid;
	private Integer num;
	private Long num1;
	private Boolean bool;
	private Date time;
}
测试文件

在这里插入图片描述

测试实现类
public class TestImpl extends ExcelAbstract<TestEntity> {

	@Override
	public Class<TestEntity> getGenericClazz() {
		return TestEntity.class;
	}

	@Override
	public void checkData(TestEntity entity, Object o) {
		System.out.println("数据");
		System.out.println(entity);
	}

	@Override
	public Map<String, String> getTitle() {
		Map<String, String> titles = new LinkedHashMap<>();
		titles.put("测试String", "uuid");
		titles.put("测试int", "num");
		titles.put("测试long", "num1");
		titles.put("测试boolean", "bool");
		titles.put("测试Date", "time");
		return titles;
	}

	public static void main(String[] args) {
		TestImpl impl = new TestImpl();
//		File f = new File("C:\\Users\\YHSJ\\Desktop\\新建 XLSX 工作表.xlsx");
		File f = new File("C:\\Users\\YHSJ\\Desktop\\新建 XLS 工作表.xls");
		try (InputStream is = new FileInputStream(f)) {
			List<TestEntity> l = impl.read(is, true, null);
			System.out.println("数据列表");
			System.out.println(l);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值