基于Apache poi hssf对xls(excel)文件进行解析

2024-05-10 00:48

本文主要是介绍基于Apache poi hssf对xls(excel)文件进行解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在美团实习的过程中,马上要做的功能有一项是前台上传文件后台获取文件对excel文件进行解析。之前做过后台从DB获取数据按照模板将查询的数据填入xls并返回给前台提供下载的功能,最后会给出一个工具类,里面包含这个功能的实现。

实现对excel文件的读写,比较主流的做法是使用Apache POI提供的各种类和方法,对Apache POI的理解可以参照这篇文章:POI基础

在对POI有足够的认识和理解后,可以预想对前台上传的文件进行解析,实际上就是在服务器端打开该文件,遍历里面的数据,将Excel里面存储的数据按照合适的对应关系存入正确的data object的field。接下来想做什么都可以了,不管是存储数据到DB或者进行相应的计算的都可以。感觉其实excel文件的结构通过POI提供的类来组织的话还比较简单,宏观的看其实一个Excel文件就是一个HSSFWorkbook类的实例,文件里的多个sheet各自对应HSSFSheet实例,每个sheet里面的一行行记录对应HSSFRow,一个个单元格就是一个个HSSFCell。

那么下面我将自己认为最主要的代码实现,在网上看到的,我做了一些修改。粘贴如下:

解析excel文件核心代码
public  class  PoiExcelParser { 
     private  Sheet sheet;     //表格类实例 
     LinkedList[] result;     //保存每个单元格的数据 ,是容器就好,看需求吧 
   
