欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android EXCEL 解析 xls 和 xlsx,方法其实很简单

程序员文章站 2022-04-15 22:05:14
前言 Excel 解析,一般来说是在服务端进行的,但是如果移动端要实现解析Excel的功能,那也是有实现的方法的。 不过由于Android 原生用Java/Kotlin实现,所以也可以参考服务端解析Excel的方法。 首先说, jxl ,过去比较流行的解析office文档的框架,但目前官方的版本,在 ......

前言

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文件夹

Android EXCEL 解析 xls 和 xlsx,方法其实很简单

Android EXCEL 解析 xls 和 xlsx,方法其实很简单

将简单解析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,方法其实很简单

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

Android EXCEL 解析 xls 和 xlsx,方法其实很简单

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

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

总结

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

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

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