May I use jxls and apache poi together? - apache-poi

I'm making an application to analize some data and the result must be presented in excel files. In that sense I started to use Apache POI (3.11). Due to some reports consumes a lot of time and memory to be reproduce, I made an investigation and I found jxls, after some test I thought was the solution. But now I found a problem: can´t work both frameworks together.
I have to update Apache POI from 3.11 to 3.14, in order to work with jxls-2.3.0
I made an extra package in order to make my tests with jxls, not problem
I try to migrated one of my classes from Apache POI to jxls, and a I got this error: java.lang.IllegalStateException: Cannot load XLS transformer. Please make sure a Transformer implementation is in classpath. This is the code of my method:
private void prepareNewReport(File excelFile) {
List perforaciones = makePerforacionReport
.makePerforacionData(escenario);
try (InputStream is = ReportePerforacionTotalDialog.class
.getResourceAsStream("PerforacionTotal_template.xls")){
try (OutputStream os = new FileOutputStream(excelFile)) {
Context context = new Context();
context.putVar("perforaciones", perforaciones);
JxlsHelper.getInstance().processTemplate(is, os, context);
LOGGER.logger.log(Level.INFO, "Archivo de perfortacion generado con éxito");
}
} catch (IOException e) {
LOGGER.logger.log(Level.SEVERE, "Problemas buscando el archivo", e);
}
}
How could be this possible?. In the same project I have my test class, just another package and its working fine. As you can see it´s not so much different from the example in the jxls page and the imports are the same.
But even worst, when I tried to make clean & build of my project, then I got this other error:
java.lang.RuntimeException: com.sun.tools.javac.code.Symbol$CompletionFailure: class file for org.openxmlformats.schemas.officeDocument.x2006.docPropsVTypes.CTArray not found
I looked at every library that I importede in order to work with jxls and apache poi, and that´s rigth, that class is not there. Just to see if there a conflict among these two framewoks, I eliminated from the class path all libraries needed to use jxls. Clean & build again, and not problem, I have my .jar file to send to my customer, but incomplete.
I could try to replace all classes that use Apache POI, but that means a lot of work, since POI is used in my project to read excel files with data many times and to write another many files to excel. I planned to use jxls in order to take advantage of use templates.
I will apreciate any help or suggestion.

For the first error, it would appear that the JXLS transformer for Apache POI is missing in your classpath when running the application. Check the JXLS getting started info here: http://jxls.sourceforge.net/getting_started.html
As it is explained in Transformers section (see Main Concepts)) Jxls core module does not depend on any specific Java-Excel library and works with Excel exclusively through a predefined interface. Currently Jxls supplies two implementations of this interface in separate modules based on the well-known Apache POI and Java Excel API libraries.
If you're using maven, be sure to include in your pom.xml the jxls-poi dependency listed on the JXLS getting started page:
<dependency>
<groupId>org.jxls</groupId>
<artifactId>jxls-poi</artifactId>
<version>1.0.9</version>
</dependency>
For the second issue, org.openxmlformats.schemas.officeDocument.x2006.docPropsVTypes.CTArray is not in the apache POI ooxml schemas jar files for either 3.11 (poi-ooxml-schemas-3.11-20141221.jar) or 3.14 (poi-ooxml-schemas-3.14-20160307.jar). POI uses a stripped down set of ooxml schema classes, you will need to get the ooxml schemas complete jar from http://central.maven.org/maven2/org/apache/poi/ooxml-schemas/1.3/ or if you're using maven (or another build tool), get the dependency for your build from https://mvnrepository.com/artifact/org.apache.poi/ooxml-schemas/1.3
e.g for maven:
<!-- https://mvnrepository.com/artifact/org.apache.poi/ooxml-schemas -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>ooxml-schemas</artifactId>
<version>1.3</version>
</dependency>
Be sure to remove the poi-ooxml-schemas dependency from your maven pom.xml so that ooxml-schemas above takes precedence instead.

Related

Apache POI 5 and XMLBeans Classpath issues

