导入Excel 工具类

1 篇文章 0 订阅

本人测试时软硬件环境:Eclipse、JDK1.8、SpringBoot 2.0.5.RELEASE、poi-ooxml.jar3.17

准备工作

第一步:在pom.xml中引入依赖

<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi-ooxml</artifactId>
	<version>3.17</version>
</dependency>

第二步:编写一个对应excel  sheet的通用模型ExcelSheetVO

import java.util.List;
 
public class ExcelSheetVO {
 
    /** 工作表表名(即:sheet的名称) */
    private String sheetName;
 
    /**
     * 该工作表数据集合
     * 说明:excel的每一个Cell对应为一个Object;
     *     那么一行即对应:List<Object>;
     *     那么一个sheet的内容即对应List<List<Object>>
     */
    private List<List<Object>> dataList;
 
    public List<List<Object>> getDataList() {
        return dataList;
    }
 
    public void setDataList(List<List<Object>> dataList) {
        this.dataList = dataList;
    }
 
    public String getSheetName() {
        return sheetName;
    }
 
    public void setSheetName(String sheetName) {
        this.sheetName = sheetName;
    }
 
	/*
	 * 说明:对集合.toString();相当于 对集合中的每一个元素进行toString(),然后以逗号拼接起来,首位再以[ ]括起来;
	 *   如: [我是一只小小小小鸟~, 2, 6]
	 */
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append("ExcelSheetVO {sheetName = '").append(sheetName).append("'");
		sb.append(", dataList = ").append(dataList).append("}");
		return sb.toString();
	}
    
}

编写Excel导入工具类

import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
 
/**
 * EXCEL导入工具类
 *
 * @author JustryDeng
 * @DATE 2018年9月24日 下午7:38:34
 */
public class ExcelImportUtil {
 
    /** EXCEL2003后缀名 */
    private final static String EXCEL_VERSION_2003_SUFFIX = "xls";
 
    /** EXCEL2007后缀名 */
    private final static String EXCEL_VERSION_2007_SUFFIX = "xlsx";
 
    /** 日期格式 */
    private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
 
    /**
     * excel读取
     *
     * @param excelFile
     *            xls或xlsx文件
     * @param rowCount
     *            要读取的总列数;为null或大于实际总行数时,则读取实际总行数
     * @param columnCount
     *            要读取的总列数;为null或大于实际列数时,则读取实际总行数
     * @return Sheet集合
     * @DATE 2018年9月24日 下午9:44:05
     */
    public static List<ExcelSheetVO> readExcel(File excelFile, Integer rowCount, Integer columnCount)
            throws IOException {
 
        // 获取文件的后缀名
        String fileName = excelFile.getName();
        String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
        System.out.println(" this file's suffix is ---> " + suffix);
 
        // 此集合用于存放多个sheet的数据
        List<ExcelSheetVO> sheetList = new ArrayList<>();
 
        // 根据不同的后缀名(不同版本的excel)创建不同的Workbook
        Workbook wb = null;
        try {
            if (EXCEL_VERSION_2003_SUFFIX.equals(suffix)) {
                wb = new HSSFWorkbook(new FileInputStream(excelFile));
            } else if (EXCEL_VERSION_2007_SUFFIX.equals(suffix)) {
                wb = new XSSFWorkbook(new FileInputStream(excelFile));
            } else {
                throw new IllegalArgumentException("Invalid excel version");
            }
 
 
            // 循环遍历每一个sheet
            for (int i = 0; i < wb.getNumberOfSheets(); i++) {
 
                Sheet sheet = wb.getSheetAt(i);
                ExcelSheetVO excelSheetVO = new ExcelSheetVO();
 
                excelSheetVO.setSheetName(sheet.getSheetName());
                List<List<Object>> dataList = new ArrayList<>(16);
                // 因为 引用的传递,所以我们可以先进行此操作
                excelSheetVO.setDataList(dataList);
                System.out.println(" first row num is ---> " + sheet.getFirstRowNum());
                System.out.println(" a total of ---> " + sheet.getPhysicalNumberOfRows());
                int readRowCount;
                // 要读取的总行数设置
                if (rowCount == null || rowCount > sheet.getPhysicalNumberOfRows()) {
                    // 总行数
                    readRowCount = sheet.getPhysicalNumberOfRows();
                } else {
                    readRowCount = rowCount;
                }
 
                // 已经读取了的行数,标识
                int alreadyReadRowTotal = 0;
                // 循环遍历sheet的每一行
                // rowNum与index类似,从0开始(即: 0 对应第一行)
                for (int j = sheet.getFirstRowNum(); alreadyReadRowTotal < readRowCount; j++) {
                    Row row = sheet.getRow(j);
                    if (row == null) {
                        System.out.println(" row = null ---> " + j);
                        continue;
                    }
                    if (row.getFirstCellNum() < 0) {
                        System.out.println(" the row doesn't exist cell --> " + j);
                        continue;
                    }
                    int readColumnCount;
                    // 该行要读取的总列数设置
                    if (columnCount == null || columnCount > row.getLastCellNum()) {
                        readColumnCount = (int) row.getLastCellNum();
                    } else {
                        readColumnCount = columnCount;
                    }
                    List<Object> rowValue = new ArrayList<>();
                    // 解析sheet 的列
                    for (int k = 0; k < readColumnCount; k++) {
                        Cell cell = row.getCell(k);
                        rowValue.add(getCellValue(cell));
                    }
                    dataList.add(rowValue);
                    alreadyReadRowTotal++;
                }
                sheetList.add(excelSheetVO);
            }
        } finally {
            if(wb != null) {
                wb.close();
            }
        }
        return sheetList;
    }
 
