技术开发 频道

Java中使用JCOM操作Office对象

【IT168技术文档】

  通过使用COM技术,我们用微软Office应用程序能够建立很多应用程序扩展,但是Java开发人员却无法享受它带来的便利--除非他们拥有方便的Java访问COM的途径(Java-to-COM桥)。使用JCom的时候,你可以在Java中控制几乎所有的COM对象,而且它还带有一些用于Excel的强大的辅助类。
 
  在你每次编写用HTML表格样式或Java表格对象显示数据的应用程序的时候,通常都需要带有"导出到Excel"功能。那么头疼的问题就出现了。怎么样实现这种功能呢?在HTML中显示的可以在Office 2003中处理吗?没有这么好!你还必须支持Office 97!
 
  你只能去找一个符合当前需求的工具了,但是接着收到更多的要求了。"这能在Word中做到吗?PowERPoint能做到吗?能不能用调制解调器拨号到远程服务器上并发布数据?Java无法实现这些功能是什么意思啊?Java可以实现任何功能。"
 
  感谢作为Java和COM桥梁的框架组件,它使你在遇到这些情况的时候都可以回答"Yes"。Java-COM桥梁使你能够根据自己的需要操作Windows组件--以前这是VB、C++和.net开发人员的领地。你通过实现一个与DCOM后端(back end)对话的Java前端(front end),可以远离端对端(end-to-end)的COM系统。在本文的末尾,你可以使用其中一个Java-to-COM桥:它可以被命名为JCom。
 
Excel基础知识
 
  开始之前,你需要首先从Sourceforge网站下载API。它包含了JCom所使用的Java类的所有源代码、C++代码和JCom用于配置Java和COM的编译好的DLL。把这个DLL放到你的Java主目录的/bin/目录下面,否则会出现问题。同时,为了不出现问题,还要正确地设置JAVA_HOME环境变量。JCom的大多数文档目前都是用日语写的,但是翻译工作正在进行中,因此以后会有些改进的。
 
  下载和安装过程完成以后,用列表1中的代码试一试。这段代码会建立到Excel的JCom接口,并把"Hello World"写入第一个单元格中。尽管JCom是一个通用的COM类库,但是还是带有很多用于Excel的辅助类,这是因为Excel可能是最常用的自动化COM应用程序。这些辅助类可以为我们节省很多时间,它们使JCOM成为一个更好的类库了。

  列表1:开始使用JCOM和Excel

import jp.ne.so_net.ga2.no_ji.jcom.excel8.*; import jp.ne.so_net.ga2.no_ji.jcom.*; public class testSimple { public static void main(String[] args) throws Exception { ReleaseManager rm = new ReleaseManager(); try { System.out.println("EXCEL is Starting..."); ExcelApplication excel = new ExcelApplication(rm); excel.Visible(true); ExcelWorkbooks xlBooks = excel.Workbooks(); ExcelWorkbook xlBook = xlBooks.Add(); ExcelWorksheets xlSheets = xlBook.Worksheets(); ExcelWorksheet xlSheet = xlSheets.Item(1); ExcelRange xlRange = xlSheet.Cells(); xlRange.Item(1,1).Value("Hello, World!" ); } catch(Exception e) { e.printStackTrace(); } finally { rm.release(); } } }
  如果曾经使用VB或VBA来自动化Excel,那么你应该很熟悉列表1中的代码了。ExcelApplication类暴露了Workbooks()属性,它列举出Excel中当前打开的工作薄(workbook),并允许你向运行的Excel副本增加或删除工作薄。使用.Add()方法增加工作薄,这个方法会返回一个工作薄的引用。
 
  在Excel中工作薄用于保存输入的数据。工作薄是XLS文件的基础。一个工作薄由多个工作表(worksheet,在图1中有三个工作表,分别叫做Sheet1、Sheet2和Sheet3)。工作表通过Item属性来枚举。你可以使用这个属性访问特定的工作表。
 
  有了工作表之后,你就可以使用range(范围)来操作它上面的数据。Range是一个单元格或多个单元格。例如,单元格A1可以使用range (1,1)来引用,接着可以使用Value属性把数据载入单元格中。
 
