读书人

核心技术:在SWT中使用OLE操纵Excel(2)

发布时间: 2009-02-01 11:33:41 作者: liuhuituzi

为Excel的A1单元格赋值
  代码:
  package com.jrkui.example.excel;
  import java.io.File;
  import org.eclipse.swt.SWT;
  import org.eclipse.swt.layout.FillLayout;
  import org.eclipse.swt.ole.win32.OLE;
  import org.eclipse.swt.ole.win32.OleAutomation;
  import org.eclipse.swt.ole.win32.OleClientSite;
  import org.eclipse.swt.ole.win32.OleFrame;
  import org.eclipse.swt.ole.win32.Variant;
  import org.eclipse.swt.program.Program;
  import org.eclipse.swt.widgets.Display;
  import org.eclipse.swt.widgets.Menu;
  import org.eclipse.swt.widgets.Shell;
  public class ExcelShell {
  public static void main(String[] args) {
  new ExcelShell().open();
  }
  public void open()
  {
  Display display = Display.getDefault();
  Shell shell = new Shell();
  shell.setSize(600,400);
  shell.setText("Excel Window");
  shell.setLayout(new FillLayout());
  //使Excel的菜单栏显示
  shell.setMenuBar(new Menu(shell,SWT.BAR));
  createExcelPart(shell);
  shell.open();
  while(!shell.isDisposed()){
  if(!display.readAndDispatch())
  display.sleep();
  }
  display.close();
  }
  /**
  * 使Excel嵌入到shell中
  * @param shell
  */
  private void createExcelPart(Shell shell)
  {
  //OleFrame实际上是一个Composite,用于放置OLE控件
  OleFrame oleFrame = new OleFrame(shell,SWT.NONE);
  //OleClientSite提供一个场所用于把OLE对象嵌入到容器中,在这里“Excel.Sheet”表示的OLE对象是Excel
  OleClientSite clientSite = new OleClientSite(oleFrame,SWT.NONE,"Excel.Sheet");
  setValueForA1Cell(clientSite);
  //OleClientSite在显示OLE对象时所做的动作,这里的动作是OLEIVERB_SHOW,显示
  clientSite.doVerb(OLE.OLEIVERB_SHOW);
  }
  /**
  * Sheet的Id
  */
  private static final int SHEET_ID = 0x000001e5;
  /**
  * 单元格的Id
  */
  private static final int CELL_ID = 0x000000c5;
  /**
  * 单元格值的Id
  */
  private static final int CELL_VALUE_ID = 0x00000006;
  /**
  * 为第一个Sheet页的A1单元格赋值
  * @param clientSite
  */
  private void setValueForA1Cell(OleClientSite clientSite)
  {
  //获得Excel的workbook对象
  OleAutomation workbook = new OleAutomation(clientSite);
  //获得workbook的第一个Sheet页
  OleAutomation sheet = workbook.getProperty(SHEET_ID,new Variant[]{new Variant(1)}).getAutomation();
  //获得Sheet页的A1单元格
  Variant cellA1Variant = sheet.getProperty(CELL_ID, new Variant[]{new Variant("A1")});
  OleAutomation cellA1 = cellA1Variant.getAutomation();
  //为A1单元格赋值
  cellA1.setProperty(CELL_VALUE_ID, new Variant("Hello OLE!"));
  //获得A1单元格的值并输出到控制台上
  System.out.println(cellA1Variant.getString());
  }
  }
  控制台输出:Hello OLE!

