|
|
|||||||||||||||||||||||||||||||||||||||||||||
Krishnan Viswanath's Blog
Open Office Java APIPosted by tchangu on December 30, 2005 at 06:20 AM | Permalink | Comments (0)When I worked for a consulting firm I got an opportunity to work on a Strategy & Operations pursuit. The task was to fill up a 20 page MS Word report template with lots of data from MS Access and Oracle (which was backend to some ERP system). The requirement was to produce 10 or so reports quickly, which showed the client how the firm can help them to define a strategic sourcing model followed by a transformation roadmap. Not being a fluent VB Scripter, I was totally frustrated trying different things - manually plugging in data, patchy VB Scripting, Apache POI - but nothing worked satisfactorily. Finally after looking around, I ended up discovering OpenOffice UNO Java API (Universal Network Objects). After going through an initial ramp, it worked out pretty good. With OO UNO and JDBC, ugly and complex reporting became a breeze! Open Office UNO API is pretty involved in concept and is complex as well. Of course it’s pretty powerful and can do much more than what I made use of. However, there is very little general documentation like articles etc available online. But Sun’s Developer's guide and supplied samples is very good. For starters here is some code that helped me going. First - Read an existing document, and this can be accomplished by
// get the remote office component context
xContext = com.sun.star.comp.helper.Bootstrap.bootstrap();
System.out.println("Connected to a running office ...");
// Get the remote office service manager
XMultiComponentFactory xMCF = xContext.getServiceManager();
// Get the root frame (i.e. desktop) of openoffice framework.
Object oDesktop = xMCF.createInstanceWithContext("com.sun.star.frame.Desktop", xContext);
// Desktop has 3 interfaces. The XComponentLoader interface provides ability to load
// components.
XComponentLoader xCompLoader = (XComponentLoader)
UnoRuntime.queryInterface(com.sun.star.frame.XComponentLoader.class, oDesktop);
// URL of the component to be loaded
String sUrl = "file:///[file name]";
// Load the document, which will be displayed. More param info in apidoc
XComponent xComp = xCompLoader.loadComponentFromURL(sUrl, "_blank", 0, new PropertyValue[0]);
// Get the textdocument
XTextDocument aTextDocument = (XTextDocument)UnoRuntime.queryInterface(
com.sun.star.text.XTextDocument.class, xComp);
Now that we have text document we can manipulate in how ever manner we want. In my particular case, I had to deal with data that were in tables. This was accomplished by
// Query the XTextTablesSupplier interface from our document
XTextTablesSupplier xTablesSupplier = (XTextTablesSupplier) UnoRuntime.queryInterface(
XTextTablesSupplier.class, aTextDocument );
// Get the tables collection
XNameAccess xNamedTables = xTablesSupplier.getTextTables();
// Query the XIndexAccess from the tables collection
XIndexAccess xIndexedTables = (XIndexAccess) UnoRuntime.queryInterface(
XIndexAccess.class, xNamedTables);
for (int i = 0; i < xIndexedTables.getCount(); i++) {
Object table = xIndexedTables.getByIndex(i);
XTextTable xTable = (XTextTable) UnoRuntime.queryInterface(
XTextTable.class, table);
// Getting Table Rows
XTableRows xRows = xTable.getRows();
// Getting the right Table Cell (Hard Coded as B2).
XText xCellText = (XText) UnoRuntime.queryInterface (
XText.class, xTable.getCellByName ( "B2" ) );
// Make JDBC calls. Perform data tranformation and set it
xCellText.setString("Hello Worlds");
}
The final task after all the transformation has been performed is to save the document.
// URL where the document is to be stored String storeUrl = "file:///Test_97.rtf"; XStorable xStorable = (XStorable)UnoRuntime.queryInterface(XStorable.class, aTextDocument); PropertyValue[] storeProps = new PropertyValue[1]; storeProps[0] = new PropertyValue(); storeProps[0].Name = "FilterName"; storeProps[0].Value = "Rich Text Format"; xStorable.storeAsURL(storeUrl, storeProps);Of course the document could be sent to the printer as well. Here is the code to do that XPrintable xPrintable = (XPrintable)UnoRuntime.queryInterface(XPrintable.class, aTextDocument); PropertyValue[] printerDesc = new PropertyValue[1]; printerDesc[0] = new PropertyValue(); printerDesc[0].Name = "Name"; printerDesc[0].Value = "PDFCreator"; xPrintable.setPrinter(printerDesc); PropertyValue[] printOpts = new PropertyValue[1]; printOpts[0] = new PropertyValue(); printOpts[0].Name = "Pages"; printOpts[0].Value = "1"; xPrintable.print(printOpts);Enjoy! Dealing with Command Line ParametersPosted by tchangu on December 19, 2005 at 09:43 AM | Permalink | Comments (5)One of the things that keep popping up often is a need to write batch programs that is started from command line. Every single time its always been either reinvent the wheel or copy/paste from old code. So recently decided to put an end to this practice by looking at CLI solution from Apache. But one could externalize this in a XML by hiding the plumbing of CLI that deals with verbosity. A simple framework around CLI framework would do this trick and this means a developer who wants to use CLI would write this simple XML Better yet, Commons Configuration could be used to implement something similar! too... |
December 2005
Search this blog:ArchivesRecent EntriesDealing with Command Line Parameters ArticlesThe New RMI Robotics: Using Lego Mindstorms and Java All articles by Krishnan Viswanath » | ||||||||||||||||||||||||||||||||||||||||||||
|
|