前言
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檔案夾
將簡單決議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 = https://www.cnblogs.com/DMingO/p/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 =https://www.cnblogs.com/DMingO/p/= 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內容的方案中,使用起來比較簡單且輕便挺不錯的方案,
我的文章中的代碼比較簡陋,僅為各位同學提供一個實作這個功能的思路~
十分謝謝閱讀的同學,歡迎交流和討論~
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/5569.html
標籤:Android
上一篇:Android JetPack組件-CameraX初探
下一篇:Android 屬性影片