解释:
  <!--[if !supportLists]-->l <!--[endif]-->原理:
  <!--[if !supportLists]-->Ø <!--[endif]-->使用SWT进行OLE操作时,所有的对OLE对象的引用都是通过OlE定义的Id获得,获得各个对象的Id方法稍后会进行说明
  <!--[if !supportLists]-->Ø <!--[endif]-->所有的动作都通过OleAutomation对象进行,OleAutomation可以代表任一OLE对象,如Workbook、Worksheet、Range。可以通过getProperty()方法获得它的属性,也可以用setProperty()方法为它的属性赋值
  <!--[if !supportLists]-->Ø <!--[endif]-->Variant对象一般是封装了OLE对象的值,可以通过它进行值传入及获得相应的值,也可以通过它获得OleAutomation对象
  <!--[if !supportLists]-->Ø <!--[endif]-->如果想对单元格进行操作(如:赋值、取值),则:
  <!--[if !supportLists]-->ü <!--[endif]-->首先要取得Workbook的引用:
  OleAutomation workbook = new OleAutomation(clientSite);
  在这里OleClientSite对象就代表着Workbook对象,需要把OleClientSite转换成OleAutomation对象以便进行下一步动作
  <!--[if !supportLists]-->ü <!--[endif]-->然后需要获得第一个Sheet页的引用:
  OleAutomation sheet = workbook.getProperty(SHEET_ID,new Variant[]{new Variant(1)}).getAutomation();
  需要知道Worksheet的Id(0x000001e5),因为在OLE中获得Worksheet的方法是的返回值是一个数组,所以需要传入一个参数“1”,表示数组的第一个元素,在这里参数“1”是通 过new Variant[]{new Variant(1)}传入的
  <!--[if !supportLists]-->ü <!--[endif]-->获得A1单元格的引用:
  Variant cellA1Variant = sheet.getProperty(CELL_ID, new Variant[]{new Variant("A1")});OleAutomation cellA1 = cellA1Variant.getAutomation();
  在OLE中代表单元格的是Range:范围,可以表示一个单元格也可以表示一个单元格区域。实际上一个单元格就是一个特殊的Range, Range的Id是0x000000c5。Range是通过Worksheet获得的,需要传入的参数为字符串(用Variant进行包装),可以为一个(代表一个单元格,如new Variant[]{new Variant("A1")}),也可以为两个(代表一个单元格区域,如new Variant[]{new Variant("A1"), new Variant("D4")}),因为我们要对单元格进行赋值,所以需要获得Range的OleAutomation对象
  <!--[if !supportLists]-->ü <!--[endif]-->为A1单元格赋值:
  cellA1.setProperty(CELL_VALUE_ID, new Variant("Hello OLE!"));
  Range的值(Value)的属性的Id是0x00000006,在这里传入一个字符串作为单元格的值
  <!--[if !supportLists]-->ü <!--[endif]-->获得A1单元格的值:
  System.out.println(cellA1Variant.getString());
  取值的动作需要通过Variant对象进行,所以获得A1单元格的值就需要通过cellA1Variant对象
  <!--[if !supportLists]-->l <!--[endif]-->获得OLE对象的Id
  <!--[if !supportLists]-->Ø <!--[endif]-->微软提供一个工具OleView.exe,可列出当前机器上的所有类别信息,以及每一种类别下的组件对象列表,这个工具貌似可以从VS或VC上获得,如果没有这个工具的话也可以上网下,我下的版本在使用的时候少了一个dll库,这个也可以上网去下  
  <!--[if !supportLists]-->Ø<!--[endif]-->查找Excel的Id:
  Excel的Id在Document ObjectsàMicrosoft Excel WorkSheet项里,选中这一项可以看到有一些tab页,其中在Registry tab页中记录了该项的详细休息,一项项找,可以发现Excel在我的机子上的Id是Excel.Sheet (VersionIndependentProgID = Excel.Sheet),通过这个Id就可以使用new OleClientSite(oleFrame,SWT.NONE,"Excel.Sheet")这个方法获得Excel的引用了
  <!--[if !supportLists]-->Ø <!--[endif]-->查找Excel组件下的对象(如,WorkSheet、Range)需要打开另一个窗口ITypeLib Viewer:
  右键点击Microsoft Excel WorkSheetà选择View Type Information…  
  <!--[if !supportLists]-->Ø<!--[endif]-->获得WorkSheet(因为这个工具没有查找的功能,所以找起来有点费劲,点击Toolbar上的第二个按钮可以进行分类):
  因为WorkSheet是通过Workbook获得的(是它的一个属性),而Workbook已经通过OleAutomation workbook = new OleAutomation(clientSite)方法获得了,所以这时候我们查找WorkSheet要在Workbook中找
  <!--[if !supportLists]-->ü <!--[endif]-->找到dispinterface _Workbooks (注意:有下划线。如果使用了分类功能,在Dispinterfaces节点下)
  <!--[if !supportLists]-->ü <!--[endif]-->打开Methods节点(Methods:顾名思义,表示该对象的所有方法的集合)
  <!--[if !supportLists]-->ü <!--[endif]-->在众多Method中找到Sheets  
  可以在右边的信息框中知道,这个方法是获得一组Sheets(WorkSheet),其id是0x000001e5,是一个proget类型的方法(get类型),帮助文档的id是0x000101e5(一般用不上),方法描述是Sheets* Sheets();,没有参数
  <!--[if !supportLists]-->Ø<!--[endif]-->获得单元格也是同样的道理
  <!--[if !supportLists]-->ü <!--[endif]-->找到dispinterface _Worksheet
  <!--[if !supportLists]-->ü <!--[endif]-->找到MethodsàRange,得知:这个方法是获得一组Range对象,是一个是一个proget类型的方法(get类型),方法描述是Range* Range([in] VARIANT Cell1, [in, optional] VARIANT Cell2),这里的“in”表示传入的参数,“optional”表示这个参数是可选的,即可要可不要。
  <!--[if !supportLists]-->ü<!--[endif]-->传入的参数以单元格的location表示(如:A1,D2,E5),一个参数表示一个单元格,两个参数表示两个参数代表的单元格区域(如:A1 * D5)
  <!--[if !supportLists]-->Ø<!--[endif]-->查找单元格的Value的属性
  <!--[if !supportLists]-->ü <!--[endif]-->找到dispinterface Range
  <!--[if !supportLists]-->ü <!--[endif]-->找到MethodsàValue,这里会发现有两个Value,实际上它们的Id都是一样,但是代表不同的意思,一个是获得Range的Value属性(proget),一个是为Range的Value属性赋值(propput)
  <!--[if !supportLists]-->ü <!--[endif]-->为Value属性赋值,方法描述是void Value([in, optional] VARIANT RangeValueDataType, [in] VARIANT rhs)
  <!--[if !supportLists]-->ü <!--[endif]-->获得Value属性的值,方法描述是VARIANT Value([in, optional] VARIANT RangeValueDataType)


3COME考试频道为您精心整理,希望对您有所帮助,更多信息在http://www.reader8.net/exam/

读书人网 >JAVA认证

热点推荐