Android : Apache POI duplicate entry: org/apache/xmlbeans/xml/stream/Location.class error

笑着哭i 提交于 2019-12-29 09:07:23

问题


Hi I am getting following error while running my android project :

Error:Execution failed for task ':app:transformClassesWithJarMergingForDebug'.
> com.android.build.api.transform.TransformException: java.util.zip.ZipException: duplicate entry: org/apache/xmlbeans/xml/stream/Location.class

I have searched about this issue on internet, differenet type of solutions provided few of them as below :

1] Enable multidex, (by doing `multiDexEnabled true`),
2] Remove support library v4 as v7 comes with it, (I am using only v7),
3] Increase jvm heap size through gradle or through gradle.properties,
2] Do not use multiple playstore library versions (Which I am not using already)

All above started when I added dependecy for Apache POI in gradle as follows :

dependencies {
    ....
    compile group: 'org.apache.poi', name: 'poi-ooxml', version: '3.14'
}

None of the above worked in my case. Why this is happening & what is reliable solution.


回答1:


There are a few projects available which try to work around a number of issues when using POI on Android.

Please take a look at the sample project https://github.com/centic9/poi-on-android/ which allows to build a single jar-file for POI on Android. It removes the duplicates and also fixes a few other issues with prohibited package names and others.

Another project in that area is https://github.com/andruhon/android5xlsx, however it only supports an older version of POI currently.




回答2:


The poi library has dependancy clashes with multidex apk build. To fix these clashes:

  1. Remove gradle reference to the dependancy or jar [as bellow].
  2. Add this jar without clashing dependancies to /lib
  3. Add the following line to module gradle:

    //    implementation 'org.apache.poi:poi-ooxml:3.17'
    

    implementation files('libs/poishadow-all.jar')

  4. You can also right click the jar and choose add as library which will do this automatically

The jar was built from This Github repository




回答3:


In your Gradle Compile with support:multidex and add also dexOptions

android {
compileSdkVersion 23
buildToolsVersion "23.0.3"



defaultConfig {
   ..............
    minSdkVersion 19
    targetSdkVersion 23
    versionCode 1
    versionName "1.0"
    multiDexEnabled true


}
dexOptions {
    //incremental = true;
    preDexLibraries = false
    javaMaxHeapSize "4g"
}

packagingOptions {
    exclude 'META-INF/NOTICE.txt' // will not include NOTICE file
    exclude 'META-INF/LICENSE.txt' // will not include LICENSE file
}

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
 }

 dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
//Your Dependencies
compile 'com.android.support:multidex:1.0.1'
 }

In Your AndroidManifest.xml add this lines android:name

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme"
    android:name="android.support.multidex.MultiDexApplication"
    >

If you have using the play service library than replace with

 compile 'com.google.android.gms:play-services:+'

Instead OF

   compile 'com.google.android.gms:play-services-maps:8.4.0' //or other



回答4:


After doing some other reading I found out there are issues with using poi library in android, see link below :

https://bz.apache.org/bugzilla/show_bug.cgi?id=59268#c0

Project at https://github.com/andruhon/android5xlsx has reduced library versions for both poi.jar & poi-ooxml.jar, import these in your libs folder & include following code in your gradle :

compile fileTree(include: ['*.jar'], dir: 'libs')

The reason this works is the guy who has created this project has excluded the xmlbeans.jar from basic poi.jar with which android build has problem. Credit goes to the guy andruhon.

This workaround worked for me hence posting as answer




回答5:


As to help other people, here the complete working solution to read XLS files with POI v 3.17 (Android API 15 and later) (XLSX too but some lines to be changed).

First off all download the 0.5 release of the POI jar file form here: Releases and paste it to the /lib folder in Android Studio.

Your Layout with a simple TextView and a simple Button:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFEB3B"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginLeft="24dp"
        android:layout_marginTop="24dp"
        android:layout_marginRight="24dp"
        android:layout_marginBottom="24dp"
        android:background="#FFFFFF"
        android:inputType="textMultiLine"
        android:padding="24dp"
        android:singleLine="false"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="@+id/textView"
        app:layout_constraintEnd_toEndOf="@+id/textView"
        app:layout_constraintStart_toStartOf="@+id/textView" />

</android.support.constraint.ConstraintLayout>

Then place this line in module gradle:

implementation files('libs/poishadow-all.jar')

