在Android中读取Excel

目前我正在开发android。 根据要求,应用程序应能够读取Excel文件以进行数据input。

正如其他人从这个话题开始,我已经经历了Java Excel ApiApache POI ,但都需要进行一些修改以适应我的要求:

JExcel API
– 无法支持XLSX

Apache POI
– 支持XLS文件
– 要在Dalvik中支持XLSX,您需要克服64K和javax库,或者使用端口版本(即来自Andrew Kondratev )
– 文件大小将增加2.4MB

但是,我们有其他select在Android 4或更低版本中使用Excel文件吗?

对于那些需要使用全function的excel文件(例如绘图,VBA等)的应用程序,您应该使用Apache POI ,这很简单,但现在仍然是最好的解决scheme。

但是,如果您只需要阅读Excel,那么使用JavaScript解决scheme也许是件好事。 使用js-xlsx库,您可以将Excel文件转换为JSON。 而且这个库的大小很小,只有395KB(只包含xlsx.core.min.js

我相信这不是最好的解决scheme:
WebView需要使用UI Thread ,在读取大型Excel文件时可能会阻塞UI。
– 性能问题
但是你可以把它改成像RhinoV8这样的其他JavaScript引擎来解决这些问题。

这是代码

callback界面:

 public interface ExcelReaderListener { void onReadExcelCompleted(List<String> stringList); } 

主要活动:

 private ProgressDialog progressDialog; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new AlertDialog.Builder(MainActivity.this) .setMessage("message") .setTitle("title") .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); new FileChooser(MainActivity.this, new String[]{"xls", "xlsx"}) .setFileListener(new FileChooser.FileSelectedListener() { @Override public void fileSelected(File file) { progressDialog = new ProgressDialog(MainActivity.this); progressDialog.setTitle("title"); progressDialog.setMessage("message"); progressDialog.setIndeterminate(true); progressDialog.setCanceledOnTouchOutside(false); Toast.makeText(MainActivity.this, file.getName(), Toast.LENGTH_SHORT).show(); String filePath = file.getAbsolutePath(); ExcelReaderListener excelReaderListener = MainActivity.this; progressDialog.show(); try { final WebView webView = new WebView(MainActivity.this); new JSExcelReader(filePath, webView, excelReaderListener); } catch (Exception ex) { Log.e("Import excel error", ex.getMessage()); } } }) .showDialog(); } }) .show(); } @Override public void onReadExcelCompleted(List<String> stringList) { Toast.makeText(MainActivity.this, "Parse Completed", Toast.LENGTH_SHORT).show(); if (progressDialog != null && progressDialog.isShowing()) { progressDialog.dismiss(); } // Write into DB ... } 

用户selectexcel文件的界面:

https://rogerkeays.com/simple-android-file-chooser

JSExcelReader :(核心部分读取excel并将其转换为ArrayList)

 public class JSExcelReader { private ExcelReaderListener callback; public JSExcelReader(String filePath, final WebView webView, ExcelReaderListener callback) { this.callback = callback; File file = new File(filePath); try (InputStream is = new FileInputStream(file)) { // convert file to Base64 if (file.length() > Integer.MAX_VALUE) Log.e("File too big", "file too big"); byte[] bytes = new byte[(int) file.length()]; int offset = 0; int numRead; while (offset < bytes.length && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) { offset += numRead; } if (offset < bytes.length) throw new Exception("Could not completely read file"); final String b64 = Base64.encodeToString(bytes, Base64.NO_WRAP); // feed the string into webview and get the result WebSettings webSettings = webView.getSettings(); webSettings.setJavaScriptEnabled(true); webView.loadUrl("file:///android_asset/AndroidParseExcel.html"); webView.setWebViewClient(new WebViewClient() { public void onPageFinished(WebView view, String url) { webView.evaluateJavascript("convertFile('" + b64 + "');", new ValueCallback<String>() { @Override public void onReceiveValue(String value) { parseJSON(value); } }); } }); } catch (Exception ex) { Log.e("Convert Excel failure", ex.getMessage()); } } private void parseJSON(String jsonString) { try { // return value is something like "{\n\"Sheet1\":\n[\"title\"... // you need to remove those escape character first JSONObject jsonRoot = new JSONObject(jsonString.substring(1, jsonString.length() - 1) .replaceAll("\\\\n", "") .replaceAll("\\\\\"", "\"") .replaceAll("\\\\\\\\\"", "'")); JSONArray sheet1 = jsonRoot.optJSONArray("Sheet1"); List<String> stringList = new ArrayList<>(); JSONObject jsonObject; for (int i = 0; i < sheet1.length(); i++) { jsonObject = sheet1.getJSONObject(i); stringList.add(jsonObject.optString("title")); } callback.onReadExcelCompleted(stringList); } catch (Exception ex) { Log.e("Error in parse JSON", ex.getMessage()); } } } 

AndroidParseExcel.html 🙁你应该把这个和JavaScript库放到资源文件夹中)

 <html> <script src="file:///android_asset/xlsx.core.min.js"></script> <head></head> <body> </body> <script type ="text/javascript"> "use strict"; var X = XLSX; function convertFile(b64data) { var wb = X.read(b64data, {type: 'base64',WTF: false}); var result = {}; wb.SheetNames.forEach(function(sheetName) { var roa = X.utils.sheet_to_row_object_array(wb.Sheets[sheetName]); if(roa.length > 0){ result[sheetName] = roa; } }); return JSON.stringify(result, 2, 2); } </script> </html>