We tried a lot of things but they were all crap solution. We had to delivery those "word" reports so the solution was pretty bad: Generate Jasper RTF and open as an Word Document.
When you open this rtf, the result is just horrible. You can't properly edit those dodge tables generated by jasper. Other problem is when you save this document as .doc, file size increased from 5 MB to 40 MB.
So... there were I again... playing around with the problem...
I decide to create an API in Java to generate Word documents from Java code. The Document generated HAS to be compatible with Microsoft Word and can't have any manipulation - so has to be ready for the end user!
I wrote two implementations: one for Word 97 - 2003 and another for Word 2004 +.
To be honest I spent more time in W2004 because this is the current standard.
I have created the java project and hosted in Google code:
http://code.google.com/p/java2word/
The philosophy is have something in Java and really easy like:
IDocument myDoc = new Document2004();
myDoc.getBody().addEle(new Heading1("Heading01"));
myDoc.getBody().addEle(new Paragraph("This is a paragraph..."));
You are Java dev and deal with this API. You Don't need to worry about the implementation!
*Project has 97% of code test coverage.
** When I say no "special" components I mean not using any MS library.
In order to use the Java2Word you will need in your classpath xstream (if you use images) and log4j (for other than JBoss server).
Please refer to dependencies section in the project page.
Hi there,
ReplyDeleteCan you tell me if there are any Javadocs available for this project and where can I find them?
Thanks!
Hey Gabriel
ReplyDeleteI didn't generate the Javadoc because I am still entering the javadoc comments on the API.
I can help you to set it up i you want.
Take a look at http://code.google.com/p/java2word/ and see if you can get around with that.
In my case, I use Maven and I build the jar locally because I couldn't find a public maven repo.
Let me know if you have any problem to play around.
cheers
Leonardo
I've built a new project in eclipse and included in its classpath your "j2w-ejb-1.0.jar". Then I've created the following simple class:
ReplyDeleteimport word.api.interfaces.IDocument;
import word.w2000.Document2000;
import word.w2000.elements.BreakLine;
import word.w2000.elements.Heading1;
import word.w2000.elements.Paragraph;
public class TestJava2Doc {
public static void main(String[] args) {
IDocument myWord = new Document2000();
myWord.getBody().addEle(new Heading1("Heading01"));
myWord.getBody().addEle(new Paragraph("This document is an example of paragraph"));
myWord.getBody().addEle(new BreakLine());
System.out.println(myWord.getContent());
}
}
When I try to run it I get:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/Logger
at word.w2000.Document2000.(Document2000.java:13)
at TestJava2Doc.main(TestJava2Doc.java:9)
Caused by: java.lang.ClassNotFoundException: org.apache.log4j.Logger
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
... 2 more
I've added to the classpath the "log4j_1.2.15.jar" jar file and got this to work.
However, on the Google Code link you mentioned it says that "There are NO third part components or libraries - only java code in one jar". Is it possible I misunderstood this as "There are no 3rd party dependencies, just add this jar to your classpath and you're good to go"? I know that this is still work in progress, however I find it to be the simplest and most straightforward way of exporting data from Java in Word format. The only question I have is if there are any othere dependencies I should be aware of when working with your library?
Thank you very much! Keep up the good work!
Thank you very much Gabriel for the feedback!
ReplyDeleteI will sort this out. I will maybe mention that we need "log4j_1.2.15.jar".
When I say we don't need third part component, I meant no Microsoft stuff... just XML(for version >= 2004) or HTML(for version < 2003).
I also see that you instantiate a Document2000. Remember to take a look at the "table of supported tags" in the project page.
The implementation for W2004 has got more components like header, footer, images...
If you are Dev and one day need to change the code, let me know and I add you as a Admin Project Member.
Thanks for your feedback!!!
You can send emails directly if you have any problem.
cheers
Leonardo
You are very welcome!
ReplyDeleteYes, I am a dev and when that day comes I will ask. :-) 'Till then, I bookmarked your project for future reference. Nice job!
All the best 2u!
Cheers!
I updated the project page with the information about log4j.
ReplyDeleteThis framework is made to work in a web application. So if you deploy in JBoss, you don't need to worry about log4j. Worse case scenario the JVM default log will be utilized.
Thanks
Leonardo
Hi,
ReplyDeleteI am getting following error while using java2word.
java.lang.UnsupportedClassVersionError: Bad version number in .class file (unable to load class word.api.interfaces.IDocument)
at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:1854)
at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:890)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1354)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1233)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Unknown Source)
at java.lang.Class.getConstructor0(Unknown Source)
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1116)
at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:809)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:129)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
at java.lang.Thread.run(Unknown Source)
Did you download the j2w-ejb-1.0.jar or compile by yourself?
ReplyDeleteWhat application server are you using?
What is your Java version?
I don't want to downgrade to java5 because java6 has been hanging around for a while and java7 is coming soon...
The pom file in the j2w-app is set to compile using java 1.6 (line 121-128):
The problem is definitely Java version of compiled classes.
If you still have the problem and if you don't mind, please open an issue in the project page and I investigate this for you. Don't forget to give all details about your environment.
Issues:
http://code.google.com/p/java2word/issues/list
Thanks for your feedback man!
cheers
Leonardo
Classes have been compiled in Java 1.6 but maybe your JAVA_HOME or JRE_HOME in your tomcat/jboss in set to Java 1.5
ReplyDeleteMore in:
http://www.mkyong.com/java/javalangunsupportedclassversionerror-bad-version-number-in-class-file/
and
http://stackoverflow.com/questions/2466828/java-lang-unsupportedclassversionerror-bad-version-number-in-class-file
Seems from code that it needs dom4j also.
ReplyDeleteHi Leonardo, you did a great job with this lib.
ReplyDeleteBut I would like to use a word template and fill it, and I didn't find the way to do this with your lib, is it possible ? it seems not but I prefer to ask, may be I missed something ... ^^
Thanks ^^.
Alex.
Hi Areku
ReplyDeleteIt is not possible to use template and I don't think will be... The framework wasn't designed for templates because the is a POI (Apache POI) that does this.
For the time being, with java2word you can build very simple documents with headings, footer, H1, paragraph, break line, images but all will take a default styling...
I will think about your problem and see if it is posible to solve...
thanks for your feedback! Take a look at POI and let me know how you go. If you tell me that POI doesn't do it then we will have to implement one!
cheers
Leonardo
Is this meant to be a library?
ReplyDeleteI ask because I find it odd that you selected the GNU license for the project.
"The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read ."
You're right. But any one who reads knows that can use/change this library anytime.
ReplyDeleteAs I said, when I created java2word it wasn't supposed to be what is is now. I just wanted to put the code in a SVN repo.
At that time, I didn't have permission to create one repo in my current company, so I decided to use google code.
I have changed the license to "GNU Lesser General Public License". Now is is clear that you can do whatever with java2word.
Btw if you really care about license and copy rights, DOC is a property format and belongs to M$.
Thanks for your feedback! Don't be afraid to give more if your feel like.
cheers
Leonardo
Hi
ReplyDeleteI use this code from your example. Can you tell me why this generates an empty Document? Thx!
IDocument myDoc = null;
try {
PrintWriter writer = new PrintWriter("C:/word2000_3.doc");
myDoc = new Document2000();
myDoc.getBody().addEle(new Heading1("Heading01"));
myDoc.getBody().addEle(new Paragraph("This document is an example of paragraph"));
myDoc.getBody().addEle(new BreakLine());
String myWord = myDoc.getContent();
writer.println(myWord);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
best regards
Thomas
I wrote a very basic unit test just to print it out:
ReplyDelete@Test
public void xxx(){
Document2000 myDoc = new Document2000();
myDoc.getBody().addEle(new Heading1("Heading01"));
myDoc.getBody().addEle(new Paragraph("This document is an example of paragraph"));
myDoc.getBody().addEle(new BreakLine());
String myWord = myDoc.getContent();
System.out.println(myWord);
}
Then I copied the output and pasted on the Web Test Application (part of the framework) and worked fine.
I have the screenshot but can't attach to the comment.
You can always make sure the method myDoc.getContent() returns/prints something.
I am not sure if you noticed but the MS Word 2000 of this framework will be removed in the version 2.0.
W2000 implementation in Java2word is very limited whereas W2004 we can implement almost everything. W2004 is XML based.
I strongly recommend you to use Document2004:
Document2004 myDoc = new Document2004();
Send me an email if you have any problem and I help you.
cheers
Leonardo
Another thing: Are you using Servlet?
ReplyDeleteBecause I can't see where you get a reference to the ServletResponse.
HI Leonardo
ReplyDeleteG8 job..
this is working fine for me...
Thankx for your sharing
Hi Leonardo,
ReplyDeleteI got a doubt that,if i want to insert an image in a td, how can i insert that?
please suggest me on this.
please correct me if i am wrong..
Hi Rajesh
ReplyDeleteI will have a look and tell you. This is definitely possible.
I am setting up a new computer and will have a look at this tomorrow or after tomorrow.
* Style Framework is out!
Leonardo
Hello Leonardo.
ReplyDeleteI´m sorry but my English is very bad. I´m Spanish.
I´m very interested in your project.
I tried java2word a standalone application. This works fine. ;-)
I´m very interested in supporting fonts, colors, lists and tables.
How is all this?
Thank you and encourage you with your project.
Holla Como estas Rrr,
ReplyDeleteAt the moment, you can apply colors to paragraphs and Headings. I will implement font very soon.
list is a bit difficult to do. Numeric is ok but with bullet points is a bit complicated... I will try again in the future.
I am still defining the Style pattern and the "Fluent Interface". When this happens, I will replicate/apply the same pattern for the other elements.
Styling Tables is down on track.
Hasta luego amigo!
Leonardo
Holla Rrr,
ReplyDeleteThis is the solution for you:
Table tbl01 = new Table();
Image img = new Image("http://www.google.com.au/intl/en_com/images/srpr/logo1w.png", ImageLocation.WEB_URL);
String [] cols = {img.getContent(), "aaa", "bbb"};
tbl01.addTableEle(TableEle.TH, cols);
This was already implemented but I had to test before I affirm anything...
cheers
Leonardo
Hi Leonardo,
ReplyDeleteThanks for your reply..
Can we have api for this?if yes please let me know.
i tried in java2word site,but i could not find that..
I couldn't find a nice way to display the Javadoc in google code. But this is possible because I have seen it before.
ReplyDeleteIf you want to have a look at the SVN you can access:
http://code.google.com/p/java2word/source/browse/#svn/trunk/j2w-ejb/docs/2.0
another good way to see what is possible is looking at the examples and also the page "Elements Reference".
This will be improved in the future...
Leonardo
Hola Leonardo!
ReplyDeleteI am delighted with this project!.
With your permission ... I've been doing some development testing to use the fonts.
The first tests (very basic) are working well, although I think the approach that I have given is not correct. Right (I guess) would mix fonts with styles.
I pass the class I developed, and an example of use, if you're serving.
Saludos!
Example of use:
---------------
FontSimple fontSimple = new FontSimple("Courier New", "Hello", FontSimple.FONT_SIZE_16);
fontSimple.setColor("C00000");
fontSimple.setColorBackgroundFill("000000");
fontSimple.setBold(true);
fontSimple.setItalic(true);
myDoc.getBody().addEle(fontSimple);
-----
Uhmmm... As I attached the Java class?
Hi Leonardo,
ReplyDeleteNice, Neat and Easy way to write MS Word files using java2word.
Your statement above for AREKU:
"The framework wasn't designed for templates because the is a POI (Apache POI) that does this."
but POI doesn't do that, even they say they are in development stages.
Can you link me to some examples/code for creating word files using java2word or POI.
That would be of great help to me.
I would like to see if I can contribute by writing some classes to add more functionality to java2word with your permission.
Please show me the path.
Thanks,
Sudheer
Hi Sudheer
ReplyDeleteThere are some examples (Struts and Seam) in:
http://code.google.com/p/java2word/source/browse/#svn/trunk/ExampleStruts
The class AllInOneAction.java in the Struts Example shows a little bit of every element of the API but this class NEEDS UPDATE because new elements have been added:
http://code.google.com/p/java2word/source/browse/trunk/ExampleStruts/JavaSource/demo/AllInOneAction.java
See the Project Page to check what is going on: http://code.google.com/p/java2word/
See the issue list to check what WILL be coming soon:
http://code.google.com/p/java2word/issues/list
cheers
Leonardo
Hey Leonardo,
ReplyDeleteI have found the example AllInOneAction.java, and was able to generate some good word doc.
Thanks a lot.
Hey Ricard,
Can I get the FontSimple.class file.
Thanks,
Sudheer
Hey Leonardo,
ReplyDeleteCan java2word can be used to read the .DOC or .DOT files.
I have a requirement like this, is this achievable using JAVA.
Can we convert a .DOT (a word template file) to a .DOC (ms word document file) programmatically by filling some values at given places.
Ex: My MS Word template file would have "Attribute Display Name: Attribute Value", a key:pair value types, the program should fill these values with the array of values I pass.
Let me know if such thing is achievable mostly in Java or C/C++.
--
Sudheer
Hi Sudheer
ReplyDeleteI have created an issue so that other people can contribute: https://code.google.com/p/java2word/issues/detail?id=14
Take a look pls. Someone has asked this before...
cheers
Leonardo
Hi
ReplyDeleteLeonardo
Gr8 job, I had requirments like admin will put rich test data in database(Html )also need to add TOC for word doc how do we do tat?
Thanks
Raghu
Hi ,Leonardo
ReplyDeleteI am using Java2word for generating word document . and seriously saying its a wonderfull and very easy api i have ever seen for generating word document . I stuck in one problem . I am adding image into my word document . But my scenario is some thing like i need to add image at particular location.
So is that any way by which i can provide X and Y cordination while inserting image . and image will at that cordinate only ...
Thanks in advance .
Jitendra
Thanks Jitendra for your feedback!
ReplyDeleteI haven't implemented image styling yet. I created an issue for this. It shouldn't be too difficult.
https://code.google.com/p/java2word/issues/detail?id=19
what you can currently do with images is change the size: width and length.
cheers
Leonardo
Java2word with Templates is out!
ReplyDeletehttps://code.google.com/p/java2word/wiki/TemplatesWithJava2word
Hi Leonardo,
ReplyDeleteI want to modify style of the table.How to do that?
It is not possible yet. There is a task to do it but it hasn't been implemented.
ReplyDeleteLeonardo,
ReplyDeleteThanks for your great code.
I have a problem following your solution for Rrr :)
When trying to instantiate Image as (to add in table):
Image img = new Image();
I get the:
The constructor Image() is undefined.
Any suggestions?
Thanks,
Blagoy
the current version you HAVE to use fluent interfaces:
DeleteImage.from_FULL_LOCAL_PATHL(...) or
Image.from_WEB_URL
Take a look at the class Image
Hi Leonardo first of all i want to thank you for your work , i'm doing a school proyect and it has been of great help.
ReplyDeleteWhile doing this proyect i have had a problem in adding text dynamically to a paragraph. By dynamically i mean that i have an array which have a different size every time i need to write the document. Whenever i'm writing the document i need all of the elements in the array to be in the same paragraph.
I have been trying to create the paragraph with ParagraphPieces, but since the Paragraph.withPieces accepts only ParagraphPieces arguments, everytime i write the elements they are in separate paragraphs.
Is there a workaround to insert text in an already set paragraph?
The paragraph will be composited by many paragraphPieces. Post the code and we have a look at it.
DeleteIm having this problem:
ReplyDeleteava.io.FileNotFoundException: build.properties (No such file or directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.(FileInputStream.java:120)
at java.io.FileInputStream.(FileInputStream.java:79)
at word.utils.TestUtils.createLocalDocument(TestUtils.java:45)
at word.utils.TestUtils.createLocalDoc(TestUtils.java:37)
at paquete.OtraPruebaJavaAWord.testJava2wordAllInOne(OtraPruebaJavaAWord.java:254)
at paquete.OtraPruebaJavaAWord.main(OtraPruebaJavaAWord.java:29)
java.io.FileNotFoundException: null/Documento Nuevo Word (No such file or directory)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.(FileOutputStream.java:194)
at java.io.FileOutputStream.(FileOutputStream.java:145)
at java.io.PrintWriter.(PrintWriter.java:218)
at word.utils.TestUtils.createLocalDocument(TestUtils.java:58)
at word.utils.TestUtils.createLocalDoc(TestUtils.java:37)
at paquete.OtraPruebaJavaAWord.testJava2wordAllInOne(OtraPruebaJavaAWord.java:254)
at paquete.OtraPruebaJavaAWord.main(OtraPruebaJavaAWord.java:29)
Exception in thread "main" java.lang.NullPointerException
at word.utils.TestUtils.createLocalDocument(TestUtils.java:64)
at word.utils.TestUtils.createLocalDoc(TestUtils.java:37)
at paquete.OtraPruebaJavaAWord.testJava2wordAllInOne(OtraPruebaJavaAWord.java:254)
at paquete.OtraPruebaJavaAWord.main(OtraPruebaJavaAWord.java:29)
Java Result: 1
I cant find a solution. I have already linked the java2word.jar to the project libraries
Copy the file build.properties.EXAMPLE to build.properties. Add it to SVN ignore list
Deletehttp://code.google.com/p/java2word/wiki/How_to_Implement_a_New_Element?ts=1327271293&updated=How_to_Implement_a_New_Element#Set_up_your_Development_Environment
Hi Leonardo,
ReplyDeleteI tried your code in struts java application it does create a word file but data in the file is not as expected. Please help me to write the static data and tables to word document.
JAVA CODE :
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException{
IDocument myDoc = new Document2004();
myDoc.addEle(Heading1.with("Heading01").create());
myDoc.addEle(Paragraph.with("This document is an example of paragraph").create());
String myWord = myDoc.getContent();
response.setContentType("application/msword");
response.setHeader("Content-disposition", "inline; filename="
+ "myWordDoc.doc");
PrintWriter writer = response.getWriter();
writer.println(myWord);
response.flushBuffer();
return null;
}
Output file prints data as below : (Due to size constrain i have not pasted entire string)
Java2word title
Created by Java2word library
java2word, word document
Leonardo Correa Leonardo Correa Leonardo Correa
Java2word, coding for fun!
1 1 2010-07-16T07:18:00Z 2010-07-
Hey can you please reply to the March 29 Post ?
ReplyDeletethis one right: "Mar 29, 2012 02:09 AM".
ReplyDeleteI can see that you are not specifying charset:
response.setContentType("application/msword; charset=UTF-8");
Take a look at the working examples:
http://code.google.com/p/java2word/source/browse/trunk/j2w-webtest/src/main/java/java2word/actions/Testing.java
or
http://code.google.com/p/java2word/source/browse/trunk/ExampleStruts/JavaSource/demo/AllInOneAction.java
Code is not pretty but it works well. This 2 examples are in Struts2. Your code looks like Struts1.
If you still can't get this to work, send me an email with the file and code. Then I look with more time.
cheers
Leonardo
Hi Leonardo,
ReplyDeleteI am trying a standalone example as what Thomas used :
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import word.api.interfaces.IDocument;
import word.w2004.Document2004;
import word.w2004.elements.BreakLine;
public class idoc {
public static void main(String[] args) {
IDocument myDoc = null;
try {
PrintWriter writer = new PrintWriter("C:/word2004.doc");
myDoc = new Document2004();
myDoc.getBody().addEle("Hello");
myDoc.getBody().addEle(new BreakLine());
String myWord = myDoc.getContent();
writer.println(myWord);
System.out.println("word is "+myWord);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
In the example, the file is written with the content. But when I open the file with MS-WORD 2007 it shows a blank page, when I open the doc in any text editor it does have the content.
Would be great if I get support from you.
don't use getBody(). it has been deprecated so long ago. Use addEle().
ReplyDeleteSee the examples on http://java2word.blogspot.com.au/p/all-in-one-example.html
Btw this doesn't work: myDoc.getBody().addEle("Hello")
You have to pass e IElement or the XML String representation of an element.
Leonardo
How do I add a line break inside a paragraph ? I want to have a paragraph which is a list of strings written on different lines.
DeleteThanks.
try: paragraph.with( "first line: " + BreakLine.create().getContent + "after break");
DeleteI havent tried this code so you may need to adjust the name of methods. However the idea is be able to add elements inside elements however you like. If MS word will like it in all cases, it is a different story.
cheers
Leonardo
Hi leonardo,
ReplyDeleteI have used your j2w-ejb-1.0.jar for creating word document 2003. It is working fine and very useful.
But I am facing one issue which I would like to bring it to your notice so that you can provide a solution to the issue.
Issue
On clicking the Export button my code generates a word document with data populated in it. The problem occurs in the nth(4th or 5th) time when
I close the word document and open the document. At the time of issue, the document is not getting opened and the browser triggers an action which
goes in to an infinite loop and nothing happens.
I sent Mail to your mail-id along with sample code.
Hi Leonardo Correa ,
ReplyDeletecan you please help me to export inline comments in java file to word document ???... thanks