    /**
     * 获取单元格内的值
     *
     * @param cell
     *            单元格
     * @return 该单元格内的内容
     * @DATE 2018年9月24日 下午8:06:53
     */
    private static Object getCellValue(Cell cell) {
        Object value = null;
        if (cell != null) {
            // 获取单元格类型
            CellType ct = cell.getCellTypeEnum();
            // 枚举的比较 使用 == 或 equals 都是一样的(枚举重写了equals方法,该方法内部其实也是用的==进行比较的)
            if (ct == CellType.STRING) {
                value = cell.getStringCellValue();
            } else if (ct == CellType.NUMERIC) {
                // 日期格式会被认为是数字(因为日期在导入时,会转化为1900年到该日期的天数)
                // 这里我们先要判断是否为日期
                if(HSSFDateUtil.isCellDateFormatted(cell)) {
                    value = simpleDateFormat.format(cell.getDateCellValue());
                    return value;
                }
                /*
                 * 如果是数字类型的;那么我们将其类型设置为String,再取值
                 *
                 *  但是注意:这样取值的话,如果是小数,如1.228,那么 获得的却是 1.2228000000000001
                 *         我们在实际使用这个1.2228000000000001这个String值时,可以
                 *         Double.valueOf((String)value)一下,这样就能获取到准确地1.228这个值了
                 *     注意:如果该cell的值本来就是1.2228000000000001,那么进过上述步骤获得的仍然是1.228
                 *         所以此步骤仍然是有漏洞的;
                 */
                cell.setCellType(CellType.STRING);
                value = cell.getStringCellValue();
 
                /* 当然也可以直接取数字类型的值;但是这样取值的话,如果cell的值是小数,还行;
                 *    如果是整数的话,那么取出来的值会多一个.0    如:24取出来就变成了24.0
                 *    我们也可以使用java.text.DecimalFormat对十进制数据进行格式化
                 */
                // value = cell.getNumericCellValue();
            } else if (ct == CellType.BOOLEAN) {
                value = cell.getBooleanCellValue();
            } else if (ct == CellType.BLANK) {
                // 如果Cell中无内容,则设置其值为null;
                value = null;
            } else {
                value = cell.toString();
            }
        }
        return value;
    }
    
}

测试一下

现有excel文件test.xlsx:

注:我没在Sheet2、Sheet3中写任何数据。

简单写一个测试代码:

上述代码在控制台中输出的内容为:

https://blog.csdn.net/justry_deng/article/details/82833508

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值