POI处理Excel数据(2021-09-06)

一、POI读Excel数据

读取内容表

导入两个依赖:

        <!--   xls文件     -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.1.2</version>
        </dependency>
        <!--   xls文件     -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>

需要根据表格里面的对象建立实体类ExcelDataVO,并生成get和set方法。

public class ExcelDataVO {
    private String name;//姓名
    private Integer age;//年龄
    private String location;//居住城市
    private String job;//职业
}

知识点:打印日志

    //打印日志
    private static Logger logger = Logger.getLogger(ExcelReader.class.getName());
    //两种文件名
    private static final String XLS = "xls";
    private static final String XLSX = "xlsx";

根据文件后缀名类型获取对应的工作簿对象:getWorkBook

    /**
     * 根据文件后缀名类型获取对应的工作簿对象
     * @param inputStream 读取文件的输入流
     * @param fileType 文件后缀名类型(xls或xlsx)
     * @return 包含文件数据的工作簿对象
     * @throws IOException
     */
    public static Workbook getWorkBook(InputStream inputStream, String fileType) throws IOException {
        Workbook workbook = null;
        if (fileType.equalsIgnoreCase(XLS)){
            workbook = new HSSFWorkbook(inputStream);
        }else if(fileType.equalsIgnoreCase(XLSX)){
            workbook = new XSSFWorkbook(inputStream);
        }
        return workbook;
    }

将单元格内容转换为字符串: convertCellValueToString
CellType getCellType();

public enum CellType {
    @Internal(
        since = "POI 3.15 beta 3"
    )
    _NONE(-1),
    NUMERIC(0),//数值
    STRING(1),//字符串
    FORMULA(2),//公式
    BLANK(3),//空值
    BOOLEAN(4),//布尔值
    ERROR(5);//错误
}
.getCellType()的几种类型值

将单元格内容转换为字符串

/**
     * 将单元格内容转换为字符串
     * @param cell
     * @return
     */
    private static String convertCellValueToString(Cell cell){
        if (cell == null){
            return null;
        }
        String returnValue = null;
        switch (cell.getCellType()){
            case NUMERIC://数值型 0
            //case CELL_TYPE_NUMERIC://数值型 0
                Double doubleValue = cell.getNumericCellValue();
                // 格式化科学计数法,取一位整数
                DecimalFormat df = new DecimalFormat("0");
                returnValue = df.format(doubleValue);
                break;
            case STRING://字符串型 1
            //case CELL_TYPE_STRING://字符串型 1
                returnValue = cell.getStringCellValue();
                break;
            case FORMULA://公式型 2
            //case CELL_TYPE_FORMULA://公式型 2
                returnValue = cell.getCellFormula();
                break;
            case BLANK://空值 3
            //case CELL_TYPE_BLANK://空值 3
                break;
            case BOOLEAN://布尔型 4
            //case CELL_TYPE_BOOLEAN://布尔型 4
                Boolean booleanValue = cell.getBooleanCellValue();
                returnValue = booleanValue.toString();
                break;
            case ERROR://错误 5
            //case CELL_TYPE_ERROR://错误 5
                break;
            default:
                break;
        }
        return returnValue;
    }

Java中 DecimalFormat 用法详解:https://www.cnblogs.com/Small-sunshine/p/11648652.html


提取每一行中需要的数据,构造成为一个结果数据对象: convertRowToData

/**
     * 提取每一行中需要的数据,构造成为一个结果数据对象
     * 当该行中有单元格的数据为空或不合法时,忽略该行的数据
     * @param row 行数据
     * @return 解析后的行数据对象,行数据错误时返回null
     */
    private static ExcelDataVO convertRowToData(Row row){
        ExcelDataVO resultData = new ExcelDataVO();
        Cell cell;
        int cellNum = 0;
        //获取姓名
        cell = row.getCell(cellNum++);
        String name = convertCellValueToString(cell);
        resultData.setName(name);

        //获取年龄
        cell = row.getCell(cellNum++);
        String ageStr = convertCellValueToString(cell);
        if (null == ageStr || "".equals(ageStr)){
            //年龄为空
            resultData.setAge(null);
        }else {
            resultData.setAge(Integer.parseInt(ageStr));
        }

        //获取居住地
        cell = row.getCell(cellNum++);
        String location = convertCellValueToString(cell);
        resultData.setLocation(location);
        //获取职业
        cell = row.getCell(cellNum++);
        String job = convertCellValueToString(cell);
        resultData.setJob(job);

        return resultData;
    }

解析Excel数据:parseExcel

/**
     * 解析Excel数据
     * @param workbook Excel工作簿对象
     * @return 解析结果
     */
    private static List<ExcelDataVO> parseExcel(Workbook workbook){
        List<ExcelDataVO> resultDataList = new ArrayList<>();
        //解析sheet,parse从语法上分析
        for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {
            Sheet sheet = workbook.getSheetAt(sheetNum);

            // 校验sheet是否合法
            if (sheet == null){
                continue;
            }

            // 获取第一行数据
            int firstRowNum = sheet.getFirstRowNum();
            System.out.println("test:firstRowNum:  "+firstRowNum);
            Row firstRow = sheet.getRow(firstRowNum);
            System.out.println(firstRow);
            if (null == firstRow){
                logger.warning("解析Excel失败,在第一行没有读取到任何数据!");
            }
            //解析第一行数据


            // 解析每一行的数据,构造数据对象
            //getPhysicalNumberOfRows()获取的是物理行数,也就是不包括那些空行(隔行)的情况。
            //getLastRowNum()获取的是最后一行的编号(编号从0开始)。
            int rowStart = firstRowNum + 1;
            int rowEnd = sheet.getPhysicalNumberOfRows();
            for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) {
                Row row = sheet.getRow(rowNum);
                if(null == row){
                    continue;
                }

                ExcelDataVO resultData = convertRowToData(row);
                if (null == resultData){
                    logger.warning("第 " + row.getRowNum() + "行数据不合法,已忽略!");
                    continue;
                }
                resultDataList.add(resultData);
            }
        }
        return resultDataList;
    }

读取Excel文件内容readExcel

/**
     * 读取Excel文件内容
     * @param fileName 要读取的Excel文件所在路径
     * @return 读取结果列表,读取失败时返回null
     */
    public static List<ExcelDataVO> readExcel(String fileName){
        Workbook workbook = null;
        FileInputStream inputStream = null;
        try {
            // 获取Excel后缀名
            String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
            // 获取Excel文件
            File excelFile = new File(fileName);
            if (!excelFile.exists()){
                logger.warning("指定的Excel文件不存在!");
                return null;
            }
            // 获取Excel工作簿
            inputStream = new FileInputStream(excelFile);
            workbook = getWorkBook(inputStream, fileType);

            // 读取excel中的数据
            List<ExcelDataVO> resultDataList = parseExcel(workbook);
            return resultDataList;

        } catch (Exception e) {
            logger.warning("解析Excel失败,文件名:" + fileName + " 错误信息:" + e.getMessage());
            return null;
        } finally {
            try {
                if (null != workbook){
                    workbook.close();
                }
                if (null != inputStream){
                    inputStream.close();
                }
            } catch (Exception e) {
                logger.warning("关闭数据流出错!错误信息:" + e.getMessage());
                return null;
            }
        }

    }

We are family

  • 德意 2020.09.08

有你的每一天,都非常的充实,每一天都充满着期待,我们分享彼此的故事,彼此云学习、云上班、云看夕阳落下……是那么的舒适愉悦

  • Excel文档结构:一个Excel文档包含了多个数据表;一个数据表包含了多个行,一行中有多个单元格,我们将数据写入到单元格中。
/**
 * 1、创建一个Excel表格
 */
public static void creatExcel() throws IOException {
     //生成文档对象
     HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
     //指定文档写出的路径
     File file = new File("E://java//sany//poi//poiExcel.xls");
     //写出对象到指定的路径
     hssfWorkbook.write(file);
}
private static void writeExcelData() throws IOException {
        HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
        HSSFSheet sheet = hssfWorkbook.createSheet("学生成绩表");
        //写表头
        HSSFRow row = sheet.createRow(0);
        for (int i = 0; i < header.length; i++) {
            HSSFCell cell = row.createCell(i);
            cell.setCellValue(header[i]);
        }
        //写表中数据+data.length+"||"+data[0].length
        for (int i = 0; i < data.length; i++) {
            HSSFRow row1 = sheet.createRow(i+1);
            for (int j = 0; j < data[0].length; j++) {
                /**
                 * 进行处理,data第一个数据为字符串,后面的均为数字
                 */
                if (j == 0){
                    HSSFCell cell1 = row1.createCell(j);
                    cell1.setCellValue(data[i][j]);
                }else {
                    HSSFCell cell1 = row1.createCell(j);
//                    cell1.setCellValue(Integer.valueOf(data[i][j]));
//                    Integer.parseInt(data[i][j]);
                    cell1.setCellValue(Double.parseDouble(data[i][j]));
                }
            }
        }
        File file = new File("E://java//sany//poi//poiExcel.xls");
        hssfWorkbook.write(file);
        hssfWorkbook.close();

    }


夏雨雪时光

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355

推荐阅读更多精彩内容