Как автоматизировать Open Office с помощью JAVA и SWT OleAutomation?
Я успешно запрограммировал автоматизацию Microsoft Word с помощью Java и SWT. Теперь мне нужно сделать то же самое для писателя Open Office / Libre Office.
В случае MS Word я использовал Word.Application, что-то вроде этого:
...
wordSite = new OleClientSite(frame, SWT.NONE, "Word.Application");
wordAutomation = new OleAutomation(wordSite);
...
wordautomation.getIDsOfNames ....
Я считаю, что это должно быть сделано аналогичным образом с Open Office. Какой объект (ы) я должен использовать? И как? Спасибо
РЕДАКТИРОВАТЬ1: Я пытался избежать создания длинного вопроса, но так как мой вопрос опущен, я попытаюсь объяснить его более подробно:
- Моя долгосрочная потребность - открыть и автоматизировать документ open office с помощью Java-апплета.
- Я пробовал UNO и Office bean, но оба они кажутся бесполезными в моем случае (зависимость от пути и параметров среды), которые не принимаются при запуске чего-либо из веб-браузера
- Я запросил объекты из-за моего предыдущего опыта работы с 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? Если так, то мне пока не удалось его использовать.
Я думал, что в прошлом можно было запрограммировать доступ OOO через OLe и поделиться некоторыми идеями или кодом.
Спасибо.
РЕДАКТИРОВАТЬ 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, а некоторые данные записываются в документ. Я не могу заставить его работать в 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)
Я предполагаю, что я пытаюсь использовать неправильные объекты или использовать их ненадлежащим образом. Спасибо за вашу помощь.
2 ответа
Хотя уже слишком поздно, чтобы ответить на этот вопрос, но недавно я искал такое же решение. Я обнаружил, что мы можем использовать следующую строку кода, чтобы открыть OpenOffice. Надеюсь, что это помогает другим...
clientSite = new OleClientSite (frame, org.eclipse.swt.SWT.NONE, "opendocument.WriterDocument.1");
Не нашел решения. Мне нужна была простая автоматизация, поэтому я так и делаю.
Я извлекаю файл odt (это zip), изменяю содержимое файла content.xml и упаковываю всю структуру обратно в zip.
Затем я открываю новый почтовый индекс через
oleObj = new OleClientSite(oleFrame, SWT.NONE, this.fileName);
oleObj.doVerb(OLE.OLEIVERB_INPLACEACTIVATE);
Я позволил пользователю сохранить файл после того, как он был отредактирован, добавив меню сохранения, которое выдает команду:
oleObj.save(fileName, true);
Однако здесь есть одна проблема. Новый документ сохранен, но открытый офис / офис libre не может его прочитать!
Мне потребовалось время, чтобы понять, что делать. Я распаковал уже отредактированный и сохраненный файл и упаковал его обратно в zip (без каких-либо изменений), изменил расширение обратно на odt... и что удивительно - файл можно прочитать правильно!
Я бы назвал все эти обходные пути неприятными, но, по крайней мере, они работают. Я могу открыть любой документ odt из своего веб-приложения, автоматически заполнить содержимое полей шаблона данными, переданными в апплет. Затем этот заполненный документ может быть далее обработан пользователем и сохранен в веб-приложении.... и это то, что мне нужно было сделать.
Я не отмечаю этот рецепт как ответ, потому что я твердо верю, что должен быть способ сделать это должным образом с помощью автоматизации OLE.