I am having trouble to properly import the Apache POI dependencies I need to run in my Java program. I do need to use some classes to manipulate a .docx file in my program. Since I am doing it in Android Studio, I am importing all the dependencies I need through gradle. However, I am facing some trouble during those imports.
Since I am manipulating some lists in my Word/docx file, I need to use the CTLevelSuffix and STLevelSuffix classes. However, if I implement just org.apache.poi:poi-ooxml:5.2.3
, those classes cannot be found.
So, I thought that I should use the org.apache.poi:poi-ooxml-full:5.2.3
implementation. However, if I do so, those 2 classes can be imported, however, all the org.apache.poi.xwpf.usermodel.*
classes are not imported.
//These imports do not work if I only use "implementation 'org.apache.poi:poi-ooxml-full:5.2.3' "
import org.apache.poi.xwpf.usermodel.XWPFAbstractNum;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFNumbering;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
//----------------------------
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTAbstractNum;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLvl;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STNumberFormat;
//-----------------------------------
//These imports do not work if I only use " implementation 'org.apache.poi:poi-ooxml:5.2.3' "
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STLevelSuffix;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLevelSuffix;
Then, I thought that my problems would be solved if I implemented both poi-ooxml
and poi-ooxml-full
. However, if I do so, I get plenty of building errors, which a small amount of them will be shown here:
...
Duplicate class org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShapeNonVisual found in modules jetified-poi-ooxml-full-5.2.3 (org.apache.poi:poi-ooxml-full:5.2.3) and jetified-poi-ooxml-lite-5.2.3 (org.apache.poi:poi-ooxml-lite:5.2.3)
Duplicate class org.openxmlformats.schemas.presentationml.x2006.main.CTHandoutMasterIdList found in modules jetified-poi-ooxml-full-5.2.3 (org.apache.poi:poi-ooxml-full:5.2.3) and jetified-poi-ooxml-lite-5.2.3 (org.apache.poi:poi-ooxml-lite:5.2.3)
Duplicate class org.openxmlformats.schemas.presentationml.x2006.main.CTHandoutMasterIdListEntry found in modules jetified-poi-ooxml-full-5.2.3 (org.apache.poi:poi-ooxml-full:5.2.3) and jetified-poi-ooxml-lite-5.2.3 (org.apache.poi:poi-ooxml-lite:5.2.3)
...
I get that both poi-ooxml
and poi-ooxml-full
have the same classes and that's why the building keeps failing. However, I do not know how to fix this error since I wasn't able to find a way to import the classes that I need.
Can someone help?
By the way, the implementation snippet of my build.gradle(:app) file looks like that:
...
dependencies {
...
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation 'com.github.bumptech.glide:glide:4.13.1'
implementation 'com.github.Gavras:MultiLineRadioGroup:v1.0.0.6'
implementation 'org.apache.poi:poi-ooxml-full:5.2.3'
implementation 'org.apache.poi:poi-ooxml:5.2.3'
...
}
After a while pondering about this problem, I ended up figuring out that such error was more a "gradle"-based one than an Apache POI one.
As defined in the Apache POI Component Overview, you might have to use more than one jar dependency to fulfill your needs. In my case, since I needed some OpenXML4J
components, I had to use both poi-ooxml
and poi-ooxml-full
jars in order to have access to everything I needed. However, since these two jar have a lot of classes in common, that ended up creating the "duplicate error" problem I was facing.
If we look closer to one (of the many) error messages I got during my building process, we can see which modules were causing my problem:
...
Duplicate class (...) found in
modules jetified-poi-ooxml-full-5.2.3 (org.apache.poi:poi-ooxml-full:5.2.3)
and jetified-poi-ooxml-lite-5.2.3 (org.apache.poi:poi-ooxml-lite:5.2.3)
...
However, a closer look into my gradle file (which the important snippets of it are shown below) would demonstrate that I did not add the poi-ooxml-lite
jar, only the poi-ooxml
(and poi-ooxml-full
). But, as defined on the Component Overview:
poi-ooxml requires poi-ooxml-lite
Which means that, in order to use the former you have to add the latter. However, since gradle helps automatize the download of the dependencies, adding poi-ooxml
makes the builder download all the requirements for this jar to work.
Since the poi-ooxml-full
(formerly known as ooxml-schemas) is only recommended if you need some features not fully implemented in poi-ooxml
, normally you would not have the need to use both jars. However, if you DO need them (like me), you will end up incorring in the problem of this question. That's because, as said before, poi-ooxml
requires poi-ooxml-lite
to work (and, therefore, is downloaded by gradle when you build your project) but plenty of the classes present in the lite version are ALSO present in the full version.
So, in order to solve the problem of duplicate classes, I used the gradle configuration and defined the exclusion of the poi-ooxml-lite
module, since all classes inside it are present inside the poi-ooxml-full
module as well.
My build.gradle(:app) file looks like this
plugins {
id 'com.android.application'
}
android {
...
defaultConfig {
...
}
...
configurations {
all {
exclude group: 'org.apache.poi', module: 'poi-ooxml-lite'
}
}
}
dependencies {
...
implementation 'org.apache.poi:poi-ooxml:5.2.3'
implementation 'org.apache.poi:poi-ooxml-full:5.2.3'
...
}
That being said, Apache POI surely could have made a more intuitive guide or FAQ for some of their modules. The fact that, even if you implement poi-ooxml
module you still might need to implement the poi-ooxml-lite
or poi-ooxml-full
modules are totally counter intuitive at best.