Excel 解析,一般来说是在服务端进行的,但是如果移动端要实现解析Excel的功能,那也是有实现的方法的。

不过由于Android 原生用Java/Kotlin实现,所以也可以参考服务端解析Excel的方法。

首先说,jxl,过去比较流行的解析office文档的框架,但目前官方的版本,在移动端上是不能解析xlsx。

然后是POI,是如今比较主流的处理office文档的框架,可以导入也可以生成,缺点是:官方的依赖包的体积较大,官方最新版本在android项目所需sdk需要minSDK 24及以上。

最后找到的一个比较轻便简单的方案是,通过一个国外的开发者对POI包进行简化后的库android5xlsx,保留了在Android5以上解析xls和xlsx的功能(开发者本人吐槽在android5以下解析Excel真有点绕)

android5xlsx的github地址

下面是我的项目中简单使用这个库的一些步骤(非源码分析讲解,请谅解):(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文件夹

Android Excel 解析 xls 和 xlsx,方法也可以很简单_第1张图片

Android Excel 解析 xls 和 xlsx,方法也可以很简单_第2张图片

将简单解析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文件内的内容

Android Excel 解析 xls 和 xlsx,方法也可以很简单_第3张图片

解析结果:以log打印结果展示

Android Excel 解析 xls 和 xlsx,方法也可以很简单_第4张图片

可以看到可以按照从左到右读取每一行内容,一直向下读取。

有需要的同学可以根据需求,改造一下解析工具类,可以将解析结果转为所需要的实体类对象,也可以写入Excel,更更更具体多样的操作请参考开发者给出的demo吧。

总结

我认为这是在Android端解析Excel 的xls xlsx内容的方案中,使用起来比较简单且轻便挺不错的方案。

我的文章中的代码比较简陋,仅为各位同学提供一个实现这个功能的思路~

十分谢谢阅读的同学,欢迎交流和讨论~

更多相关文章

  1. Android中使用定制系统的签名文件给应用签名
  2. Android OTA包重新签名的方法
  3. 【Android语音合成TTS】百度语音接入方法,和使用技巧详解
  4. 通过wifi连接android设备的方法
  5. Android Studio中新建assets文件的两种方法
  6. 多态在android中(利用接口调用服务中方法)的应用

随机推荐

  1. Android捕获Home按键
  2. XUtils-Android(安卓)最火的快速开发框架
  3. Android事件的分发、拦截和执行
  4. android_Server_Socket_通信序列化实现
  5. Android(安卓)高德地图 Polyline 设置点
  6. android- activity,Application,activity
  7. Error generating final archive
  8. android(bug) USB BUG
  9. android代码分析,及Terminal使用
  10. Android(安卓)使用USB与PC通信之ADB方式