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内容的方案中,使用起来比较简单且轻便挺不错的方案。
我的文章中的代码比较简陋,仅为各位同学提供一个实现这个功能的思路~
十分谢谢阅读的同学,欢迎交流和讨论~
Android EXCEL 解析 xls 和 xlsx,方法其实很简单的更多相关文章
- Java 解析Excel(xls、xlsx两种格式)
Java 解析Excel(xls.xlsx两种格式) 一.环境 JDK 1.8 二.JAR 1.commons-collections4-4.1.jar 2.poi-3.9-20121203.jar ...
- java 调用 C# 类库搞定,三步即可,可以调用任何类及方法,很简单,非常爽啊
java 调用 C# 类库搞定,三步即可,可以调用任何类及方法,很简单,非常爽啊 java 调用 C# 类库搞定,可以调用任何类及方法,很简单,非常爽啊 总体分三步走: 一.准备一个 C# 类库 (d ...
- POI操作Excel(xls、xlsx)
阿帕奇官网:http://poi.apache.org/ POI3.17下载:http://poi.apache.org/download.html#POI-3.17 POI操作Excel教程(易百教 ...
- Android程序解析XML文件的方法及使用PULL解析XML案例
一.一般解析XML文件的方法有SAX和DOM.PULL (1)DOM(JAXP Crimson解析器) DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准.DOM是以层次结构组织的节点或信 ...
- php导出excel(xls或xlsx)
$titles = array('订单号','商品结算码','合同号','供应商名称','专柜','商品名称','商品货号','商品单价','商品总价','供应商结算金额','商品数量','商品促销优 ...
- php导出excel(xls或xlsx)(解决长数字显示问题)
1)demo $titles = array('订单号','商品结算码','合同号','供应商名称','专柜','商品名称','商品货号','商品单价','商品总价','供应商结算金额','商品数量' ...
- java解析Excel(xls、xlsx两种格式)
https://www.cnblogs.com/hhhshct/p/7255915.html ***************************************************** ...
- C# 操作 Excel 文件(.xls 或 .xlsx)
在.net中,常用的操作excel文件的方式,有三种: OLE DB的形式, 第三方框架NPOI, Office组件. 总结: 通过对比,在读取大数据量的excel文件,建议用OLE DB的形式,把e ...
- POI 3.8读取2003与2007格式EXCEL(xls、xlsx)
废话少说直接上代码,记得是poi3.8版本啊.方法入口唯一,自动判断格式,使用接口引用,自动选择执行方法. 方法入口: public static ArrayList<String[]> ...
随机推荐
- python连接mysql中文数据编码
系统是win7 x64 Python 2.7.6的site.py里面编码设定为 utf-8 py文件首行指定 #coding:utf-8 MySQL 5.5.38安装时指定代码为utf-8 peewe ...
- Linux中vim编辑器 的 快捷键 --- 常用 的 都比较全
Linux中vim编辑器的功能非常强大,许多常用快捷键用起来非常方便,这里将我学vim入门时学的一些常用的快捷键分享给大家一下,希望可以帮助你们. 这个是我将鸟哥书上的进行了一下整理的,希望不要涉及到 ...
- 关于《Python自动化测试实战》
作者有话说 笔者写这本书的初心是想通过自身经验分享一些在自动化测试领域中的实用技术,能够帮助那些正在从事自动化测试相关工作或者准备转型自动化测试的测试人员.任何一门技术涵盖的知识点都是非常广泛的,可能 ...
- AJ学IOS(31)UI之Quartz2D图形上下文栈
AJ分享,必须精品 首先,前面博客说过.qurza2d的上下文中有绘图信息和绘图的属性. 但是他是怎么绘制到上下午中的呢? 我们画图时候一半会用这三个步骤: (1)获取上下文 (2)绘图 (3)渲染 ...
- AJ学IOS(29)UI之Quartz2D自定义下载控件_画各种图形
AJ分享,必须精品 效果 自定义控件过程 主要过程在上一篇里有介绍了,这里主要介绍下代码实现 先做好要放的view 然后实现呢主要就是四步: 1:获取上下文 2:拼接路径 3:把路径添加到上下文. 4 ...
- SpringCloud系列之网关(Gateway)应用篇
@ 目录 前言 项目版本 网关访问 鉴权配置 限流配置 前言 由于项目采用了微服务架构,业务功能都在相应各自的模块中,每个业务模块都是以独立的项目运行着,对外提供各自的服务接口,如没有类似网关之类组件 ...
- 你知道如何自动保存 Spring Boot 应用进程号吗
1. 前言 欢迎阅读 Spring Boot 2 实战 系列文章. PID 对于系统运维来说并不陌生,但是对于一些开发者特别是新手还是要简单介绍一下的.它是 Process ID 的简称,是系统分配给 ...
- HPU第一次团队赛
D. Tom的战力问题 Tom被斯派克揍了TAT.Tom下定决心要战胜斯派克.但是在战胜最强的斯派克之前,Tom要先打败其他的狗.为此,他打算先收集一下信息.现在Tom在了得到了一些关于战斗力的小道消 ...
- python之elasticsearch查询
下载所需模块 python安装好的情况下,通过pip install elasticsearch进行es模块的安装 安装完成后通过pip list命中查询 导入模块 from elasticsearc ...
- 简单了解下CAP定理与BASE定理
分布式环境下的各种问题 通信异常 网络不可用风险高,消息丢失.消息延迟非常普遍 网络分区(脑裂) 网络发生异常情况,延迟增加,导致所有组成分布式系统的节点中,只有部分节点之间能够正常通信,而另一些 ...