我查看了最新版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();
}
}
}
答案 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个链接,所以我很抱歉,如果这些链接无法正常工作。