     //读取excel文件,创建表格实例 
     private  void  loadExcel(String filePath) { 
         FileInputStream inStream =  null
         try 
             inStream =  new  FileInputStream( new  File(filePath)); 
             Workbook workBook = WorkbookFactory.create(inStream); 
             sheet = workBook.getSheetAt( 0 );      //注意sheet以0开始计数          
         catch  (Exception e) { 
             e.printStackTrace(); 
         } finally
             try 
                 if (inStream!= null ){ 
                     inStream.close();    //关闭stream
                 }                 
             catch  (IOException e) {                 
                 e.printStackTrace(); 
            
        
    
     //获取某个单元格的值,统一以字符串形式返回 
     private  String getCellValue(Cell cell) { 
         String cellValue =  ""
         DataFormatter formatter =  new  DataFormatter(); 
         if  (cell !=  null ) { 
             //判断单元格数据的类型,不同类型调用不同的方法 
             switch  (cell.getCellType()) { 
                 //数值类型 
                 case  Cell.CELL_TYPE_NUMERIC: 
                     //进一步判断 ,单元格格式是日期格式  
                     if  (DateUtil.isCellDateFormatted(cell)) { 
                         cellValue = formatter.formatCellValue(cell); 
                     else 
                         //数值 
                         double  value = cell.getNumericCellValue(); 
                         int  intValue = ( int ) value; 
                         cellValue = value - intValue ==  0  ? String.valueOf(intValue) : String.valueOf(value); 
                    
                     break
                 case  Cell.CELL_TYPE_STRING: 
                     cellValue = cell.getStringCellValue(); 
                     break
                 case  Cell.CELL_TYPE_BOOLEAN: 
                     cellValue = String.valueOf(cell.getBooleanCellValue()); 
                     break
                     //判断单元格是公式格式,需要做一种特殊处理来得到相应的值 
                 case  Cell.CELL_TYPE_FORMULA: 
                     try
                         cellValue = String.valueOf(cell.getNumericCellValue()); 
                     } catch (IllegalStateException e){ 
                         cellValue = String.valueOf(cell.getRichStringCellValue()); 
                    
                     break
                 case  Cell.CELL_TYPE_BLANK: 
                     cellValue =  ""
                     break
                 case  Cell.CELL_TYPE_ERROR: 
                     cellValue =  ""
                     break
                 default
                     cellValue = cell.toString().trim(); 
                     break
            
        
         return  cellValue.trim(); 
    
   
   
   
     //初始化表格中的每一行,并得到每一个单元格的值 
     public  void  getData(){ 
         int  rowNum = sheet.getLastRowNum() +  1 ;
         result =  new  LinkedList[rowNum]; 
         for ( int  i= 0 ;i<rowNum;i++){ 
             Row row = sheet.getRow(i); 
             //每有新的一行,创建一个新的LinkedList对象 
             result[i] =  new  LinkedList(); 
             for ( int  j= 0 ;j<row.getLastCellNum();j++){ 
                 Cell cell = row.getCell(j); 
                 //获取单元格的值 
                 String str = getCellValue(cell); 
                 //将得到的值放入链表中,实际的使用过程中,也可以保存在dataobject里 
                 result[i].add(str); 
            
        
     }     

这段代码在实际工程中使用需谨慎,确保可用性,可能会做出相应的修改以适应工程的实际需要。

Update:

1.发现一个问题,就是作为解析前台上传的文件,控制用户上传的文件格式有一定难度,而前面用hssf实现的功能只对xls格式支持,如果万一用户上传的是xlsx就有问题。。。而这个问题,在很久之前就被很好的利用多态解决了,帖子链接如下:通过POI统一读取Excel文件(兼容97-2003和2007+两种格式)


 

这篇关于基于Apache poi hssf对xls(excel)文件进行解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/974963

相关文章

PostgreSQL的扩展dict_int应用案例解析

《PostgreSQL的扩展dict_int应用案例解析》dict_int扩展为PostgreSQL提供了专业的整数文本处理能力,特别适合需要精确处理数字内容的搜索场景,本文给大家介绍PostgreS... 目录PostgreSQL的扩展dict_int一、扩展概述二、核心功能三、安装与启用四、字典配置方法

深度解析Java DTO(最新推荐)

《深度解析JavaDTO(最新推荐)》DTO(DataTransferObject)是一种用于在不同层(如Controller层、Service层)之间传输数据的对象设计模式,其核心目的是封装数据,... 目录一、什么是DTO?DTO的核心特点:二、为什么需要DTO?(对比Entity)三、实际应用场景解析

深度解析Java项目中包和包之间的联系

《深度解析Java项目中包和包之间的联系》文章浏览阅读850次,点赞13次,收藏8次。本文详细介绍了Java分层架构中的几个关键包:DTO、Controller、Service和Mapper。_jav... 目录前言一、各大包1.DTO1.1、DTO的核心用途1.2. DTO与实体类(Entity)的区别1

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

Java easyExcel实现导入多sheet的Excel

《JavaeasyExcel实现导入多sheet的Excel》这篇文章主要为大家详细介绍了如何使用JavaeasyExcel实现导入多sheet的Excel,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录1.官网2.Excel样式3.代码1.官网easyExcel官网2.Excel样式3.代码

Golang如何对cron进行二次封装实现指定时间执行定时任务

《Golang如何对cron进行二次封装实现指定时间执行定时任务》:本文主要介绍Golang如何对cron进行二次封装实现指定时间执行定时任务问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录背景cron库下载代码示例【1】结构体定义【2】定时任务开启【3】使用示例【4】控制台输出总结背景

使用Python绘制3D堆叠条形图全解析

《使用Python绘制3D堆叠条形图全解析》在数据可视化的工具箱里,3D图表总能带来眼前一亮的效果,本文就来和大家聊聊如何使用Python实现绘制3D堆叠条形图,感兴趣的小伙伴可以了解下... 目录为什么选择 3D 堆叠条形图代码实现:从数据到 3D 世界的搭建核心代码逐行解析细节优化应用场景:3D 堆叠图

深度解析Python装饰器常见用法与进阶技巧

《深度解析Python装饰器常见用法与进阶技巧》Python装饰器(Decorator)是提升代码可读性与复用性的强大工具,本文将深入解析Python装饰器的原理,常见用法,进阶技巧与最佳实践,希望可... 目录装饰器的基本原理函数装饰器的常见用法带参数的装饰器类装饰器与方法装饰器装饰器的嵌套与组合进阶技巧

解析C++11 static_assert及与Boost库的关联从入门到精通

《解析C++11static_assert及与Boost库的关联从入门到精通》static_assert是C++中强大的编译时验证工具,它能够在编译阶段拦截不符合预期的类型或值,增强代码的健壮性,通... 目录一、背景知识:传统断言方法的局限性1.1 assert宏1.2 #error指令1.3 第三方解决

全面解析MySQL索引长度限制问题与解决方案

《全面解析MySQL索引长度限制问题与解决方案》MySQL对索引长度设限是为了保持高效的数据检索性能,这个限制不是MySQL的缺陷,而是数据库设计中的权衡结果,下面我们就来看看如何解决这一问题吧... 目录引言:为什么会有索引键长度问题?一、问题根源深度解析mysql索引长度限制原理实际场景示例二、五大解决