java操作excel之poi读取excel

1.介绍

Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。

2.依赖

首先引入maven依赖:

<dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.14</version>
        </dependency>


3.工具类ExcelUtils

package com.tl.util.core.helper;

import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Excel工具类
 * <p/>
 */
public class ExcelUtils {

    /**
     * EXCEL第一行索引
     */
    public static final int EXCEL_FIRST_ROW_INDEX = 0;

    public static final String TRUE_VALUE = "Y";

    public static final String FALSE_VALUE = "N";


    /**
     * 获取单元格字符串内容
     *
     * @param cell
     * @return
     */
    private static String getCellValue(HSSFCell cell) {
        String value = "";
        // 注意:一定要设成这个,否则可能会出现乱码
        //cell.setEncoding(HSSFCell.ENCODING_UTF_16);

        switch (cell.getCellType()) {
            case HSSFCell.CELL_TYPE_STRING:
                value = cell.getStringCellValue();
                break;
            case HSSFCell.CELL_TYPE_NUMERIC:
                if (HSSFDateUtil.isCellDateFormatted(cell)) {
                    Date date = cell.getDateCellValue();
                    if (date != null) {
                        value = new SimpleDateFormat("yyyy-MM-dd").format(date);
                    } else {
                        value = "";
                    }
                } else {
                    long longVal = Math.round(cell.getNumericCellValue());
                    if (Double.parseDouble(longVal + ".0") == cell.getNumericCellValue())
                        value = String.valueOf(longVal);
                    else
                        value = String.valueOf(cell.getNumericCellValue());
                    //value =cell.getStringCellValue();
                }
                break;
            case HSSFCell.CELL_TYPE_FORMULA:
                // 导入时如果为公式生成的数据则无值
                if (!cell.getCellFormula().equals("")) {
                    try {
                        value = String.valueOf(cell.getNumericCellValue());
                    } catch (Exception ex) {
                        value = cell.getStringCellValue();
                    }
                } else {
                    value = cell.getStringCellValue() + "";
                }
                break;
            case HSSFCell.CELL_TYPE_BLANK:
                break;
            case HSSFCell.CELL_TYPE_ERROR:
                value = "";
                break;
            case HSSFCell.CELL_TYPE_BOOLEAN:
                value = (cell.getBooleanCellValue() ? TRUE_VALUE : FALSE_VALUE);
                break;
            default:
                value = "";
        }

        return value;
    }


    /**
     * 去掉字符串右边的空格
     *
     * @param str 要处理的字符串
     * @return 处理后的字符串
     */
    private static String rightTrim(String str) {
        if (str == null) {
            return "";
        }
        int length = str.length();
        for (int i = length - 1; i >= 0; i--) {
            if (str.charAt(i) != 0x20) {
                break;
            }
            length--;
        }
        return str.substring(0, length);
    }

    /**
     * 读取Excel的内容,第一维数组存储的是一行中格列的值,二维数组存储的是多少个行
     *
     * @param inputStream 读取数据的源Excel
     * @param headerIndex 表单头所在的索引
     * @return 读出的Excel中数据的内容
     * @throws IOException
     */
    public static List<Map<String, String>> parse(InputStream inputStream, int headerIndex) throws IOException {
        List<Map<String, String>> result = new ArrayList<Map<String, String>>();
        int maxcolumnIndex = 0;
        POIFSFileSystem fs = new POIFSFileSystem(inputStream);
        HSSFWorkbook wb = new HSSFWorkbook(fs);
        HSSFCell cell = null;
        for (int sheetIndex = 0; sheetIndex < wb.getNumberOfSheets(); sheetIndex++) {
            HSSFSheet st = wb.getSheetAt(sheetIndex);
            List<String> headers = new ArrayList<String>();
            for (int rowIndex = 0; rowIndex <= st.getLastRowNum(); rowIndex++) {
                HSSFRow row = st.getRow(rowIndex);
                if (row == null) {
                    continue;
                }
                int currentcolumnIndex = row.getLastCellNum() + 1;
                if (currentcolumnIndex > maxcolumnIndex) {
                    maxcolumnIndex = currentcolumnIndex;
                }
                Map<String, String> rows = new LinkedHashMap<String, String>();

                for (int columnIndex = 0; columnIndex <= row.getLastCellNum(); columnIndex++) {
                    String value = "";
                    cell = row.getCell(columnIndex);
                    if (cell != null) {
                        value = getCellValue(cell);
                    }
                    if (rowIndex == headerIndex && value != null && !value.trim().equals("")) {
                        headers.add(value.trim());
                    } else {
                        if (columnIndex < headers.size()) {
                            rows.put(headers.get(columnIndex), value);
                        }
                    }
                }
                
                if (!isEmptyMap(rows)) {
                    result.add(rows);
                }
            }
        }
        return result;
    }


