While searching for a free solution to implement a DOC(x)-to-PDF transformation for an internal business application, I stumbled upon the org.apache.poi.xwpf.converter.* packages.
I found some examples e.g.
http://www.programcreek.com/java-api-examples/index.php?api=org.apache.poi.xwpf.converter.pdf.PdfOptions
I saw the packages starting with "org.apache.poi..." so I thought "oh great, OSS". But after further search, I realized that source code isn't coming from Apache, rather from an obscure French company I never heard of, OpenSagres: http://www.opensagres.fr/
For example http://poi.apache.org/apidocs/index.html has nothing about those packages.
I then found the matching Javadoc API: http://oss.opensagres.fr/xdocreport/javadoc/1.0.3/org/apache/poi/xwpf/converter/core/package-summary.html
...as well as source code on GitHub:
https://github.com/opensagres/xdocreport/wiki/XWPFConverterPDFViaIText org.apache.poi.xwpf.converter.pdf provides...
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>org.apache.poi.xwpf.converter.pdf</artifactId>
<version>${XDOCREPORT_VERSION}</version>
</dependency>
https://github.com/opensagres/xdocreport/wiki/XWPFConverterXHTML org.apache.poi.xwpf.converter.xhtml provides...
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>org.apache.poi.xwpf.converter.xhtml</artifactId>
<version>XDOCREPORT_VERSION</version>
</dependency>
Jars are also available (for download) inside docx.converters-xxx-sample.zip archive file, packaged (under the "libs" folder) as:
org.apache.poi.xwpf.converter.core-1.0.4.jar
org.apache.poi.xwpf.converter.pdf-1.0.4.jar
org.apache.poi.xwpf.converter.xhtml-1.0.4.jar
And when you look at the source code, there is even a copyright for The XDocReport Team e.g. see
https://github.com/opensagres/xdocreport/blob/master/thirdparties-extension/org.apache.poi.xwpf.converter.core/src/main/java/org/apache/poi/xwpf/converter/core/AbstractXWPFConverter.java
Copyright (C) 2011-2015 The XDocReport Team <xdocreport#googlegroups.com>
How is that even possible? I mean, prefixing a package from a well-known entity which releases OSS should be restricted, no?
Moreover, even if not coming from Apache, I can't use this source code/library/whatever, because:
(it) depends on iText 2.1.7 due to licensing issue(s), see: iText 5.5.0 with XDocReport 1.0.4 which should not be used anymore (but can I really trust the commenter... as he's the author of the code??? https://stackoverflow.com/users/1622493/bruno-lowagie )
there's a version with iText 5.x (https://github.com/opensagres/xdocreport/tree/master/thirdparties-extension/org.apache.poi.xwpf.converter.pdf.itext5) but it's not free! see http://itextpdf.com/Pricing
So how am I supposed to do?
Related
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.
ASM documentation (pdf) says, that Frame class has generic type, providing an example of usage: Frame<BasicValue>. (at p. 119, if needed)
When looking at the source, we can see it's declaration like Frame<V extends Value>.
But for some reason, when in my project I specify maven dependencies,
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>4.2</version>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-analysis</artifactId>
<version>4.2</version>
</dependency>
or just load according artifacts manually from repository, attempt to use Frame<...> ends with error:
Type org.objectweb.asm.tree.analysis.Frame doesn't have type parameters
And Intellij IDEA decompiler says Frame really has no ones.
The same issue takes place with Analyzer and Interpreter classes.
How can I beat that?
Complementing an answer of #dejvuth:
asm-debug-all happens to be of Java 5.0 version and contains all generic types. Morever, it's binary compatible with plain asm library with no generics
From ASM FAQ
14. What is the earliest JDK required to use ASM?
...
The asm.util and asm.tree packages require JDK 1.2, ...
and History of ASM 4.0 RC1
generified the API to use generics and varargs. However, almost all jars are still small and 1.2 compatible.
Basically, when jarred, ASM optimizes the bytecode, which (among others) makes it backward-compatible with 1.2 by changing its major version to 46 (see org.objectweb.asm.optimizer.ClassOptimizer).
I guess there are two options available: use it without generics or compile the source by yourself.
What happend:
I'm now working on a linux side-by-side installation issue since rpm no longer support to install the 32-bit and 64-bit same name packages on a machine at the same time. So I need to change the name of the 32-bit package from xxx.i386.rpm to xxx-32bit.i386.rpm. For supporting the upgrade of this package, I should provide the old package name: xxx in the spec file.
Problem:
I've looked into the pages of rpm.org looking for whether we can specify the version which we provided in the spec file like:
Provides: xxx = 16.0
I've done some test and it seems to work. But I can't find any offical explanation.
Does anyone else know the properly behaviour if I specified the provides package version in the Provides.
I'm putting aside that multilib is still supported by RPM (and I'm puzzled why are you doing that). But when i focus on that spec problem.
You have it nearly correct. Just omit that percent sign. Correct is:
Provides: xxx = 16.0
Note that the "16.0" should be just version. While it technically can be version-release, this will make you trouble some time later.
And if you want to provide really clean upgrade path, you should put there Obsolete too. See https://docs.fedoraproject.org/en-US/packaging-guidelines/#renaming-or-replacing-existing-packages
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!
I am trying to develop a simple project in Pharo, and I would like to add its dependencies in Metacello. My project depends on Glamour, Roassal and XMLSupport.
A way to cleanly install my project is to install the dependencies by hand first. Following the book Deep into Pharo one can do
Gofer new
smalltalkhubUser: 'Moose' project: 'Glamour';
package: 'ConfigurationOfGlamour';
load.
(Smalltalk at: #ConfigurationOfGlamour) perform: #loadDefault.
Gofer new smalltalkhubUser: 'ObjectProfile'
project: 'Roassal';
package: 'ConfigurationOfRoassal';
load.
(Smalltalk at: #ConfigurationOfRoassal) load.
Gofer new
squeaksource: 'XMLSupport';
package: 'ConfigurationOfXMLSupport';
load.
(Smalltalk at: #ConfigurationOfXMLSupport) perform: #loadDefault.
and then my project will work fine.
I have tried to create a ConfigurationOfMyProject using the Versionner, and I have added Glamour, Roassal and XMLSupport as dependencies, using the version that are currently installed in my image (2.6-snapshot, 1.430 and 1.2.1 respectively).
The problem is that I am not able to load my project using Metacello in a fresh image. The project loads fine, but whenever I try to load my classes I get method missing errors in Glamour. Moreover, it is apparent that something is different, because even the world menu has different entries.
I have tried other combinations of versions, including using the stable Glamour (2.1) but I have obtained more errors, including not even being able to open the project in the Versioner (it complains about a missing Roassal name).
What is the correct way to add these dependencies cleanly?
First of all I want to highlight that if configuration is in class ConfigurationOf<proj-name> you can load it as using #configuration message:
Gofer new
smalltalkhubUser: 'Moose' project: 'Glamour';
configuration;
load.
(Smalltalk at: #ConfigurationOfGlamour) perform: #loadDefault.
A I don't see your project, I can just suggest you to write configuration by hand. There is an easy tutorial called Dead simple intro to Metacello.
According to your description it should be something like:
baseline01: spec
<version: '0.1'>
spec for: #common do: [
spec blessing: #release.
spec repository: 'your repo url'.
spec
package: 'YourPackage' with: [
spec requires: #('Glamour' 'Roassal' 'XMLSupport') ].
"also maybe you have a couple of packages that depend on different projects"
spec project: 'Glamour' with: [
spec
className: 'ConfigurationOf Glamour';
repository: 'http://smalltalkhub.com/mc/Moose/Glamour/main';
version: #'2.6-snapshot' ].
spec project: 'Roassal' with: [
spec
className: 'ConfigurationOfRoassal';
repository: 'http://smalltalkhub.com/mc/ObjectProfile/Roassal/main';
version: #'1.430' ].
"and same for XMLSupport" ].
Also you can try to load #development versions, as I have an impression that projects like Roassal and Glamour have very outdated stable versions. Also please note that Roassal2 is actively developed and will replace original Roassal in Moose platform, maybe you want to consider using it.
I would seriously discourage writing configs by hand - that is the assembly code of Metacello ;) Unless you are working on cross-Smalltalk-platform projects with platform-specific code (e.g. code for Pharo 1.4 vs Squeak 4.5) - an area which hasn't been explored yet, Versionner is the tool for you. I have written dozens of configs with it and have yet to run into a roadblock.
When you say you added them as dependencies, did you just add them as projects in the "Dependent projects" pane?
If so, you also have to specify which of your project's packages depend on them. To do this, you select the relevant package of your project on the "Packages" pane.
Now, click on the edit button with the pencil icon that just became enabled. In the dialog that appears, click the green + button and add the external projects of interest.
It looks like you are trying this in an old version of Pharo?
Roassal has been superseded by Roassal2, and the support for XML is on smalltalkhub, split into ConfigurationOfXMLWriter and ConfigurationOfXMLParser, both in PharoExtras.
If you load the right groups from Glamour you don't need to describe the dependencies on Roassal, as Glamour already depends on Roassal(2). That explains your cyclic dependency.
You have also run into the problem we've recently talk about on the pharo mailing lists
that #stable is not a usable symbolic version name. In the Seaside/Magritte/Grease projects we've changed to using #'release3.1' style symbolic version names. That ensures that there is less of a ripple effect when progressing stable.
Snapshot versions should never be a dependency, they just describe what is loaded at the moment, and are basically not upgradable.
[edit]
Metacello by default tries to be smart about not installing older versions over newer. This works pretty well as long as things are not moved to different packages. So it's a bit of bad luck there that you ended up with a non-working combination.
Metacello support complex workflows, and different smalltalk projects (need to) use different workflows. It often takes some time to reach consensus on the best way to do things.
Roassal does not depend on Glamour, but you can create the cycle in your own configuration :)
Packages were moved from squeaksource to ss3 and smalltalkhub because the server had had stability problems. More recently, those problems seem to have been fixed. The xml support was split as it was noted that a lot of applications actually don't need both writing and reading of xml.
Once you have a working configuration, it might be a good idea to build and test it on the continuous integration server of pharo: http://ci.inria.fr/pharo-contribution
If not your actually application, at least the open source parts as used by you. That way the Pharo, Glamour & Roassal teams can know if a change they make breaks something.