ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

在Android中阅读Excel

2019-07-27 11:35:54  阅读:336  来源: 互联网

标签:jexcelapi android excel apache-poi


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

正如其他人从这个主题开始,我已经完成了Java Excel ApiApache POI,但两者都需要进行一些修改以满足我的要求:

JExcel API:
   – 不能支持XLSX

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

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

解决方法:

对于那些需要使用全功能excel文件(即绘图,VBA等等)的应用程序,你应该使用Apache POI,它很简单,但现在仍然是最好的解决方案.

但是,如果您只需要阅读Excel,那么使用JavaScript解决方案可能会更好.使用js-xlsx库,您可以将Excel文件传输到JSON.库大小很小,只有395KB(仅包括xlsx.core.min.js)

我相信这不是最好的解决方案:
   – WebView需要使用UI Thread,它可能会在读取大型Excel文件时阻止UI.
   – 性能问题
但您可以将其更改为其他JavaScript引擎(如Rhino或V8)以解决这些问题.

这是代码

回调接口:

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
    ...
}

用户选择excel文件的界面:

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>

标签:jexcelapi,android,excel,apache-poi
来源: https://codeday.me/bug/20190727/1553770.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有