· 首先你必须获取表现Excel本身的对象,有了JCOM辅助类的帮助以后,这一步操作相当直接:
ExcelApplication excel = new ExcelApplication(rm);
· 下一步,你希望获取对工作薄集合的访问权。你希望打开自己的模板工作薄(本示例中这个模板在C:\sales.xls中),在工作薄集合中打开它:
ExcelWorkbooks xlBooks = excel.Workbooks();
· 下一步,你希望打开自己的工作薄并获取该工作薄集合的引用:
ExcelWorkbook xlBook = xlBooks.Open("c:\\sales.xls");
ExcelWorksheets xlSheets = xlBook.Worksheets();
· 最后,你希望获取集合中的第一个工作表,并把工作范围定义为整个工作表:
ExcelWorksheet xlSheet = xlSheets.Item(1);
ExcelRange xlRange = xlSheet.Cells();
完成这些工作以后,你的xlRange对象将允许你在单元中放入值和公式了。通过在前面的记录集(从提交给数据库的SQL命令中返回的)中循环,使用xlRange.Item(nRow,nCol).Value("whatever")语法,逐行逐列地把记录集中的值插入到电子表格中(语法中的whatever来自于记录集)。通过使用rs.getObject(i).toString可以得到当前行中I列的值。通过使用rs.movenext(),当前行一直向后移动,直到记录集的末尾。
你在列表2中可能会注意到一个奇怪的函数调用:nCol = getExcelColumn(i);
这是一个简单的辅助函数,它把记录集中的列编号与Excel中存放数据的位置进行匹配。例如,如果你再次查看上面的SQL语句,佣金费率将返回到第8列。在电子表格中,存放它的列是第13列。这个函数用于处理两者之间的转换。更复杂的应用程序可以使用Excel中的命名(named)范围来匹配列,但是这超出了本文的范围。
最后,应用程序把公式输入适当的单元中。它是使用Excel的R1C1符号来实现的,因此相应的字符串是用于描述公式的。在Excel中,假设你希望把第1行中A列的值与B列的值相加,然后放到C列中,那么你就需要在C列中输入公式"=A1+B1"。如果在第二行你也希望这样操作,那么可以复制和粘贴这个公式,它会自动地更新为"=A2+B2"。
从示例程序中得到这些值需要一些字符串操作,但是如果使用"R1C1"相关的转换就非常直接了。在本文的例子中,你在C1中输入公式的时候,不需要给出"=A1+B1"引用,而是给出"=RC[-2]+RC[-1]"引用,它的意思是把向前两列的值与向前一列的值相加。
当你移动了其它行的时候,这个公式的值不会发生改变,因此它使我们生成程序所需要的值非常简单了。这也是我用于计算总销售额、销售税金、毛销售额和纯销售额的方法,如下所示:
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)");
请注意,这是一种比较好的工程学经验,即不要在应用程序中包含公式,因为公式可能随时改变,而你肯定不希望在改变公式的时候就去改变自己的代码。这种办法使每个新数据行成为包含公式的已有数据行的副本。模板电子表格(sales.xls)包含了假数据,并在第二列中包含了公式(第一列包含了列标题)。因此,当你填充每行的时候,在你填入数据库值的之前线复制这一行的内容。通过这种办法,公式通过复制进入了新数据行,并且你不需要在Java代码中包含任何业务逻辑。
我们看一看salesReport2.java文件中的内容,你可以发现,我们并没有使用前面所说的公式,而是在While循环顶部使用了下面的代码:
if(nRow>1)
{
String strDest="A"+(nRow+1);
ExcelRange xlRange2Copy = xlSheet.Range("A2:M2");
xlRange2Copy.Copy(xlSheet.Range(strDest));
}
除了第一行之外(第一行不需要处理,这样的信息已经包含在sales.xls中了),这段代码将处理A2到M2之间的单元,并把它们复制到nRow+1标识的数据行中(nRow是当前行的编号)。加上1的原因是计算了列标题(列标题在第一行)。
超越Excel
请记住JCOM是用于COM的而不仅仅是用于Excel的。你可以使用这种工具在Java中控制几乎所有的COM对象。Excel是最常见的被控制对象,因为有很多很好的辅助类可以让它更简单,但是所有的COM组件都是可以使用的。因此控制其它的应用程序(例如Word和PowERPoint)也是直接的。
下面是使用Word的一个例子:
IDispatch wdApp = new IDispatch(rm, "Word.Application");
wdApp.put("Visible", new Boolean(true));
由于没有用于Word的直接的辅助类,每个部分都必须通过使用IDispatch对象来实现(用于Excel的下层辅助类也是这样实现的)。上面的代码将载入微软Word副本,并通过wdApp对象使它可以自动化操作。接着你可以使用类似"put"(设置属性)或"method"(调用方法)等方法来使用Word。例如,上面的代码把Visible属性设置为true,使得该Word应用程序可视。
如果你一定要使用Windows,那么有大量的COM组件可以扩充你的视野,它的数量比Java目前提供的多很多。通过串行和并行口进行硬件控制也可以在Java中实现了,而这仅仅是个开始。在你的工具包中有了JCOM之后,就不受任何限制了。