访问表格,保存Excel文件,Java,Java Com Bridge(Jacob jacob-1.16)

时间:2012-01-09 16:18:38

标签: java jacob

我查看了最新版Java Com Bridge(jacob-1.16)的附带Excel示例,并且有点失望,因为它创建并处理全新的Excel文件。

我想要做的是访问Java中的现有Excel文件,在本例中名为“JACOBWithExcel.xls”,但任何Excel文件都应该没问题。

Excel的SourceForge示例在我的机器上正常工作,当我修改它以访问现有的Excel文件时,我遇到了以下问题:

1.我无法在工作簿中获得现有工作表,即使我正在尝试    我得到工作簿的方式相同:

Dispatch sheet = Dispatch.get(workbook, "Worksheets").toDispatch();  
Dispatch.call(sheet, "Select", new Object[]{"Sheet2"}).toDispatch();

此代码将生成以下异常:     com.jacob.com.ComFailException:无法将名称映射到dispid:Worksheets

2 .;无法保存工作簿:

// Save the open workbook as "C:\jacob-1.16-M1\Test1.xls" file:
Dispatch.call(workbook, "SaveAs", new Variant("C:\\jacob-1.16-M1\\Test1.xls"),new   Variant("1"));

此代码将生成以下异常:     com.jacob.com.ComFailException:无法将名称映射到dispid:SaveAs

3 .;我不知道如何开始使用以下简单但非常常见的Excel操作,就Java COM桥的Java语法而言:

(此处包含我尝试在Java中实现的Excel VBA代码)

选择单个细胞:     范围( “A4”)。选择

将所选范围复制到剪贴板:

Selection.Copy

选择要复制到的多单元格范围:

Range("D9:D17").Select

将剪贴板内容粘贴到选择中:

ActiveSheet.Paste

重命名工作表:

Sheets("Sheet2").Select
Sheets("Sheet2").Name = "MySheet2"

格式化单元格,文本示例:

Selection.NumberFormat = "@"

删除行:

Rows(intI).Select
Selection.Delete Shift:=xlUp

可能......

对选择进行排序:

Selection.Sort Key1:=Range("A2"), Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False,  Orientation:=xlTopToBottom

找到工作表中的最后一个单元格:

ActiveSheet.Cells(65536, 1).End(xlUp).Select
intLastCellRow = Selection.Row

感谢您的帮助。

P.S:

申请表的完整代码:

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;

public class TestJACOBWithExcel {
public static void main(String[] args) {

String strInputDoc = "C:\\jacob-1.16-M1\\JACOBWithExcel.xls";  // file to be opened.

ComThread.InitSTA();

ActiveXComponent xl = new ActiveXComponent("Excel.Application"); // Instance of application object created.

try {
// Get Excel application object properties in 2 ways:
System.out.println("version=" + xl.getProperty("Version"));
System.out.println("version=" + Dispatch.get(xl, "Version"));

// Make Excel instance visible:
Dispatch.put(xl, "Visible", new Variant(true));

// Open XLS file, get the workbooks object required for access:
Dispatch workbook = xl.getProperty("Workbooks").toDispatch();
Dispatch.call(workbook, "Open", new Variant(strInputDoc),new Variant("1"));

Dispatch sheet = Dispatch.get(workbook, "Worksheets").toDispatch();
Dispatch.call(sheet, "Select", new Object[]{"Sheet2"}).toDispatch();

// put in a value in cell A22 and place a a formula in cell A23:
Dispatch a22 = Dispatch.invoke(sheet, "Range", Dispatch.Get, new Object[] { "A22" }, new int[1]).toDispatch();

Dispatch a23 = Dispatch.invoke(sheet, "Range", Dispatch.Get, new Object[] { "A23" }, new int[1]).toDispatch();

Dispatch.put(a22, "Value", "123.456");
Dispatch.put(a23, "Formula", "=A22*2");

// Get values from cells A1 and A2
System.out.println("a22 from excel:" + Dispatch.get(a22, "Value"));
System.out.println("a23 from excel:" + Dispatch.get(a23, "Value"));

// Save the open workbook as "C:\jacob-1.16-M1\Test1.xls" file:
Dispatch.call(workbook, "SaveAs", new Variant("C:\\jacob-1.16-M1\\Test1.xls"),new Variant("1"));

// Close the Excel workbook without saving:
Variant saveYesNo = new Variant(false);
Dispatch.call(workbook, "Close", saveYesNo);

} catch (Exception e) {
e.printStackTrace();
} finally {

// Quit Excel:
// xl.invoke("Quit", new Variant[] {});
ComThread.Release();
}

}
}

2 个答案:

答案 0 :(得分:0)

