Android EXCEL 解析 xls 和 xlsx,方法其实很简单
前言
excel 解析,一般来说是在服务端进行的,但是如果移动端要实现解析excel的功能,那也是有实现的方法的。
不过由于android 原生用java/kotlin实现,所以也可以参考服务端解析excel的方法。
首先说,jxl,过去比较流行的解析office文档的框架,但目前官方的版本,在移动端上是不能解析xlsx。
然后是poi,是如今比较主流的处理office文档的框架,可以导入也可以生成,缺点是:官方的依赖包的体积较大,官方最新版本在android项目所需sdk需要minsdk 24及以上。
最后找到的一个比较轻便简单的方案是,通过一个国外的开发者对poi包进行简化后的库android5xlsx,保留了在android5以上解析xls和xlsx的功能(开发者本人吐槽在android5以下解析excel真有点绕)
下面是我的项目中简单使用这个库的一些步骤(非源码分析讲解,请谅解):(android 10 环境实测有效)
使用步骤
一、解除 65 k 方法的限制:
android { compilesdkversion 29 buildtoolsversion "29.0.2" defaultconfig { ..... versionname "1.0" multidexenabled true //true 开启多dex,解除65k限制 testinstrumentationrunner "androidx.test.runner.androidjunitrunner" } }
二、将android5xlsx的核心的两个jar包导入项目lib文件夹
将简单解析excel文件内容的操作,封装在一个工具类excelutils
内:
excel解析工具类代码
import android.util.log; import com.blankj.utilcode.util.logutils; import org.apache.poi.hssf.usermodel.hssfdateutil; import org.apache.poi.ss.usermodel.cell; import org.apache.poi.ss.usermodel.cellvalue; import org.apache.poi.ss.usermodel.formulaevaluator; import org.apache.poi.ss.usermodel.row; import org.apache.poi.xssf.usermodel.xssfsheet; import org.apache.poi.xssf.usermodel.xssfworkbook; import java.io.file; import java.io.fileinputstream; import java.io.filenotfoundexception; import java.io.inputstream; import java.text.simpledateformat; /** * @description: excel 工具类 * @author: odm * @date: 2020/4/11 */ public class excelutils { /** * 读取excel文件 * @param file * @throws filenotfoundexception */ public static void readexcel(file file) throws filenotfoundexception { if(file == null) { log.e("nullfile","读取excel出错,文件为空文件"); return; } inputstream stream = new fileinputstream(file); try { xssfworkbook workbook = new xssfworkbook(stream); xssfsheet sheet = workbook.getsheetat(0); int rowscount = sheet.getphysicalnumberofrows(); formulaevaluator formulaevaluator = workbook.getcreationhelper().createformulaevaluator(); for (int r = 0; r<rowscount; r++) { row row = sheet.getrow(r); int cellscount = row.getphysicalnumberofcells(); //每次读取一行的内容 for (int c = 0; c<cellscount; c++) { //将每一格子的内容转换为字符串形式 string value = getcellasstring(row, c, formulaevaluator); string cellinfo = "r:"+r+"; c:"+c+"; v:"+value; logutils.d(cellinfo); } } } catch (exception e) { /* proper exception handling to be here */ logutils.e(e.tostring()); } } /** * 读取excel文件中每一行的内容 * @param row * @param c * @param formulaevaluator * @return */ private static string getcellasstring(row row, int c, formulaevaluator formulaevaluator) { string value = ""; try { cell cell = row.getcell(c); cellvalue cellvalue = formulaevaluator.evaluate(cell); switch (cellvalue.getcelltype()) { case cell.cell_type_boolean: value = ""+cellvalue.getbooleanvalue(); break; case cell.cell_type_numeric: double numericvalue = cellvalue.getnumbervalue(); if(hssfdateutil.iscelldateformatted(cell)) { double date = cellvalue.getnumbervalue(); simpledateformat formatter = new simpledateformat("dd/mm/yy"); value = formatter.format(hssfdateutil.getjavadate(date)); } else { value = ""+numericvalue; } break; case cell.cell_type_string: value = ""+cellvalue.getstringvalue(); break; default: break; } } catch (nullpointerexception e) { /* proper error handling should be here */ logutils.e(e.tostring()); } return value; } /** * 根据类型后缀名简单判断是否excel文件 * @param file 文件 * @return 是否excel文件 */ public static boolean checkifexcelfile(file file){ if(file == null) { return false; } string name = file.getname(); //”.“ 需要转义字符 string[] list = name.split("\\."); //划分后的小于2个元素说明不可获取类型名 if(list.length < 2) { return false; } string typename = list[list.length - 1]; //满足xls或者xlsx才可以 return "xls".equals(typename) || "xlsx".equals(typename); } }
三、简单解析一个excel文件 演示
在页面打开文件管理器,选取手机本地的excel文件,然后利用excelutils
打印出excel文件的内容:
顺带一提,读取excel也是需要对应读写文件的权限的哦~
class memberfragment : basemvvmfragment() { // 打开系统自带的文件选择器 private fun openfileselector() { val intent = intent(intent.action_get_content) intent.addcategory(intent.category_openable) intent.type = "*/*" // intent.type = "application/vnd.ms-excel application/x-excel" 未知无效原因 this.startactivityforresult(intent, 1) } override fun onactivityresult( requestcode: int, resultcode: int, data: intent? ) { super.onactivityresult(requestcode, resultcode, data) if (data == null) { // 用户未选择任何文件,直接返回 return } val uri: uri? = data.data // 获取用户选择文件的uri uri?.let { val file = uriutils.uri2file(it) if(excelutils.checkifexcelfile(file)){ excelutils.readexcel(file) //读取excel file 内容 } } } }
在本地文件管理器中,任意选择一个excel文件,这里是选择了读取 test2.xlsx 文件,以下是excel文件内的内容
解析结果:以log打印结果展示
可以看到可以按照从左到右读取每一行内容,一直向下读取。
有需要的同学可以根据需求,改造一下解析工具类,可以将解析结果转为所需要的实体类对象,也可以写入excel,更更更具体多样的操作请参考开发者给出的demo吧。
总结
我认为这是在android端解析excel 的xls xlsx内容的方案中,使用起来比较简单且轻便挺不错的方案。
我的文章中的代码比较简陋,仅为各位同学提供一个实现这个功能的思路~
十分谢谢阅读的同学,欢迎交流和讨论~
上一篇: 6. Go 语言数据类型:字典与布尔类型