Android:Apache POI 重复条目:org/apache/xmlbeans/xml/stream/Location.class 错误
Android : Apache POI duplicate entry: org/apache/xmlbeans/xml/stream/Location.class error
嗨,我在 运行 我的 android 项目时遇到以下错误:
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
我在互联网上搜索过这个问题,提供了以下几种不同类型的解决方案:
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)
当我在 gradle 中添加对 Apache POI 的依赖时,上述所有内容都开始了,如下所示:
dependencies {
....
compile group: 'org.apache.poi', name: 'poi-ooxml', version: '3.14'
}
以上的 None 在我的案例中有效。为什么会发生这种情况以及什么是可靠的解决方案。
在你的 Gradle 中使用 support:multidex 编译并添加 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'
}
在你的 AndroidManifest.xml 添加这行 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"
>
如果您使用的是播放服务库而不是替换为
compile 'com.google.android.gms:play-services:+'
代替
compile 'com.google.android.gms:play-services-maps:8.4.0' //or other
阅读其他文章后,我发现在 android 中使用 poi 库存在问题,请参阅下面的 link:
https://bz.apache.org/bugzilla/show_bug.cgi?id=59268#c0
https://github.com/andruhon/android5xlsx 的项目减少了 poi.jar 和 poi-ooxml.jar 的库版本,将它们导入您的 libs 文件夹并在您的 gradle 中包含以下代码:
compile fileTree(include: ['*.jar'], dir: 'libs')
之所以可行,是因为创建此项目的人已将 xmlbeans.jar 从基本 poi.jar 中排除,android 构建有问题。感谢安德鲁洪。
这个解决方法对我有用,因此发布为答案
有一些可用的项目试图解决在 Android 上使用 POI 时的一些问题。
请查看示例项目 https://github.com/centic9/poi-on-android/,它允许为 Android 上的 POI 构建单个 jar 文件。它删除了重复项,还修复了一些与禁止的包名称和其他名称有关的其他问题。
该领域的另一个项目是 https://github.com/andruhon/android5xlsx,但它目前仅支持旧版本的 POI。
poi 库与 multidex apk 构建存在依赖冲突。
要修复这些冲突:
- 删除 gradle 对依赖项或 jar 的引用 [如下所示]。
- 将 this jar without clashing dependancies 添加到 /lib
将以下行添加到模块 gradle:
// implementation 'org.apache.poi:poi-ooxml:3.17'
实现文件('libs/poishadow-all.jar')
您也可以右键单击 jar 并选择添加为库这将自动执行此操作
jar 是从 This Github repository
构建的
为了帮助其他人,这里提供了使用 POI v 3.17(Android API 15 及更高版本)读取 XLS 文件的完整工作解决方案(XLSX 也是如此,但有些行需要更改)。
首先在此处下载 POI jar 文件格式的 0.5 版本:Releases 并将其粘贴到 Android Studio 中的 /lib 文件夹。
带有简单 TextView 和简单 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>
然后将此行放入模块 gradle:
implementation files('libs/poishadow-all.jar')
现在(试用该应用程序)创建一个示例 excel 文件,3 列,3 行,任何您想要的数据。您可以创建更多列和 sheet。但如果您是第一次尝试此代码,请只使用三列。现在文件名与“myexcelsheet.xls”相同 转到 android 项目目录并打开你的 android 项目。进入文件夹 app -> src ->main。在那里你会看到两个文件夹名称为 java 和 res。现在在这里创建一个新文件夹,命名为 assets 并将 myexcelsheet.xls 文件放入其中。
最后是主要 Activity 代码:
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());
}
}
}
要阅读XLSX文件,请阅读Kamal Bunkar先生的评论:
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(“”);
}
显然要适应Android文件位置...
希望能帮到你...
解决它的另一种方法是排除您在实施中视为错误的组,然后重试 运行。
像这样:
implementation ('org.apache.poi:poi-ooxml:3.17')
{
exclude group: 'org.apache.xmlbeans', module: 'xmlbeans'
//
}
注意:检查您的构建错误并将您得到的 class 替换为重复项。
嗨,我在 运行 我的 android 项目时遇到以下错误:
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
我在互联网上搜索过这个问题,提供了以下几种不同类型的解决方案:
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)
当我在 gradle 中添加对 Apache POI 的依赖时,上述所有内容都开始了,如下所示:
dependencies {
....
compile group: 'org.apache.poi', name: 'poi-ooxml', version: '3.14'
}
以上的 None 在我的案例中有效。为什么会发生这种情况以及什么是可靠的解决方案。
在你的 Gradle 中使用 support:multidex 编译并添加 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'
}
在你的 AndroidManifest.xml 添加这行 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"
>
如果您使用的是播放服务库而不是替换为
compile 'com.google.android.gms:play-services:+'
代替
compile 'com.google.android.gms:play-services-maps:8.4.0' //or other
阅读其他文章后,我发现在 android 中使用 poi 库存在问题,请参阅下面的 link:
https://bz.apache.org/bugzilla/show_bug.cgi?id=59268#c0
https://github.com/andruhon/android5xlsx 的项目减少了 poi.jar 和 poi-ooxml.jar 的库版本,将它们导入您的 libs 文件夹并在您的 gradle 中包含以下代码:
compile fileTree(include: ['*.jar'], dir: 'libs')
之所以可行,是因为创建此项目的人已将 xmlbeans.jar 从基本 poi.jar 中排除,android 构建有问题。感谢安德鲁洪。
这个解决方法对我有用,因此发布为答案
有一些可用的项目试图解决在 Android 上使用 POI 时的一些问题。
请查看示例项目 https://github.com/centic9/poi-on-android/,它允许为 Android 上的 POI 构建单个 jar 文件。它删除了重复项,还修复了一些与禁止的包名称和其他名称有关的其他问题。
该领域的另一个项目是 https://github.com/andruhon/android5xlsx,但它目前仅支持旧版本的 POI。
poi 库与 multidex apk 构建存在依赖冲突。 要修复这些冲突:
- 删除 gradle 对依赖项或 jar 的引用 [如下所示]。
- 将 this jar without clashing dependancies 添加到 /lib
将以下行添加到模块 gradle:
// implementation 'org.apache.poi:poi-ooxml:3.17'
实现文件('libs/poishadow-all.jar')
您也可以右键单击 jar 并选择添加为库这将自动执行此操作
jar 是从 This Github repository
构建的为了帮助其他人,这里提供了使用 POI v 3.17(Android API 15 及更高版本)读取 XLS 文件的完整工作解决方案(XLSX 也是如此,但有些行需要更改)。
首先在此处下载 POI jar 文件格式的 0.5 版本:Releases 并将其粘贴到 Android Studio 中的 /lib 文件夹。
带有简单 TextView 和简单 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>
然后将此行放入模块 gradle:
implementation files('libs/poishadow-all.jar')
现在(试用该应用程序)创建一个示例 excel 文件,3 列,3 行,任何您想要的数据。您可以创建更多列和 sheet。但如果您是第一次尝试此代码,请只使用三列。现在文件名与“myexcelsheet.xls”相同 转到 android 项目目录并打开你的 android 项目。进入文件夹 app -> src ->main。在那里你会看到两个文件夹名称为 java 和 res。现在在这里创建一个新文件夹,命名为 assets 并将 myexcelsheet.xls 文件放入其中。
最后是主要 Activity 代码:
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());
}
}
}
要阅读XLSX文件,请阅读Kamal Bunkar先生的评论:
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(“”);
}
显然要适应Android文件位置...
希望能帮到你...
解决它的另一种方法是排除您在实施中视为错误的组,然后重试 运行。
像这样:
implementation ('org.apache.poi:poi-ooxml:3.17')
{
exclude group: 'org.apache.xmlbeans', module: 'xmlbeans'
//
}
注意:检查您的构建错误并将您得到的 class 替换为重复项。