基于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

相关文章

线上Java OOM问题定位与解决方案超详细解析

《线上JavaOOM问题定位与解决方案超详细解析》OOM是JVM抛出的错误,表示内存分配失败,:本文主要介绍线上JavaOOM问题定位与解决方案的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一、OOM问题核心认知1.1 OOM定义与技术定位1.2 OOM常见类型及技术特征二、OOM问题定位工具

Python实现Excel批量样式修改器(附完整代码)

《Python实现Excel批量样式修改器(附完整代码)》这篇文章主要为大家详细介绍了如何使用Python实现一个Excel批量样式修改器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录前言功能特性核心功能界面特性系统要求安装说明使用指南基本操作流程高级功能技术实现核心技术栈关键函

Python实现批量CSV转Excel的高性能处理方案

《Python实现批量CSV转Excel的高性能处理方案》在日常办公中,我们经常需要将CSV格式的数据转换为Excel文件,本文将介绍一个基于Python的高性能解决方案,感兴趣的小伙伴可以跟随小编一... 目录一、场景需求二、技术方案三、核心代码四、批量处理方案五、性能优化六、使用示例完整代码七、小结一、

深度解析Python中递归下降解析器的原理与实现

《深度解析Python中递归下降解析器的原理与实现》在编译器设计、配置文件处理和数据转换领域,递归下降解析器是最常用且最直观的解析技术,本文将详细介绍递归下降解析器的原理与实现,感兴趣的小伙伴可以跟随... 目录引言:解析器的核心价值一、递归下降解析器基础1.1 核心概念解析1.2 基本架构二、简单算术表达

深度解析Java @Serial 注解及常见错误案例

《深度解析Java@Serial注解及常见错误案例》Java14引入@Serial注解,用于编译时校验序列化成员,替代传统方式解决运行时错误,适用于Serializable类的方法/字段,需注意签... 目录Java @Serial 注解深度解析1. 注解本质2. 核心作用(1) 主要用途(2) 适用位置3

Java MCP 的鉴权深度解析

《JavaMCP的鉴权深度解析》文章介绍JavaMCP鉴权的实现方式,指出客户端可通过queryString、header或env传递鉴权信息,服务器端支持工具单独鉴权、过滤器集中鉴权及启动时鉴权... 目录一、MCP Client 侧(负责传递,比较简单)(1)常见的 mcpServers json 配置

从原理到实战解析Java Stream 的并行流性能优化

《从原理到实战解析JavaStream的并行流性能优化》本文给大家介绍JavaStream的并行流性能优化:从原理到实战的全攻略,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的... 目录一、并行流的核心原理与适用场景二、性能优化的核心策略1. 合理设置并行度:打破默认阈值2. 避免装箱

Maven中生命周期深度解析与实战指南

《Maven中生命周期深度解析与实战指南》这篇文章主要为大家详细介绍了Maven生命周期实战指南,包含核心概念、阶段详解、SpringBoot特化场景及企业级实践建议,希望对大家有一定的帮助... 目录一、Maven 生命周期哲学二、default生命周期核心阶段详解(高频使用)三、clean生命周期核心阶

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

Java Scanner类解析与实战教程

《JavaScanner类解析与实战教程》JavaScanner类(java.util包)是文本输入解析工具,支持基本类型和字符串读取,基于Readable接口与正则分隔符实现,适用于控制台、文件输... 目录一、核心设计与工作原理1.底层依赖2.解析机制A.核心逻辑基于分隔符(delimiter)和模式匹