blob: 50eb276176dd701b33fdf21153126f9abbce13ca [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
package org.apache.openoffice.poi.filter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URI;
import java.net.URISyntaxException;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import com.sun.star.beans.PropertyValue;
import com.sun.star.container.XIndexAccess;
import com.sun.star.container.XNamed;
import com.sun.star.document.XExporter;
import com.sun.star.document.XFilter;
import com.sun.star.io.XOutputStream;
import com.sun.star.lang.IllegalArgumentException;
import com.sun.star.lang.IndexOutOfBoundsException;
import com.sun.star.lang.WrappedTargetException;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XServiceInfo;
import com.sun.star.lib.uno.adapter.XOutputStreamToOutputStreamAdapter;
import com.sun.star.lib.uno.helper.ComponentBase;
import com.sun.star.sheet.XCellRangeAddressable;
import com.sun.star.sheet.XSheetCellCursor;
import com.sun.star.sheet.XSpreadsheet;
import com.sun.star.sheet.XSpreadsheetDocument;
import com.sun.star.sheet.XSpreadsheets;
import com.sun.star.sheet.XUsedAreaCursor;
import com.sun.star.table.CellContentType;
import com.sun.star.table.CellRangeAddress;
import com.sun.star.table.XCell;
import com.sun.star.text.XTextRange;
import com.sun.star.uno.AnyConverter;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
public class ExcelFilter extends ComponentBase implements XServiceInfo, XExporter, XFilter {
private static String[] services = new String[] {
"com.sun.star.document.ExportFilter"
};
private XComponentContext componentContext;
private XComponent document;
public ExcelFilter(XComponentContext componentContext) {
this.componentContext = componentContext;
}
public static String[] getSupportedServiceNamesStatic() {
return services.clone();
}
// XComponent:
@Override
protected synchronized void postDisposing() {
componentContext = null;
}
// XServiceInfo:
@Override
public String getImplementationName() {
System.out.println("getImplementationName()");
return getClass().getName();
}
@Override
public String[] getSupportedServiceNames() {
System.out.println("getSupportedServiceNames()");
return getSupportedServiceNamesStatic();
}
@Override
public boolean supportsService(final String serviceName) {
System.out.println("supportsService(" + serviceName + ")");
for (String service : getSupportedServiceNames()) {
if (service.equals(serviceName)) {
return true;
}
}
return false;
}
// XExporter
@Override
public void setSourceDocument(final XComponent document) throws IllegalArgumentException {
System.out.println("setSourceDocument()");
this.document = document;
}
// XFilter
@Override
public void cancel() {
System.out.println("cancel()");
}
@Override
public boolean filter(final PropertyValue[] properties) {
System.out.println("filter!!!");
try (PrintWriter pw = new PrintWriter("/tmp/log.txt")) {
pw.println("Filter called!!!");
pw.flush();
for (final PropertyValue property : properties) {
pw.println(property.Name + "=" + property.Value.toString());
}
} catch (FileNotFoundException fileNotFoundException) {
}
MediaDescriptor mediaDescriptor = new MediaDescriptor(properties);
try {
System.out.println("Starting");
SXSSFWorkbook poiWorkbook = new SXSSFWorkbook(100);
try {
System.out.println("Created POI workbook");
XSpreadsheetDocument spreadSheetDocument = UnoRuntime.queryInterface(XSpreadsheetDocument.class, document);
if (spreadSheetDocument == null) {
return false;
}
XSpreadsheets spreadsheets = spreadSheetDocument.getSheets();
XIndexAccess spreadsheetsIndexAccess = UnoRuntime.queryInterface(XIndexAccess.class, spreadsheets);
for (int i = 0; i < spreadsheetsIndexAccess.getCount(); i++) {
System.out.println("Saving sheet " + i);
XSpreadsheet spreadsheet = (XSpreadsheet) AnyConverter.toObject(XSpreadsheet.class, spreadsheetsIndexAccess.getByIndex(i));
XNamed named = UnoRuntime.queryInterface(XNamed.class, spreadsheet);
SXSSFSheet poiSheet = poiWorkbook.createSheet(named.getName());
saveSheet(spreadsheet, poiSheet);
}
// FIXME: other ways of specifying where to save the file?
Object unoOutputStreamObject = mediaDescriptor.get(MediaDescriptor.OutputStream);
OutputStream javaOutputStream = null;
try {
if (unoOutputStreamObject != null) {
// "If used when storing a document: writing must be done using this stream"
System.out.println("Using output stream");
XOutputStream unoOutputStream = (XOutputStream) AnyConverter.toObject(XOutputStream.class, unoOutputStreamObject);
javaOutputStream = new XOutputStreamToOutputStreamAdapter(unoOutputStream);
} else {
String urlString = mediaDescriptor.getUnpackedValueOrDefault(MediaDescriptor.URL, (String)null);
if (urlString != null) {
URI uri = new URI(urlString);
File file = new File(uri);
System.out.println("Using file " + file.getAbsolutePath());
javaOutputStream = new FileOutputStream(file);
} else {
throw new IOException("Unsupported data source!");
}
}
poiWorkbook.write(javaOutputStream);
} finally {
if (javaOutputStream != null) {
javaOutputStream.close();
}
}
} finally {
poiWorkbook.dispose();
}
System.out.println("Success!");
return true;
} catch (WrappedTargetException wrappedTargetException) {
wrappedTargetException.printStackTrace();
} catch (FileNotFoundException fileNotFoundException) {
fileNotFoundException.printStackTrace();
} catch (IOException ioException) {
ioException.printStackTrace();
} catch (URISyntaxException uriSyntaxException) {
uriSyntaxException.printStackTrace();
} catch (IndexOutOfBoundsException e) {
e.printStackTrace();
} catch (Throwable t) {
t.printStackTrace();
}
return false;
}
private void saveSheet(XSpreadsheet spreadsheet, SXSSFSheet poiSheet) {
XSheetCellCursor cursor = spreadsheet.createCursor();
XUsedAreaCursor usedAreaCursor = UnoRuntime.queryInterface(XUsedAreaCursor.class, cursor);
XCellRangeAddressable cellRangeAddressable = UnoRuntime.queryInterface(XCellRangeAddressable.class, cursor);
usedAreaCursor.gotoEndOfUsedArea(true);
CellRangeAddress usedArea = cellRangeAddressable.getRangeAddress();
// FIXME: narrow down the cells to save further using ScUsedAreaIterator
for (int row = usedArea.StartRow; row <= usedArea.EndRow; row++) {
boolean hasData = false;
for (int col = usedArea.StartColumn; col <= usedArea.EndColumn; col++) {
try {
XCell cell = spreadsheet.getCellByPosition(col, row);
if (cell.getType() != CellContentType.EMPTY) {
hasData = true;
break;
}
} catch (IndexOutOfBoundsException indexOutOfBoundsException) {
indexOutOfBoundsException.printStackTrace();
}
}
if (!hasData) {
continue;
}
SXSSFRow poiRow = poiSheet.createRow(row);
System.out.println("Creating row " + row);
for (int col = usedArea.StartColumn; col <= usedArea.EndColumn; col++) {
try {
XCell cell = spreadsheet.getCellByPosition(col, row);
if (cell.getType() == CellContentType.TEXT) {
XTextRange textRange = UnoRuntime.queryInterface(XTextRange.class, cell);
SXSSFCell poiCell = poiRow.createCell(col);
System.out.println("Adding cell " + col);
poiCell.setCellValue(textRange.getString());
} else if (cell.getType() == CellContentType.VALUE) {
SXSSFCell poiCell = poiRow.createCell(col);
System.out.println("Adding cell " + col);
poiCell.setCellValue(cell.getValue());
}
} catch (IndexOutOfBoundsException indexOutOfBoundsException) {
indexOutOfBoundsException.printStackTrace();
}
}
}
}
}