Val's Blog
Lots of stuff for Web 2.0 freaks and Javaholics
Feeds RSS | Atom | RDF
 
 
Chinese proverb: "Experience without learning is better than learning without experience."
[ Login ]

April 2005
SunMonTueWedThuFriSat
      1  2 
 3  4  5  6  7  8  9 
 10  11  12  13  14  15  16 
 17  18  19  20  21  22  23 
 24  25  26  27  28  29  30 
Mar  |  Today  |  May
XML Feeds   Subscribe with Bloglines

Javaranch Sheriff   My LinkedIn Profile
Drop me a line or two   Bloglines Blogroll
JavaRSS   Referers
How cool are you?   My Reviews

Next trips...
JavaOne 2009 (Jun 2-5, 09)
Top 10 entries (#hits)
(As of Nov 30, 2007)


Top 10 entries (#hits/day)
Come Back (5.032)
(As of Nov 30, 2007)
Recent Blog Entries
Recent Blog Comments
Re: Review of "Marketing Management 12th"
i know marketing management by kotler is good book but the problem is that the management part of this book is totally missing as fare as i know managemet is complete different subject and it should not be mixed i am student of MBA i was looking at ass...

Re: Review of "Pro Spring"
Using simple POJOs + factories without Spring for "echo" and "counter" would be a lot more easier. No need to write those XML files... So, in this case using Spring makes me write a lot more code... (OK, you can generate everything with the help of And...

pls urgent
Hi I am trying to generate the word doc but i m not understanding wats happening any one pls figure it out /* * WordAPI.java * * Created on May 30, 2006, 10:50 AM * * To change this template, choose Tools | Template Manager * and open the te...
Archives (# entries)
Links
Other Blogs
Other Blogs

Reviewing
Reading
Locations of visitors to this page
What they once said...
 

In a previous installment, I wrote about the problematic of effectively piloting Microsoft Word from a Java application. The solution was a little bit clumsy but it worked fine for the needs I had at that time. The idea was to create a Word template and to define bookmarks within the document that would act as anchors that could be referenced from within my Java application. Then, Java calls would be forwarded to Word using some sort of native Word wrapper accessible as a Java proxy. That's it... A couple minutes and I could generate Word documents.

Lately, I was in need of a similar solution for the Microsoft Excel application. I investigated Apache's POI project, which seemed fine at the first glance. The only problems with POI were that:

  1. you don't get any COM bridge between Java and Excel, and thus, you cannot stream data to Excel on the fly;
  2. you get OutOfMemoryErrors when the Excel document you want to build is too big because of the size of the POI object tree.
Another solution was to build a CSV file using string concatenation and then open it in Excel. I also rejected this option because of its lack of flexibility. Besides, I also wanted to generate charts on the fly using the data I was stuffing into that Excel file.

I found a cool and very powerful, yet commercial and somewhat costly, solution, called Intrinsyc's J-Integra for COM. You might wonder, "why the hell is he talking about a $200 product"? Well, $200 is not that much once you discover all the things you can do with the product. Another important thing: this is not an advertisement message, I don't have anything to do with Intrinsyc. I'm just reporting my experience. Anyway... Let's get to the real stuff...

With J-Integra's com2java utility, you can create a Java API from a COM type library that will allow you to access any COM components, such as Word, Excel and Powerpoint to cite a few. When running the com2java utility, you first select the COM type library you would like to pilot through Java and then you run the utility to generate Java proxies for the selected application. The result is a bunch of Java classes and interfaces that mimic the state, behavior and data structures that make up the chosen COM type library. For instance, when considering Excel, you get interfaces and proxy classes, such as Sheets, Charts, Workbook, Worksheet, Axis, etc... When you are done with that one-time proxy generation, you just put them on the classpath together with J-Integra's runtime and you are good to go.

Within your Java application, you can then use the generated proxies to pilot Excel and carry out any operation that can be performed using the Excel application itself since the proxies have been automatically generated from the Excel COM components, and thus, provide all functionalities available in Excel. Concretely, you can:

  • create, rename, delete workbooks;
  • create, rename, move, delete worksheets;
  • create charts;
  • handle data ranges;
  • change the font, the borders, the background color, the cell size, etc;
  • create sophisticated data tables;
  • create formulas and perform computations;
  • register event listeners to be informed of Excel events;
  • select regions and ranges;
  • etc.
You can read the whole documentation here.

Moreover, one big plus of J-Integra's COM bridge solution over Apache's POI API is that the user can interact with the Excel file while it is being generated, which means that you can get user input in real-time and handle it accordingly in your Java business logic.

For instance, initiating an interaction with Excel is as simple as the following code piece:

  excel.Application app = new excel.Application();
  excelApp.setVisible(true);

Then, you can get workbooks and create a new worksheet with the following code:
  Workbooks workbooks = app.getWorkbooks();
  Workbook workbook   = workbooks.add(null);
  Sheets worksheets   = workbook.getWorksheets();
  Worksheet sheet     = new Worksheet(worksheets.add(null, null, null, null));

Once you have a handle on the worksheet, you can easily populate values within a given range as denoted by the following code:
  Range range = sheet.getRange("B2:D4", null);
  Object[][] newValues = {
    { "Hello",           new Boolean(true),  new Double(Math.PI)},
    { new Date(),        new Long(1234567),  new Float(Math.E)},
    { new Boolean(false), "World",            new Date()}
  };
  range.setValue2(newValues);

Finally, once you are done populating your sheet, you just close the workbook and clean the environment:
  workbook.close(new Boolean(false), null, null);
  app.quit();
  com.linar.jintegra.Cleaner.releaseAll();

That's as easy as it gets, isn't it? The biggest negative point I can mention is that 80% of the method parameters in the generated Java proxy classes are of type java.lang.Object and the provided documentation doesn't say much as to what kind of object a given method is expecting as argument. To illustrate this, let's take the method we used above to add a new worksheet.
worksheets.add(null, null, null, null);
In the Worksheets class, the signature of this method is:
public Object add(Object arg1, Object arg2, Object arg3, Object arg4);
Not really self-explanatory as you can see...

If you stick with the most commonly used functionalities, you are fine as the examples provided in the documentation are good enough. But as soon as you delve into more complicated matters, such as charting, then you are in trouble. Personally, I had to browse through their knowledge base and look for articles and white papers. I also had to swim across the 9,000+ messages available in their Yahoo discussion group in order to dig out some basic information. Plus, icing on the cake, by decompiling the generated proxies I could finally infer what a given method was expecting... Not really developer-friendly, I admit, but in a matter of one day, I could create very nice and dynamic charts in Excel.

To conclude, J-Integra brings you the full power of COM right into the Java world. I would also like to mention that J-Integra not only enables Java-to-COM (i.e., C++, ATL, MFC, VB) communications but also COM-to-Java interactions, which means that your C++ and VB applications can talk to your Java programs, such as servlets, EJBs, JMS topics and queues, etc. As you can see, J-Integra allows one to join the best of both worlds into a single and homogeneous whole, which can thus benefit from COM performance and Java flexibility and elegance. Don't throw POI out of the window, though, that API is true gold as well and will probably fit many of your needs.


JNIWrapper for Windows does the same and more. It's not free but cheaper than JIntegra. I recommend it. There are a couple of posts about it in my blog's Java category.

Janek
Thanks Janek, I'll have a look at it :) Anonymous, I'm not trying to sell anything to anyone. What I wanted to express was that J-Integra offers Java developers a good solution to enable interactions with the Microsoft world without having to put their hands into the COM dirt.
This is the kind of thing you'll have a hard time selling to the old C guy you keep caged out back. And unfortunately, most shops put that clown in charge.
I dont know what Im talking about, but doesnt the 'groovy' scripting language support easy COM interop, and compile to bytecodes?
Free alternative Jacob: http://danadler.com/jacob/
One of the things I have found with jintegra and similar com based solutions. Is that in the background they are still using word, excel etc. This presents two problems. 1. I don't believe Microsoft support running word etc. in product environments like server apps. 2. These apps are designed to be interactive apps and this creates problems with automation. Occasionally you can find that you have problems opening word or excel from your application and it turns out that word is prompting the user with a modal dialog box when the word opens that prevents your application from proceeding.
I share your opinion Lionel, I have run into these modal dialog problems as well but I have made it so that they don't happen 99% of the time ;) Anonymous, thanks for the JACOB link. It's definitely a good tool but one thing I can say for sure is that I don't really like the procedural approach that is being used with the Dispatch class. In my opinion, this brings too much complexity for the task at hand... Given that we have all the typing information from the COM type library it wouldn't be too much of a hassle to create methods that take and return something else than Objects.
Hi Val, I am trying to integrate Excel into java using JIntegra's com2java utility. I have succeded in opening excel application from java, post data from JTable to excel and read data from excel to JTable. This is a one way communication, that is my java code initiates the action of posting data to excel and reading data from excel. Next what I want to do is that register some kind of listeners with generated proxies so that when a cell value is changed in excel my java code is notified and an action can be taken. I tried to delve into the code to find any event registers but couldn't succeed as the code is not self explanatory. Do you have any idea about this? And another problem which is teasing my mind is that there is a generated interface called Range which has a method called setValue2(Object rhs1). My ExcelExample java program, same as the sample code you posted above, calls this method passing a two dimensional array as parameter and the program compiles and runs perfectly. I didn't understand why the compiler did not complain about an invalid parameter to setValue2() method. Do you know what is going wrong here? Thanks, Srinivas.
Srinivas, In Java, arrays are objects, i.e. they implicitely extend from java.lang.Object as mentioned on the first two lines of chapter 10 of the JLS. That's why the compiler doesn't complain when you pass a bidimensional array where an Object parameter is expected. As for the event listeners, I'm quite sure I have seen some posts in J-Integra's Yahoo group, you should browse a little bit in there.
J-Integra for COM has an extensive KB and documentation that provides a wealth of knowledge including tons examples communicating with existing systems and applications.

Knowledge Base & Documentation:
http://j-integra.intrinsyc.com/products/com/docs.asp

We also offer free presales support via e-mail:
http://j-integra.intrinsyc.com/support/
Val, Thank you very much val. Having worked for 7 years with Java, I couldn't trace out how compiler accepted bidimensional array where an Object parameter is expected. Its shame on part. I will explore Yahoo Groups. Thanks, Srinivas.


Add a comment

Title
Body
HTML : b, i, blockquote, br, p, pre, a href="", ul, ol, li
Math Quiz 4 + 6 = (Helps stop blog spam)
Name
E-mail address
Website
Remember me Yes  No 

E-mail addresses are not publicly displayed, so please only leave your e-mail address if you would like to be notified when new comments are added to this blog entry (you can opt-out later).

TrackBack to http://radio.javaranch.com/val/addTrackBack.action?entry=1112864761792

 
About this Blog