    private static boolean isEmptyMap(Map map) {
        boolean empty = map.isEmpty();
        if (!empty) {
            Collection values = map.values();
            for (Object value : values) {
                if (value != null && !value.toString().equals("")) {
                    return false;
                }
            }
            return true;
        }
        return empty;
    }
}

注意事项:
HSSFWorkbook:是操作Excel2003以前(包括2003)的版本,扩展名是.xls
XSSFWorkbook:是操作Excel2007的版本,扩展名是.xlsx
所以上面的代码仅支持excel2003,因为excel具有向下兼容的特性,同时也可以将07版的转为03版。

4.测试

 /**
     * 员工excel数据读取并导入staff表中
     *
     * @param request
     * @param stream
     * @param consumer
     * @return
     */
    @Override
    public ImportExcelResult importStaff(ImportStaffRequest request, InputStream stream, Consumer<ImportExcelResult> consumer) {
        ImportExcelResult result = new ImportExcelResult();
        List<Map<String, String>> data = null;

        try {
            data = ExcelUtils.parse(stream, ExcelUtils.EXCEL_FIRST_ROW_INDEX);
        } catch (Exception ex) {
            result.addFail("读取excel文件失败:" + ex.getMessage());
            consumer.accept(result);
            throw new ImportFailedException("读取excel文件失败:" + ex.getMessage());
        }
        if (data == null) {
            result.addFail("读取excel失败,或excel为空\"");
            consumer.accept(result);
            throw new ImportFailedException("读取excel失败,或excel为空");
        }

        result.setRowQuantity(data.size());
        for (Map<String, String> row : data) {
            String departmentName = row.get("部门名称");
            String code = row.get("人员编号");
            String name = row.get("人员姓名");
            String positionName = row.get("人员职位");
            String certificate = row.get("身份证号码");
            String sex = row.get("性别");
            String education = row.get("学历");
            String hiredate = row.get("入职年月");
            int age = Integer.valueOf(row.get("年龄"));
            String domicile = row.get("户籍");
            String address = row.get("现居地址");
            String mobile = row.get("手机号");

            Position position = positionRepository.findOneByName(positionName);
            if (position == null) {
                result.addFail("职位名称信息缺失:" + positionName);
                consumer.accept(result);
                continue;
            }
            Department department = departmentRepository.findOneByName(departmentName);
            if (position == null) {
                result.addFail("部门名称信息缺失:" + positionName);
                consumer.accept(result);
                continue;
            }

            Staff staff = findByCode(code);
            if (staff == null) {
                staff = new Staff();
            }

            if (Strings.isNotBlank(hiredate)) {
                Date date = strToDate(hiredate);
                staff.setHiredate(date);
            }

            staff.setCode(code);
            staff.setDepartment(department.getId());
            staff.setPosition(position.getId());
            staff.setRealname(name);
            staff.setCertificate(certificate);
            staff.setSex(Staff.Sex.fromDescription(sex));
            staff.setEducation(Staff.Education.fromDescription(education));
            staff.setDomicile(domicile);
            staff.setAge(age);
            staff.setAddress(address);
            staff.setMobile(mobile);
            staff.setUser(request.getUser());

            store(staff);
            result.addSuccess();
            consumer.accept(result);
        }
        return result;
    }

需要注意的是在读取list结果集的时候,获取某一列的数据的时候,一定要跟excel的列头字段保持一致,否则将读不到数据!



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值