HY,

实际上我现在只能回答你的第一个问题。我使用此代码,它正确地用于* .xltx模板文件:

File file = new File("pathToOurTemplate");
ActiveXComponent excel = null;
  ComThread.InitSTA();
  try {
    excel = new ActiveXComponent("Excel.Application");
    Dispatch excelObject = excel.getObject();
    Dispatch workbooks = excel.getProperty("Workbooks").toDispatch();
    Dispatch workbook = Dispatch.call(workbooks, "Add", file.getAbsolutePath()).toDispatch();
} catch (...) 
//...

至少适用于Office 2010,Java6_u23,Jacob 1.15_M4

希望这有助于第一次拍摄/这比您在示例中显示的更多(猜测你看了一下)。

答案 1 :(得分:0)

免责声明:在这个答案中,我将使用双引号来提供MS Excel对象属性,方法和对象类型,以避免一些混淆。我对这个问题的回答如下。

您好,

了解excel API具有的层次结构非常重要。并且还搜索每个层次结构级别上可用的方法,属性或事件类型。我现在要回答你的问题。

在问题1中,您说您无法打开正确的工作表,因为您正在获取财产"工作表"在错误的对象类型上。在您的代码段中

Dispatch sheet = Dispatch.get(workbook, "Worksheets").toDispatch();
Dispatch.call(sheet, "Select", new Object[]{"Sheet2"}).toDispatch();

你获得财产"工作表"对于#34; Workbooks"类型的对象,这是不正确的。 这份文档https://msdn.microsoft.com/EN-US/library/office/ff841074.aspx显示了"工作簿"没有财产"工作表"。问题在于你如何打开混凝土"工作簿"对象

Dispatch workbook = xl.getProperty("Workbooks").toDispatch();
Dispatch.call(workbook, "Open", new Variant(strInputDoc),new Variant("1"));

你打电话给方法"打开"在"工作簿"对象,根据doc有这个方法,它为你打开MS Excel。问题是可变的"调度工作簿"仍然是#34;工作簿"类型的对象而不是"工作簿",你错误地认为。正确的方法是保存" Open"的回报价值。方法调用,它为您提供具体的工作簿"对象以及之后使用可用于该类型对象的方法。正好遵循MS文档https://msdn.microsoft.com/en-us/library/office/ff194819.aspx

打开具体工作表的正确方法如下:

//get "Workbooks" property from "Application" object
Dispatch workbooks = xl.getProperty("Workbooks").toDispatch();
//call method "Open" with filepath param on "Workbooks" object and save "Workbook" object
Dispatch workbook = Dispatch.call(workbooks, "Open", new Variant(strInputDoc)).toDispatch();
//get "Worksheets" property from "Workbook" object
Dispatch sheets = Dispatch.get(workbook, "Worksheets").toDispatch();
//Call method "Select" on "Worksheets" object with "Sheet2" param   
Dispatch.call(sheets, "Select", new Object[]{"Sheet2"}).toDispatch();
//probably again save "Worksheet" object and continue same way

问题2与问题1中的问题相同。

//calling method "SaveAs" on "Workbooks" object instead of "Workbook" type
Dispatch.call(workbook, "SaveAs", new Variant("C:\\jacob-1.16-M1\\Test1.xls"),new   Variant("1"));

所有其他问题与之前的两个问题完全相同。获取正确MS对象的属性或调用方法。也不能给人留下足够的压力,MS文档对于任何拥有java-excel通信的人来说有多重要。

仅提一个例子,如何从某些MS对象中获取实际值。让我们说你想要内部的价值观"范围"对象,因为获取需要参数的对象的属性与正常值属性有点不同。要做到这一点,你需要进入"工作表"先对象然后得到"范围"该财产。

//lets say we have already some "Worksheet" object
Dispatch worksheet = ...;
//we want a property "Range" of "Worksheet" object with some macro
Variant range = Dispatch.invoke(worksheet, "Range", Dispatch.Get, new Object[]{"A1:L10"}, new int[1]);
//according to docu, you can specify format in which the value is returned
//im using 12 which is one of XML formats available
//in case no such param is provided default "textTable" format is returned
Variant value = Dispatch.invoke(range.getDispatch(), "Value", Dispatch.Get, new Object[]{12}, new int[1]);
//and get the value from it and you are done with MS Excel-Java communication
String xmlFormat = value.toString();



Worksheet.Range property docu:
msdn.microsoft.com/en-us/library/office/ff836512.aspx
Range.Value docu:
msdn.microsoft.com/en-us/library/office/ff195193.aspx

我不允许发布超过2个链接,所以我很抱歉,如果这些链接无法正常工作。