2016-10-11 4 views
2

Actuellement, je travaille sur le développement android. Comme l'exigence indiqué, l'application devrait pouvoir lire les fichiers Excel pour la saisie de données.Lire Excel dans Android

Comme d'autres personnes commencent par ce sujet, je passer par Java Excel Api et Apache POI, mais les deux doivent avoir une certaine modification pour tenir mon exigence:

API JExcel:
- ne peut pas soutenir XLSX

Apache POI:
- Support bien pour les fichiers XLS
- pour soutenir XLSX à Dalvik, vous devez surmonter 64K et javax li broyer, ou utiliser la version du port (c.-à-d. de Andrew Kondratev)
- Taille du fichier augmentera 2.4MB

Mais ne nous avons d'autres options pour travailler avec des fichiers Excel dans Android 4 ou ci-dessous?

Répondre

4

Pour ceux qui ont besoin de l'application de travailler avec des fichiers Excel fonctionnels complets (à savoir le dessin, VBA, etc ...), vous devriez aller avec Apache POI, il est clair, mais encore la meilleure solution pour que maintenant.

Cependant, si vous avez juste besoin de lire l'Excel, il est peut-être bon d'aller avec la solution JavaScript. Avec la bibliothèque js-xlsx, vous pouvez transférer des fichiers Excel dans JSON. Et la taille de la bibliothèque est petite, juste 395KB (seulement inclure xlsx.core.min.js)

Je crois que ce pas la meilleure solution:
- WebView besoin de travailler avec UI Thread, il peut bloquer l'interface utilisateur lorsque lire un gros fichier Excel.
- Problème de performance
Mais vous pouvez le remplacer par un autre moteur JavaScript tel que Rhino ou V8 pour résoudre ces problèmes.

Voici le code

Interface pour le rappel:

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

MainActivity:

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

Interface pour l'utilisateur de sélectionner fichier excel:

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

JSExcelReader: (partie de base pour lire Excel et le transformer en 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: (Vous devriez mettre cela et la bibliothèque JavaScript dans actifs dossier)

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