您的位置:首页 > 编程语言 > Java开发

Springboot中poi导入导出Excel的使用

2020-02-05 17:32 645 查看
  1. 标题
    日常开发中Excel文件的导入导出已经是很基本的需求,该文章用于记录在项目实战中使用poi的相关情况,用于后期巩固

  2. 实现
    1.Maven导入相关Jar包

    <dependency>
    <groupId>com.xtoneict</groupId>
    <artifactId>xtoneict-dcp-common</artifactId>
    <version>4.1.0</version>
    </dependency>

    2.工具类

    public class ExcelUtils {
    /**
    *  解析普通二维表单
    * @param in  文件输入流
    * @param fileName 文件名称
    * @param tableType  表单类型
    * @param tableId  表单ID
    * @param fieldNames 表头名称集合
    * @param types  表头字段所属类型
    * @return
    */
    public static  List<BaseTableInfo> getBankListByExcel(InputStream in, String fileName, TableType tableType,String tableId,
    Map<Integer,String> fieldNames,List<String> types){
    try {
    List<BaseTableInfo> list = new ArrayList<>();
    Sheet sheet = getSheet(in, fileName);
    Row row = null;
    Cell cell = null;
    BaseTableInfo baseTableInfo = null;
    //根据表单类型   获取表格起始行行号
    int firstRowNum = 0;
    // 根据表单类型  获取表格结束列号
    int lastCellNum = 0;
    switch (tableType){
    case T_RISK:
    firstRowNum = 3;
    lastCellNum = 13;
    break;
    case T_SECTOR:
    firstRowNum = 2;
    lastCellNum = 6;
    break;
    case T_DEBT:
    firstRowNum = 4;
    lastCellNum = 31;
    break;
    default:
    break;
    }
    //根据不同Excel表格 获取读取开始单元格
    for (int j = firstRowNum; j <= sheet.getLastRowNum(); j++) {
    //读取一行
    row = sheet.getRow(j);
    //去掉空行和表头
    if(row==null || row.getFirstCellNum()==j){continue;}
    baseTableInfo = getTableInfoEntity(tableType, tableId, baseTableInfo);
    boolean flag = false;
    //遍历所有的列
    for (int y = row.getFirstCellNum(); y < lastCellNum; y++) {
    cell = row.getCell(y);
    Object cellValue = getCellValue(cell);
    if(cellValue != null){
    flag = true;
    }
    cellValueType(cellValue,fieldNames.get(y),baseTableInfo,types.get(y));
    }
    if(!flag){continue;}
    list.add(baseTableInfo);
    }
    in.close();
    return list;
    } catch (StandardException e) {
    log.debug("export excel for {}",e.getMessage());
    throw new StandardException(e.getMessage());
    }catch (Exception e) {
    log.debug("export excel for {}",e.getMessage());
    throw new StandardException("表格类型不匹配,请选择正确的表格模板");
    }
    }
    
    /**
    * 根据当前类型获取 实体对象    用于反射生成对象
    * @param tableType
    * @param tableId
    * @param baseTableInfo
    * @return
    */
    private static BaseTableInfo getTableInfoEntity(TableType tableType, String tableId, BaseTableInfo baseTableInfo) {
    if(tableType.equals(TableType.T_RISK)){
    baseTableInfo = RiskInfoEntity.builder().id(UUIDUtils.newUUID().toString()).tableId(tableId).tableType(tableType).build();
    }
    if(tableType.equals(TableType.T_SECTOR)){
    baseTableInfo = SectorInfoEntity.builder().id(UUIDUtils.newUUID().toString()).tableId(tableId).tableType(tableType).build();
    }
    if(tableType.equals(TableType.T_DEBT)){
    baseTableInfo = DebtInfoEntity.builder().id(UUIDUtils.newUUID().toString()).tableId(tableId).tableType(tableType).build();
    }
    return baseTableInfo;
    }
    
    /**
    * 反射赋值给字段
    * @param cellValue  单元格值
    * @param fieldName  文件名称
    * @param baseTableInfo  反射对象实体类
    * @param type  字段类型
    */
    private static void cellValueType(Object cellValue, String fieldName, BaseTableInfo baseTableInfo,String type){
    if(cellValue != null){
    switch (type){
    case "String":
    cellValue = cellValue.toString();
    break;
    case "Integer":
    Double parseDouble = Double.parseDouble(cellValue.toString());
    cellValue = Integer.valueOf(parseDouble.intValue());
    break;
    case "Date":
    Date startTime = new GregorianCalendar(1900, 0, -1).getTime();
    Double dateDouble = Double.parseDouble(cellValue.toString());
    Date date = DateUtils.addDays(startTime,Integer.valueOf(dateDouble.intValue()));
    cellValue = date;
    break;
    case "BigDecimal":
    if("".equals(cellValue.toString())){
    cellValue = new BigDecimal("0");
    }else{
    BigDecimal bigDecimal = new BigDecimal(cellValue.toString());
    // 设置最多保留4位  四舍五入
    bigDecimal = bigDecimal.setScale(4,BigDecimal.ROUND_HALF_UP);
    cellValue = bigDecimal;
    }
    break;
    default:
    break;
    }
    try {
    Field declaredField = baseTableInfo.getClass().getDeclaredField(fieldName);
    declaredField.setAccessible(true);
    declaredField.set(baseTableInfo,cellValue);
    declaredField.setAccessible(false);
    }catch (Exception e){
    throw new StandardException("反射设置属性值出现错误");
    }
    }
    }
    
    /**
    * 解析一行表头两列数据   读取两行生成一个实体对象
    * @param in
    * @param fileName
    * @param tableId
    * @param moneyIndexs
    * @param moneyTypes
    * @param numIndexs
    * @param numTypes
    * @return
    * @throws Exception
    */
    public static  List<MoneyInfoEntity> getMoneyInfoByExcel(InputStream in, String fileName, String tableId,TableType tableType,
    Map<Integer, String> moneyIndexs, List<String> moneyTypes, Map<Integer, String> numIndexs, List<String> numTypes) {
    try {
    List<MoneyInfoEntity> list = new ArrayList<>();
    Sheet sheet = getSheet(in, fileName);
    int firstRowNum = 2;
    // 根据表单类型  获取表格结束列号
    int lastCellNum = 9;
    MoneyInfoEntity entity =  MoneyInfoEntity.builder().id(UUIDUtils.newUUID().toString()).tableId(tableId).tableType(tableType).build();
    for (int i = firstRowNum; i <= sheet.getLastRowNum(); i++) {
    Row row = sheet.getRow(i);
    if(i % 2 == 1){
    for (int j = row.getFirstCellNum(); j < lastCellNum; j++) {
    Cell cell = row.getCell(j);
    Object cellValue = getCellValue(cell);
    cellValueType(cellValue,moneyIndexs.get(j),entity,moneyTypes.get(j));
    }
    // 读取两行表格后 重新创建对象
    list.add(entity);
    entity = MoneyInfoEntity.builder().id(UUIDUtils.newUUID().toString()).tableId(tableId).tableType(tableType).build();
    }else{
    for (int j = row.getFirstCellNum(); j < lastCellNum; j++) {
    Cell cell = row.getCell(j);
    Object cellValue = getCellValue(cell);
    cellValueType(cellValue,numIndexs.get(j),entity,numTypes.get(j));
    }
    }
    }
    return  list;
    }catch (StandardException e) {
    log.debug("export excel for {}",e.getMessage());
    throw new StandardException(e.getMessage());
    }catch (Exception e) {
    log.debug("export excel for {}",e.getMessage());
    throw new StandardException("表格类型不匹配,请选择正确的表格模板");
    }
    }
    /**
    * 获取解析表格
    * @param in
    * @param fileName
    * @return
    * @throws Exception
    */
    private static Sheet getSheet(InputStream in, String fileName) throws IOException {
    //创建Excel工作薄
    Workbook work = WorkbookFactory.create(in);
    if (null == work) {
    throw new StandardException("创建Excel工作薄为空!");
    }
    if (work.getNumberOfSheets() > 1) {
    throw new StandardException("当前导入Excel中存在多个表格,请检查Excel文件");
    }
    Sheet sheet = work.getSheetAt(0);
    if (sheet == null) {
    throw new StandardException("请检查Excel文件是否存在表格");
    }
    return sheet;
    }
    
    /**
    * 解析复杂Excel表格   适用于每个单元格对应一个固定值
    * @param in
    * @param fileName
    * @param entities      数据库加载出来表格对应单元格值
    * @return
    * @throws Exception
    */
    public static Map<String, Object> getBankListByExcelAndOpeartion(InputStream in, String fileName,List<TableInfoEntity> entities){
    //创建Excel工作薄
    try {
    Sheet sheet = getSheet(in, fileName);
    Map<String, Object> tableData = new HashMap<>();
    for (TableInfoEntity entity : entities) {
    Row row = sheet.getRow(entity.getRowNum());
    if(row==null){continue;}
    Cell cell = row.getCell(entity.getColNum());
    Object cellValue = getOperationCellValue(cell);
    tableData.put("R"+entity.getRowNum().toString()+"L"+entity.getColNum().toString(),cellValue);
    }
    in.close();
    return tableData;
    } catch (StandardException e) {
    log.debug("export excel for {}",e.getMessage());
    throw new StandardException(e.getMessage());
    }catch (Exception e) {
    log.debug("export excel for {}",e.getMessage());
    throw new StandardException("表格类型不匹配,请选择正确的表格模板");
    }
    }
    /**
    * 解析复杂单元格
    * @param cell
    * @return
    */
    public static  Object getOperationCellValue(Cell cell){
    Object value = null;
    switch (cell.getCellType()) {
    case STRING:
    value = CustomUtils.stringTrim(cell.getRichStringCellValue().getString());
    break;
    case NUMERIC:
    String valueNum = String.valueOf(cell.getNumericCellValue());
    if("0".equals(valueNum)){
    value = 0;
    }else{
    BigDecimal bigDecimal = new BigDecimal(valueNum);
    bigDecimal = bigDecimal.setScale(4, BigDecimal.ROUND_HALF_UP);
    value = bigDecimal;
    }
    break;
    case BOOLEAN:
    value = cell.getBooleanCellValue();
    break;
    //如果单元格为空  返回"" map获取值避免报错
    case BLANK:
    value = "";
    break;
    default:
    break;
    }
    return value;
    }
    /**
    * 描述:对二维表表格中数值进行格式化
    */
    public static  Object getCellValue(Cell cell){
    Object value = null;
    switch (cell.getCellType()) {
    case STRING:
    // 去除单元格中的空格  字符串
    value = CustomUtils.stringTrim(cell.getRichStringCellValue().getString());
    if(StringUtils.isBlank(value.toString())){
    value = null;
    }
    break;
    case NUMERIC:
    //日期
    if("m/d/yyyy".equals(cell.getCellStyle().getDataFormatString())){
    value = cell.getDateCellValue();
    }else{
    //获取数字类型
    value = cell.getNumericCellValue();
    }
    break;
    case BOOLEAN:
    value = cell.getBooleanCellValue();
    break;
    //如果单元格为空  返回null
    case BLANK:
    value = null;
    break;
    default:
    break;
    }
    return value;
    }
    
    /**
    * 判断指定的单元格是否是合并单元格
    * @param sheet
    * @param row 行下标
    * @param column 列下标
    * @return
    */
    private static boolean isMergedRegion(Sheet sheet,int row ,int column) {
    int sheetMergeCount = sheet.getNumMergedRegions();
    for (int i = 0; i < sheetMergeCount; i++) {
    CellRangeAddress range = sheet.getMergedRegion(i);
    int firstColumn = range.getFirstColumn();
    int lastColumn = range.getLastColumn();
    int firstRow = range.getFirstRow();
    int lastRow = range.getLastRow();
    if(row >= firstRow && row <= lastRow){
    if(column >= firstColumn && column <= lastColumn){
    return true;
    }
    }
    }
    return false;
    }
    /**
    * 获取合并单元格的值
    * @param sheet 表格
    * @param row   行
    * @param column  列
    * @return
    */
    public static String getMergedRegionValue(Sheet sheet ,int row , int column){
    int sheetMergeCount = sheet.getNumMergedRegions();
    for(int i = 0 ; i < sheetMergeCount ; i++){
    CellRangeAddress ca = sheet.getMergedRegion(i);
    int firstColumn = ca.getFirstColumn();
    int lastColumn = ca.getLastColumn();
    int firstRow = ca.getFirstRow();
    int lastRow = ca.getLastRow();
    
    if(row >= firstRow && row <= lastRow){
    
    if(column >= firstColumn && column <= lastColumn){
    Row fRow = sheet.getRow(firstRow);
    Cell fCell = fRow.getCell(firstColumn);
    return getCellValue(fCell).toString() ;
    }
    }
    }
    return null ;
    }

}

  • 点赞
  • 收藏
  • 分享
  • 文章举报
wideShine 发布了10 篇原创文章 · 获赞 1 · 访问量 661 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: