java - 如何使用 JAVA 和 SWT OleAutomation 自动化 Open Office?

标签 java swt ole-automation

我已经成功地使用 Java 和 SWT 编写了 Microsoft Word 的自动化程序。 现在我需要为 Open Office/Libre Office writer 做同样的事情。

对于 MS Word,我使用了 Word.Application,类似于:

...
wordSite = new OleClientSite(frame, SWT.NONE, "Word.Application");
wordAutomation = new OleAutomation(wordSite);
...
wordautomation.getIDsOfNames ....

我相信这应该以与 Open Office 类似的方式完成。 我应该使用哪个对象?如何? 谢谢

编辑 1: 我试图避免提出冗长的问题,但由于我的问题被否决了,我将尝试更详细地解释它:

  1. 我的长期需求是通过 Java 小程序打开和自动化打开 office 文档
  2. 我尝试了 UNO 和 Office bean,但在我的情况下它们似乎都没有用(路径和环境设置依赖性),当您从网络浏览器启动某些东西时它们不被接受
  3. 由于我以前使用 Microsoft Word 的经验,我要求提供对象。当我使用 Word.Document 时,我可以打开文档,但自动化不起作用。当我通过 Word.Application 打开文档时,自动化确实起作用了,但它的行为不像我喜欢并想使用的 ole 对象。

目前我的代码(如下)不允许我使用自动化功能,它像 Word.Document 一样工作。

OODocument(String systemName, String fileName) {
    this.fileName = fileName;

    display = new Display();
    shell = new Shell(display);
    shell.setSize(1000, 700);
    shell.setLayout(new FillLayout());

    oleFrame = new OleFrame(shell, SWT.NONE);
    oleClientSite = new OleClientSite(oleFrame, SWT.NONE, new File(fileName));
    oleClientSite.doVerb(OLE.OLEIVERB_INPLACEACTIVATE);
    addMenu(oleFrame, systemName);
    shell.open();
    OleAutomation oleDocument = new OleAutomation(oleClientSite);
    infoLabel.setVisible(false);
    while (!shell.isDisposed()) {
        if (!display.readAndDispatch()) {
        display.sleep();
        }
    }
    oleDocument.dispose();
    display.dispose();
}

这就是我提出问题的方式:“我应该使用哪些对象”。我想找到类似于 Word.Application 的对象。应该是 com.sun.star.frame.Desktop 吗?如果是这样我还没有成功使用它。

我认为过去有人可能通过 OLe 编程 OOO 访问并可以分享一些想法或代码。

谢谢。

编辑 2 下面是 OpenOffice SDK 中的代码,用 vbs 编写。 如果有人可以帮助我将其转换为 JAVA 和 SWT,那将是解决方案:

'The service manager is always the starting point
'If there is no office running then an office is started up
Set objServiceManager= WScript.CreateObject("com.sun.star.ServiceManager")

'Create the CoreReflection service that is later used to create structs
Set objCoreReflection= objServiceManager.createInstance("com.sun.star.reflection.CoreReflection")

'Create the Desktop
Set objDesktop= objServiceManager.createInstance("com.sun.star.frame.Desktop")

'Open a new empty writer document
Dim args()  
Set objDocument= objDesktop.loadComponentFromURL("private:factory/swriter", "_blank", 0, args)

'Create a text object
Set objText= objDocument.getText

'Create a cursor object
Set objCursor= objText.createTextCursor

'Inserting some Text
objText.insertString objCursor, "The first line in the newly created text document." & vbLf, false

'Inserting a second line
objText.insertString objCursor, "Now we're in the second line", false

'Create instance of a text table with 4 columns and 4 rows
Set objTable= objDocument.createInstance( "com.sun.star.text.TextTable")
objTable.initialize 4, 4

'Insert the table
objText.insertTextContent objCursor, objTable, false

'Get first row
Set objRows= objTable.getRows
Set objRow= objRows.getByIndex( 0)

'Set the table background color
objTable.setPropertyValue "BackTransparent", false
objTable.setPropertyValue            "BackColor", 13421823

'Set a different background color for the first row
objRow.setPropertyValue "BackTransparent", false
objRow.setPropertyValue "BackColor", 6710932

'Fill the first table row
insertIntoCell "A1","FirstColumn", objTable 
insertIntoCell "B1","SecondColumn", objTable
insertIntoCell "C1","ThirdColumn", objTable
insertIntoCell "D1","SUM", objTable

objTable.getCellByName("A2").setValue 22.5
objTable.getCellByName("B2").setValue 5615.3
objTable.getCellByName("C2").setValue -2315.7
objTable.getCellByName("D2").setFormula"sum <A2:C2>"

objTable.getCellByName("A3").setValue 21.5
objTable.getCellByName("B3").setValue 615.3
objTable.getCellByName("C3").setValue -315.7
objTable.getCellByName("D3").setFormula "sum <A3:C3>"

objTable.getCellByName("A4").setValue 121.5
objTable.getCellByName("B4").setValue -615.3
objTable.getCellByName("C4").setValue 415.7
objTable.getCellByName("D4").setFormula "sum <A4:C4>"

'Change the CharColor and add a Shadow
objCursor.setPropertyValue "CharColor", 255
objCursor.setPropertyValue "CharShadowed", true

'Create a paragraph break
'The second argument is a com::sun::star::text::ControlCharacter::PARAGRAPH_BREAK constant
objText.insertControlCharacter objCursor, 0 , false

'Inserting colored Text.
objText.insertString objCursor, " This is a colored Text - blue with shadow" & vbLf, false

'Create a paragraph break ( ControlCharacter::PARAGRAPH_BREAK).
objText.insertControlCharacter objCursor, 0, false 

'Create a TextFrame.
Set objTextFrame= objDocument.createInstance("com.sun.star.text.TextFrame")

'Create a Size struct.
Set objSize= createStruct("com.sun.star.awt.Size")
objSize.Width= 15000
objSize.Height= 400
objTextFrame.setSize( objSize)

' TextContentAnchorType.AS_CHARACTER = 1
objTextFrame.setPropertyValue "AnchorType", 1

'insert the frame
objText.insertTextContent objCursor, objTextFrame, false

'Get the text object of the frame
Set objFrameText= objTextFrame.getText


'Create a cursor object
Set objFrameTextCursor= objFrameText.createTextCursor

'Inserting some Text
objFrameText.insertString objFrameTextCursor, "The first line in the newly created text frame.", _
                          false    
objFrameText.insertString objFrameTextCursor, _
                          vbLf & "With this second line the height of the frame raises.", false 

'Create a paragraph break
'The second argument is a com::sun::star::text::ControlCharacter::PARAGRAPH_BREAK constant
objFrameText.insertControlCharacter objCursor, 0 , false

'Change the CharColor and add a Shadow
objCursor.setPropertyValue "CharColor", 65536
objCursor.setPropertyValue "CharShadowed", false

'Insert another string
objText.insertString objCursor, " That's all for now !!", false      

On Error Resume Next
If Err Then
  MsgBox "An error occurred"
End If 


Sub insertIntoCell( strCellName, strText, objTable) 
    Set objCellText= objTable.getCellByName( strCellName)
    Set objCellCursor= objCellText.createTextCursor
    objCellCursor.setPropertyValue "CharColor",16777215
    objCellText.insertString objCellCursor, strText, false
End Sub

Function createStruct( strTypeName)
    Set classSize= objCoreReflection.forName( strTypeName)
    Dim aStruct
    classSize.createObject aStruct
    Set createStruct= aStruct
End Function

上面的代码,当保存到 .vbs 文件并启动时: cscript WriterDemo.vbs 启动 Open Office writer 并将一些数据写入文档。 不过我无法让它在 Java 中运行。

如果我尝试这样开始:

final String PROG_ID = "com.sun.star.ServiceManager";
display = new Display();
shell = new Shell(display);
frame = new OleFrame(shell, SWT.NONE);
writterSite = new OleControlSite(frame, SWT.NONE, PROG_ID);
writterAutomation = new OleAutomation(writterSite);

然后我得到异常

Caught: org.eclipse.swt.SWTException
Failed to create Ole Client. result = -2147221164
org.eclipse.swt.SWTException: Failed to create Ole Client. result = -2147221164
    at org.eclipse.swt.ole.win32.OLE.error(Unknown Source)
    at org.eclipse.swt.ole.win32.OleControlSite.<init>(Unknown Source)
    at office.WritterAutomation.<init>(WritterAutomation.java:39)
    at office.WritterAutomation.main(WritterAutomation.java:454)

我想我正在尝试使用错误的对象或不正确地使用它们。 感谢您的帮助。

最佳答案

没有找到解决方案。我需要简单的自动化,所以我就这样做了。

我提取 odt 文件(它是 zip),修改 content.xml 的内容并将整个结构打包回 zip。

然后我通过以下方式打开新的 zip

oleObj = new OleClientSite(oleFrame, SWT.NONE, this.fileName);
oleObj.doVerb(OLE.OLEIVERB_INPLACEACTIVATE);

我通过附加发出命令的保存菜单让用户在编辑后保存文件:

oleObj.save(fileName, true);

但是这里有一个问题。 新文档已保存,但open office/libre office无法读取!

我花了一段时间才弄清楚该怎么做。 我解压缩已经编辑并保存的文件并将其打包回 zip(没有任何更改)将扩展名更改回 odt ... 令人惊讶的是 - 文件可以读取妥妥的!

我认为所有这些解决方法都很糟糕,但至少它们有效。 我可以从我的 Web 应用程序打开任何 odt 文档,使用传递给小程序的数据自动填充模板字段的内容。然后这个填写好的文档可以由用户进一步处理并保存回网络应用....这就是我需要做的。

我没有将此食谱标记为答案,因为我坚信必须有一种方法可以通过 ole 自动化正确地完成它。

关于java - 如何使用 JAVA 和 SWT OleAutomation 自动化 Open Office?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17021818/

相关文章:

java - Uiautomatorviewer SWT 异常

Java swt IllegalArgumentException : Argument cannot be null

excel - 如何为 Excel 工作表中的顶行启用自动筛选?

Java使代理套接字多线程

java - org.hibernate.HibernateException 错误

java - JUnit 测试 SQL 查询

delphi - 如何识别Ole对象接口(interface)?

java - 使用 maven + yguard

java - SWT 按钮上的 MouseClick 事件在哪里?

vba - Excel range.Rows 属性的真正作用是什么?