I tried answering on the following post, but I don't have the "reputation" and really do not have time to hunt down 10 questions to answer.
Runtime Exception - POI 5 and xmlbeans
With POI 5 and XMLBeans 4 (or 5) in WebLogic server there is a classloader issue where it will try to use the underlying XMLBeans jar in the WebLogic server modules directory.
When packaging in an EAR you can use the weblogic-application.xml descriptor to override class loading with .
However, listing the POI and dependencies packages here will result in further errors.
The class SchemaTypeLoaderImpl is looking in the new (org.apache.xmlbeans.metadata) AND old (schemaorg_apache_xmlbeans) packages.
So you should also include the old package in the override list.
Now SchemaTypeLoaderImpl also tries to load the TypeSystemHolder classes using ClassLoader.getResource before it tries to look it up with Class.forName.
To fix this issue you need to prevent it from finding the old classes, as the previous package override is only giving your application bundled library priority over the underlying server libraries. It is not preventing it from finding these out of date classes and trying to load them as well.
This can be done by using for these resources.
NOTE that I am only using basic XSSFWorkbook XLS functionality!
You may need to track down other resources if you use other POI functionality.
For example the following weblogic-application.xml descriptor allows your application to use bundled POI/XMLBeans libraries and ignore the old resources.
<prefer-application-packages>
<package-name>org.apache.commons.collections4.*</package-name>
<package-name>org.apache.commons.compress.*</package-name>
<package-name>org.apache.poi.*</package-name>
<package-name>org.apache.xmlbeans.*</package-name>
<package-name>org.openxmlformats.*</package-name>
<package-name>schemaorg_apache_xmlbeans.*</package-name>
</prefer-application-packages>
<prefer-application-resources>
<resource-name>schemaorg_apache_xmlbeans/system/sXMLCONFIG/TypeSystemHolder.class</resource-name>
<resource-name>schemaorg_apache_xmlbeans/system/sXMLLANG/TypeSystemHolder.class</resource-name>
<resource-name>schemaorg_apache_xmlbeans/system/sXMLSCHEMA/TypeSystemHolder.class</resource-name>
<resource-name>schemaorg_apache_xmlbeans/system/sXMLTOOLS/TypeSystemHolder.class</resource-name>
</prefer-application-resources>

flink InputStream of class class org.apache.commons.compress.archivers.zip.ZipFile$1 is not implementing InputStreamStatistics

