OpenOffice.org offers the possibility to load and store files using streams. For using this, all you need are two classes implementing XInputStream and XOutputStream. Additionally it seems to be important, that the class that implements XInputStream also implements XSeekable.
To get this example working, I've used the BootstrapSocketConnector from [Java solution] "no office executable found!".
I've developed this example on Windows XP using OOo 2.3.1, NetBeans IDE 6.0 and Java 1.6_04.
How-to
The first class implements XInputStream and XSeekable:
Code: Select all
package ooo.streams;
import java.io.ByteArrayInputStream;
import com.sun.star.io.BufferSizeExceededException;
import com.sun.star.io.NotConnectedException;
import com.sun.star.io.XInputStream;
import com.sun.star.io.XSeekable;
/**
* <a href="http://www.oooforum.org/forum/viewtopic.phtml?t=13205">OOInputStream from the thread <b>OOo-Java: Using XInputStream...</b></a>
*/
public class OOoInputStream extends ByteArrayInputStream implements XInputStream, XSeekable {
public OOoInputStream(byte[] buf) {
super(buf);
}
//
// Implement XInputStream
//
public int readBytes(byte[][] buffer, int bufferSize) throws NotConnectedException, BufferSizeExceededException, com.sun.star.io.IOException {
int numberOfReadBytes;
try {
byte[] bytes = new byte[bufferSize];
numberOfReadBytes = super.read(bytes);
if(numberOfReadBytes > 0) {
if(numberOfReadBytes < bufferSize) {
byte[] smallerBuffer = new byte[numberOfReadBytes];
System.arraycopy(bytes, 0, smallerBuffer, 0, numberOfReadBytes);
bytes = smallerBuffer;
}
}
else {
bytes = new byte[0];
numberOfReadBytes = 0;
}
buffer[0]=bytes;
return numberOfReadBytes;
}
catch (java.io.IOException e) {
throw new com.sun.star.io.IOException(e.getMessage(),this);
}
}
public int readSomeBytes(byte[][] buffer, int bufferSize) throws NotConnectedException, BufferSizeExceededException, com.sun.star.io.IOException {
return readBytes(buffer, bufferSize);
}
public void skipBytes(int skipLength) throws NotConnectedException, BufferSizeExceededException, com.sun.star.io.IOException {
skip(skipLength);
}
public void closeInput() throws NotConnectedException, com.sun.star.io.IOException {
try {
close();
}
catch (java.io.IOException e) {
throw new com.sun.star.io.IOException(e.getMessage(), this);
}
}
//
// Implement XSeekable
//
public long getLength() throws com.sun.star.io.IOException {
return count;
}
public long getPosition() throws com.sun.star.io.IOException {
return pos;
}
public void seek(long position) throws IllegalArgumentException, com.sun.star.io.IOException {
pos = (int) position;
}
}
Code: Select all
package ooo.streams;
import java.io.ByteArrayOutputStream;
import com.sun.star.io.BufferSizeExceededException;
import com.sun.star.io.NotConnectedException;
import com.sun.star.io.XOutputStream;
/**
* <a href="http://www.oooforum.org/forum/viewtopic.phtml?t=13205">OOInputStream from the thread <b>OOo-Java: Using XInputStream...</b></a>
*/
public class OOoOutputStream extends ByteArrayOutputStream implements XOutputStream {
public OOoOutputStream() {
super(32768);
}
//
// Implement XOutputStream
//
public void writeBytes(byte[] values) throws NotConnectedException, BufferSizeExceededException, com.sun.star.io.IOException {
try {
this.write(values);
}
catch (java.io.IOException e) {
throw(new com.sun.star.io.IOException(e.getMessage()));
}
}
public void closeOutput() throws NotConnectedException, BufferSizeExceededException, com.sun.star.io.IOException {
try {
super.flush();
super.close();
}
catch (java.io.IOException e) {
throw(new com.sun.star.io.IOException(e.getMessage()));
}
}
@Override
public void flush() {
try {
super.flush();
}
catch (java.io.IOException e) {
}
}
}
Code: Select all
package ooo.streams;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import com.sun.star.beans.PropertyValue;
import com.sun.star.comp.helper.BootstrapException;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.frame.XStorable;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.uno.Exception;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.util.XCloseable;
import ooo.connector.BootstrapSocketConnector;
public class OOoStreamConverter {
private XComponentContext xComponentContext;
public OOoStreamConverter(XComponentContext xComponentContext) {
this.xComponentContext = xComponentContext;
}
public void convert(OOoInputStream input, OOoOutputStream output, String filterName) throws Exception {
XMultiComponentFactory xMultiComponentFactory = xComponentContext.getServiceManager();
Object desktopService = xMultiComponentFactory.createInstanceWithContext("com.sun.star.frame.Desktop", xComponentContext);
XComponentLoader xComponentLoader = (XComponentLoader) UnoRuntime.queryInterface(XComponentLoader.class, desktopService);
PropertyValue[] conversionProperties = new PropertyValue[2];
conversionProperties[0] = new PropertyValue();
conversionProperties[1] = new PropertyValue();
conversionProperties[0].Name = "InputStream";
conversionProperties[0].Value = input;
conversionProperties[1].Name = "Hidden";
conversionProperties[1].Value = new Boolean(true);
XComponent document = xComponentLoader.loadComponentFromURL("private:stream", "_blank", 0, conversionProperties);
conversionProperties[0].Name = "OutputStream";
conversionProperties[0].Value = output;
conversionProperties[1].Name = "FilterName";
conversionProperties[1].Value = filterName;
XStorable xstorable = (XStorable) UnoRuntime.queryInterface(XStorable.class,document);
xstorable.storeToURL("private:stream", conversionProperties);
XCloseable xclosable = (XCloseable) UnoRuntime.queryInterface(XCloseable.class,document);
xclosable.close(true);
}
public static void main(String[] args) {
String oooExecutableFolder = "c:/program files/openoffice.org 2.3/program/";
String inputFilename = "c:/temp/text.odt";
String outputFilename = "c:/temp/text.pdf";
try {
// Connect to OOo server
XComponentContext xComponentContext = BootstrapSocketConnector.bootstrap(oooExecutableFolder);
OOoStreamConverter converter = new OOoStreamConverter(xComponentContext);
// Create OOoInputStream
InputStream inputFile = new BufferedInputStream(new FileInputStream(inputFilename));
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
byte[] byteBuffer = new byte[4096];
int byteBufferLength = 0;
while ((byteBufferLength = inputFile.read(byteBuffer)) > 0) {
bytes.write(byteBuffer,0,byteBufferLength);
}
inputFile.close();
OOoInputStream inputStream = new OOoInputStream(bytes.toByteArray());
// Create OOoOutputStream
OOoOutputStream outputStream = new OOoOutputStream();
// Convert document to PDF
converter.convert(inputStream, outputStream, "writer_pdf_Export");
// Save OOoOutputStream
FileOutputStream outputFile = new FileOutputStream(outputFilename);
outputFile.write(outputStream.toByteArray());
outputFile.close();
} catch (BootstrapException e) {
System.err.println("Connection not available");
e.printStackTrace();
} catch (IOException e) {
System.err.println("File error");
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
System.exit(0);
}
}
Credits
The idea to develop this little how-to comes from the thread OOo-Java: Using XInputStream... and from various posts in the (Unofficial) OpenOffice.org Forum asking how to handle XInputStream and XOutputStream.