更有意义的例子
 
  假设你希望把Excel作为数据库中某些数据的表现层。在Java中你希望通过JDBC获取数据,并把数据显示在Excel前端。这种假设是很好的,因为复杂业务逻辑中的用例(use case)已经用Excel前端显示了,更不用说工作流中的其它的数据项的显示和交互操作了。现在你不需要了解业务逻辑或分析,就可以使用原始的电子表格,并使用Java中的自动化来"填充它们之间的裂痕"。
 
  我将给出一个演示这种操作的简单示例:本文下载中所包含的内容是建立比较销售行为的一个简单的MySQL数据库的。它有三个表:
 
  · Sales是销售的细节信息,包括销售项、数量、销售价格、是谁销售的以及销售地区。
 
  · People包含销售人员的姓名和佣金。
 
  · Districts包含了销售地区的名称和税率。
 
  生成报表的时候,你需要使用下面的业务逻辑来算出真正的数值:
 
  · 毛销售额等于销售项乘以销售价格加上地税金额。
 
  · 纯销售额等于毛销售额减去销售人员提取的税前佣金。
 
  这都是一些在Java中可以实现的简单直接的计算过程,但是我在本文中使用它们的目的是演示如何把这些数据写入Excel电子表格并让Excel自动计算。对于更复杂的情况(使用了更复杂的Excel公式),原理也是一样的。
 
  使用JCOM的时候,查询数据库中所有销售数据需要使用下面的SQL:
SELECT sales.id, sales.description, sales.quantity,
sales.price, districts.districtname,
districts.salestax,people.name,people.commission
FROM 'sales','districts','people' WHERE (sales.district = districts.id) AND (sales.salesperson = people.id)
  接着使用自动化(automation)把每条记录都写入Excel电子表格的适当的列中。下载的内容中包含了完整的代码(列表2所示)。在下面的部分,我将为你解释代码中使用JCOM的自动化部分。
 
  列表2:从数据库中获取数据并载入Excel中的代码
// 首先建立Excel的引用 ExcelApplication excel = new ExcelApplication(rm); // 使它可视 excel.Visible(true); // 接着打开我们将使用的模板工作薄 ExcelWorkbooks xlBooks = excel.Workbooks(); ExcelWorkbook xlBook = xlBooks.Open("c:\\sales.xls"); // 接着获取我们将修改的范围的引用 ExcelWorksheets xlSheets = xlBook.Worksheets(); ExcelWorksheet xlSheet = xlSheets.Item(1); ExcelRange xlRange = xlSheet.Cells(); … // 此处放置数据库链接和查询建立代码 if (stmt.execute(strSql)) {  rs = stmt.getResultSet(); } int nColCount = rs.getMetaData().getColumnCount(); int nRow=1; int nCol=0; // 在记录集中循环 while(rs.next()) {  // 记录集中的每行都是电子表格中的一行  nRow++;  for(int i=1;i<=nColCount;i++)  {   // 匹配DB列和电子表格列   nCol = getExcelColumn(i);   // 查找于行和列对应的单元格,并把它设置为适当的记录集字段   xlRange.Item(nRow,nCol).Value(rs.getObject(i).toString());  }  // 填入公式  xlRange.Item(nRow,7).Value("=RC[-2]*RC[-1]");  xlRange.Item(nRow,9).Value("=RC[-2]*RC[-1]/100");  xlRange.Item(nRow,10).Value("=RC[-3]+RC[-1]");  xlRange.Item(nRow,11).Value("=RC[-4]*((100-RC[2])/100)"); }
  在列表2的第一部分中,其目标是获取希望修改的单元格的控制权。这会花费了一定的开销。

 

0
相关文章