I was trying to load an excel into POI workbook in a Flink program. Has an error like this.
Caused by: java.lang.IllegalArgumentException: InputStream of class class org.apache.commons.compress.archivers.zip.ZipFile$1 is not implementing InputStreamStatistics.
at org.apache.poi.openxml4j.util.ZipArchiveThresholdInputStream.(ZipArchiveThresholdInputStream.java:63)
at org.apache.poi.openxml4j.util.ZipSecureFile.getInputStream(ZipSecureFile.java:147)
at org.apache.poi.openxml4j.util.ZipSecureFile.getInputStream(ZipSecureFile.java:34)
at org.apache.poi.openxml4j.util.ZipFileZipEntrySource.getInputStream(ZipFileZipEntrySource.java:66)
at org.apache.poi.openxml4j.opc.ZipPackage.getPartsImpl(ZipPackage.java:258)
at org.apache.poi.openxml4j.opc.OPCPackage.getParts(OPCPackage.java:725)
at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:275)
at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:181)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.(XSSFWorkbook.java:323)
notice a test https://github.com/apache/poi/blob/f509d1deae86866ed531f10f2eba7db17e098473/src/ooxml/testcases/org/apache/poi/openxml4j/util/TestZipSecureFile.java here that mention this. But how to work around it. Thanks!
You have to include a newer version of commons-compress and shade it (there ar different plugins in Maven, Gradle, SBT). Alternatively, you can use the HadoopOffice library, which has native Flink support, to read/write Excel files (https://github.com/zuinnote/hadoopoffice/wiki) and it has an example on how to shade the dependency correctly (see https://github.com/ZuInnoTe/hadoopoffice/wiki/Using-Apache-Flink-to-read-write-Excel-documents)

What driver are you expected to provide for Reflections.collect() to work from a Groovy script?

I have the following snippet of scratch code
import com.google.appengine.api.datastore.Entity
import org.reflections.Reflections
Reflections r = Reflections.collect()
Set<Class<?>> entities = r.getTypesAnnotatedWith(Entity.class)
print entities
that throws the following exception:
org.xml.sax.SAXException: Can't create default XMLReader; is system property org.xml.sax.driver set?
at org.xml.sax.helpers.XMLReaderFactory.createXMLReader(Unknown Source)
at org.dom4j.io.SAXHelper.createXMLReader(SAXHelper.java:83)
Googling for org.xml.sax.SAXException: Can't create default XMLReader; is system property org.xml.sax.driver set? brings up questions, mostly about Android with link only answers or code based answers that do not actually address the issue of providing the correct system property value.
The same code works as Java code from the same IDE project.
So what do I have to supply to get this to work as a Groovy script?
I have this script in the src/test/groovy in my Maven project so I added.
<dependency>
<groupId>org.apache.servicemix.bundles</groupId>
<artifactId>org.apache.servicemix.bundles.crimson</artifactId>
<version>1.1.3_2</version>
<scope>test</scope>
</dependency>
to my pom.xml
And I added -Dorg.xml.sax.driver=org.apache.crimson.parser.XMLReaderImpl to the VM Options: in the Run/Debug Configuration for the script.
This makes it work, but I would still like to know what I can used without having to add a dependency to get things in the test scope to run since things in the main scope work without this dependency.

XSSFWorkbook poi: adding image IOUtils toByteArray unfined error

To insert image to excel using POI:XSSF
I am using maven poi dependency:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.8</version>
</dependency>
AND code as :
InputStream my_banner_image = new FileInputStream("input.png");
byte[] bytes = IOUtils.toByteArray(my_banner_image);
int my_picture_id = wb.addPicture(bytes, Workbook.PICTURE_TYPE_PNG);
I am getting these errors:
1) The method toByteArray(InputStream) is undefined for the type IOUtils
2) PICTURE_TYPE_PNG cannot be resolved or is not a field
Any help would be appriciated. Thanks.
Promoting a comment to an answer:
The method you want to use is very much present in Apache POI 3.11, and you can see full details about it in the POI Javadocs.
As detailed on the POI Components page, defining a Maven dependency on poi-ooxml will pull in the main poi component jar, which is where the IOUtils class lives, so that bit is fine
What you have in this case (based on comments) is a second, older copy of POI on your classpath. You need to remove this older POI jar (or POI jars), in common with most Java projects Apache POI will only work properly if all of the POI jars are from the same version, and no old ones are present.
Because it's a fairly common problem - lots of frameworks ship old copies of POI for example - there's a POI FAQ entry on this very thing. If you can't find the old jar by hand, you can use the code given there to work out where the old jar is to remove it.
Also, one other thing to bear in mind - many many projects provide a class called IOUtils - make sure the one you have imported into your code is org.apache.poi.util.IOUtils and not something else!

How to use Apache POI to convert a .XLS into a .HTML file?

I'm trying to use the example to convert a HSSFWorkbook into a .HTML file but the example isn't working because the Maven dependency I am using does NOT contain openxml4j classes at all. Why is this... there is no explanation anywhere?
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.10-beta2</version>
</dependency>
And here is the code snippet from ToHtml.java that fails to locate classes:
public static ToHtml create(InputStream in, Appendable output)
throws IOException {
try {
Workbook wb = WorkbookFactory.create(in);
return create(wb, output);
} catch ( InvalidFormatException e){
throw new IllegalArgumentException("Cannot create workbook from stream", e);
}
}
Basically, the clases WorkbookFactory and InvalidFormatException are not located. How would I work around this? I don't know where the equivilant factory would be in the standard POI that I am using. Was there an undocumented deprecation or something?
The full list of all the different components of POI, their dependencies and their Maven Artifact IDs are given in the Apache POI Components page.
If you want to use both HSSF and XSSF (which the WorkbookFactory allows), you need to depend on poi-ooxml and not just poi.
Switch your maven dependency to poi-ooxml and it'll pull in all the required parts (including the straight poi jar), and your example code will then work
That said, you might also want to look at Apache Tika, which provides support (built on POI and others) to turn a wide range of documents into HTML (+ detect types, get metadata etc)

Resources