前言
Excel 解析,通常來講是在服務端進行的,可是若是移動端要實現解析Excel的功能,那也是有實現的方法的。java
不過因爲Android 原生用Java/Kotlin實現,因此也能夠參考服務端解析Excel的方法。android
首先說,jxl,過去比較流行的解析office文檔的框架,但目前官方的版本,在移動端上是不能解析xlsx。c++
而後是POI,是現在比較主流的處理office文檔的框架,能夠導入也能夠生成,缺點是:官方的依賴包的體積較大,官方最新版本在android項目所需sdk須要minSDK 24及以上。git
最後找到的一個比較輕便簡單的方案是,經過一個國外的開發者對POI包進行簡化後的庫android5xlsx,保留了在Android5以上解析xls和xlsx的功能(開發者本人吐槽在android5如下解析Excel真有點繞)github
android5xlsx的github地址apache
下面是個人項目中簡單使用這個庫的一些步驟(非源碼分析講解,請諒解):(Android 10 環境實測有效)app
使用步驟
1、解除 65 K 方法的限制:框架
android { compileSdkVersion 29 buildToolsVersion "29.0.2" defaultConfig { ..... versionName "1.0" multiDexEnabled true //true 開啓多dex,解除65k限制 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } }
2、將android5xlsx的核心的兩個jar包導入項目lib文件夾xss
將簡單解析Excel文件內容的操做,封裝在一個工具類ExcelUtils
內:ide
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); } }
3、簡單解析一個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內容的方案中,使用起來比較簡單且輕便挺不錯的方案。
個人文章中的代碼比較簡陋,僅爲各位同窗提供一個實現這個功能的思路~
十分謝謝閱讀的同窗,歡迎交流和討論~