Now (to try the app) create a sample excel file, 3 columns, 3 rows, any data you want. You can create more columns and sheet. But if you are trying this code first time, so please work with three columns only. now same the file name as “myexcelsheet.xls” Go to android project directory and open your android project. Go inside folder app -> src ->main. There you will see two folder name as java and res. Now create a new folder here name as assets and put myexcelsheet.xls file inside it.

Finally the Main Activity code:

package com.example.readexcelfiles;

import android.content.res.AssetManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;

import java.io.InputStream;
import java.util.Iterator;

public class MainActivity extends AppCompatActivity {

    TextView txtView;
    Button btnRead;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        txtView = findViewById(R.id.textView);
        btnRead = findViewById(R.id.button);



        btnRead.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                readExcelFileFromAssets();
            }
        });

    }


    public void readExcelFileFromAssets() {
        try {
            InputStream myInput;
            // initialize asset manager
            AssetManager assetManager = getAssets();
            //  open excel sheet
            myInput = assetManager.open("myexcelsheet.xls");
            // Create a POI File System object
            POIFSFileSystem myFileSystem = new POIFSFileSystem(myInput);
            // Create a workbook using the File System
            HSSFWorkbook myWorkBook = new HSSFWorkbook(myFileSystem);
            // Get the first sheet from workbook
            HSSFSheet mySheet = myWorkBook.getSheetAt(0);
            // We now need something to iterate through the cells.
            Iterator<Row> rowIter = mySheet.rowIterator();
            int rowno =0;
            txtView.append("\n");
            while (rowIter.hasNext()) {
                Log.e("aaa", " row no "+ rowno );
                HSSFRow myRow = (HSSFRow) rowIter.next();
                if(rowno !=0) {
                    Iterator<Cell> cellIter = myRow.cellIterator();
                    int colNum =0;
                    String sno="", date="", det="";
                    while (cellIter.hasNext()) {
                        HSSFCell myCell = (HSSFCell) cellIter.next();
                        if (colNum==0){
                            sno = myCell.toString();
                        }else if (colNum==1){
                            date = myCell.toString();
                        }else if (colNum==2){
                            det = myCell.toString();
                        }
                        colNum++;
                        Log.e("aaa", " Index :" + myCell.getColumnIndex() + " -- " + myCell.toString());
                    }
                    txtView.append( sno + " -- "+ date+ "  -- "+ det+"\n");
                }
                rowno++;
            }
        } catch (Exception e) {
            Log.e("aaa", "error "+ e.toString());
        }
    }





}

In order to read XLSX file, please read Mr. Kamal Bunkar comment:

First understand the notation. XSSF (XML SpreadSheet Format) – Used to reading and writting Open Office XML (XLSX) format files. HSSF (Horrible SpreadSheet Format) – Use to read and write Microsoft Excel (XLS) format files. HWPF (Horrible Word Processor Format) – to read and write Microsoft Word 97 (DOC) format files.

In my tutorial I was using

// Get the first sheet from workbook
HSSFSheet mySheet = myWorkBook.getSheetAt(0);

Now to work with xlsx you should use this code

File myFile = new File(“C://temp/Employee.xlsx”);
FileInputStream fis = new FileInputStream(myFile);
// Finds the workbook instance for XLSX file
XSSFWorkbook myWorkBook = new XSSFWorkbook (fis);
// Return first sheet from the XLSX workbook
XSSFSheet mySheet = myWorkBook.getSheetAt(0);
// Get iterator to all the rows in current sheet
Iterator rowIterator = mySheet.iterator();
// Traversing over each row of XLSX file
while (rowIterator.hasNext())
{
Row row = rowIterator.next();
// For each row, iterate through each columns
Iterator cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
switch (cell.getCellType()) { case Cell.CELL_TYPE_STRING: System.out.print(cell.getStringCellValue() + “\t”);
break; case Cell.CELL_TYPE_NUMERIC:System.out.print(cell.getNumericCellValue() + “\t”);
break; case Cell.CELL_TYPE_BOOLEAN: System.out.print(cell.getBooleanCellValue() + “\t”);
break; default : }
}
System.out.println(“”);
}

Obviously to be adapted to Android file location...

Hope to help...



来源:https://stackoverflow.com/questions/38201667/android-apache-poi-duplicate-entry-org-apache-xmlbeans-xml-stream-location-cl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!