You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by da...@apache.org on 2020/10/17 07:59:40 UTC

[openoffice] 01/01: Initial import of the preliminary POI-based OOXML export filter. Only does .xlsx for now, and breaks due to POI classpath problems.

This is an automated email from the ASF dual-hosted git repository.

damjan pushed a commit to branch poi-filter
in repository https://gitbox.apache.org/repos/asf/openoffice.git

commit 323984d94e92d002cd771da940e01f66a9ad6bfe
Author: Damjan Jovanovic <da...@apache.org>
AuthorDate: Sat Oct 17 09:57:17 2020 +0200

    Initial import of the preliminary POI-based OOXML export filter.
    Only does .xlsx for now, and breaks due to POI classpath problems.
    
    Patch by: me
---
 main/filter/source/config/fragments/fcfg_calc.mk   |   8 +-
 .../calc_export_MS_Excel_2007_poi_XML.xcu}         |  18 +-
 .../calc_export_MS_Excel_2007_poi_XML_ui.xcu}      |  13 +-
 .../config/fragments/types/MS_Excel_2007_XML.xcu   |   2 +-
 main/poi-filter/Ant_poi-filter.mk                  |  29 +++
 main/poi-filter/Makefile                           |  32 +++
 main/poi-filter/Module_poi-filter.mk               |  31 +++
 main/poi-filter/java/poi-filter/MANIFEST.MF        |   2 +
 .../java/poi-filter/build.xml}                     |  32 ++-
 .../java/poi-filter/poi-filter.component}          |  24 +-
 .../apache/openoffice/poi/filter/ExcelFilter.java  | 253 +++++++++++++++++++++
 .../openoffice/poi/filter/FormatDetector.java}     |  32 ++-
 .../openoffice/poi/filter/MediaDescriptor.java     | 112 +++++++++
 .../poi/filter/POIFilterServiceProvider.java       |  53 +++++
 main/poi-filter/prj/build.lst                      |   2 +
 main/poi-filter/prj/d.lst                          |   0
 main/poi-filter/prj/makefile.mk                    |  44 ++++
 main/postprocess/packcomponents/makefile.mk        |   1 +
 main/postprocess/prj/build.lst                     |   2 +-
 main/scp2/source/ooo/file_ooo.scp                  |   4 +
 main/scp2/source/ooo/module_hidden_ooo.scp         |   1 +
 21 files changed, 640 insertions(+), 55 deletions(-)

diff --git a/main/filter/source/config/fragments/fcfg_calc.mk b/main/filter/source/config/fragments/fcfg_calc.mk
index 42d8086..c375a36 100644
--- a/main/filter/source/config/fragments/fcfg_calc.mk
+++ b/main/filter/source/config/fragments/fcfg_calc.mk
@@ -51,7 +51,7 @@ T4_CALC = \
 	MS_Excel_2007_Binary
 
 # -----------------------------------------------
-# count = 28
+# count = 29
 F4_CALC = \
 	DIF \
 	HTML__StarCalc_ \
@@ -78,11 +78,12 @@ F4_CALC = \
 	calc8_template \
 	MS_Excel_2003_XML \
 	calc_MS_Excel_2007_XML \
+	calc_export_MS_Excel_2007_poi_XML \
 	calc_MS_Excel_2007_XML_Template \
 	calc_MS_Excel_2007_Binary
 
 # -----------------------------------------------
-# count = 12
+# count = 13
 F4_UI_CALC = \
 	HTML__StarCalc__ui \
 	MS_Excel_4_0_Vorlage_Template_ui \
@@ -99,7 +100,8 @@ F4_UI_CALC = \
 	MS_Excel_2003_XML_ui \
 	calc_MS_Excel_2007_XML_ui \
 	calc_MS_Excel_2007_XML_Template_ui \
-	calc_MS_Excel_2007_Binary_ui
+	calc_MS_Excel_2007_Binary_ui \
+	calc_export_MS_Excel_2007_poi_XML_ui
 
 # -----------------------------------------------
 # count = 0
diff --git a/main/filter/source/config/fragments/types/MS_Excel_2007_XML.xcu b/main/filter/source/config/fragments/filters/calc_export_MS_Excel_2007_poi_XML.xcu
similarity index 63%
copy from main/filter/source/config/fragments/types/MS_Excel_2007_XML.xcu
copy to main/filter/source/config/fragments/filters/calc_export_MS_Excel_2007_poi_XML.xcu
index 91e549f..f8c286c 100644
--- a/main/filter/source/config/fragments/types/MS_Excel_2007_XML.xcu
+++ b/main/filter/source/config/fragments/filters/calc_export_MS_Excel_2007_poi_XML.xcu
@@ -19,13 +19,13 @@
  * 
  ***********************************************************-->
 
-<node oor:name="MS Excel 2007 XML" oor:op="replace" >
-	<prop oor:name="DetectService"><value>com.sun.star.comp.oox.FormatDetector</value></prop>
-	<prop oor:name="URLPattern"/>
-	<prop oor:name="Extensions"><value>xlsm xlsx</value></prop>
-	<prop oor:name="MediaType"/>
-	<prop oor:name="Preferred"><value>false</value></prop>
-	<prop oor:name="PreferredFilter"><value>Calc MS Excel 2007 XML</value></prop>
-	<prop oor:name="UIName"><value xml:lang="x-default">Microsoft Excel 2007 XML</value></prop>
-	<prop oor:name="ClipboardFormat"/>
+<node oor:name="Calc export MS Excel 2007 poi XML" oor:op="replace">
+	<prop oor:name="Flags"><value>IMPORT EXPORT ALIEN 3RDPARTYFILTER</value></prop>
+	<prop oor:name="UIComponent"/>
+	<prop oor:name="FilterService"><value>org.apache.openoffice.poi.filter.ExcelFilter</value></prop>
+	<prop oor:name="UserData"/>
+	<prop oor:name="FileFormatVersion"/>
+	<prop oor:name="Type"><value>MS Excel 2007 XML</value></prop>
+	<prop oor:name="TemplateName"/>
+	<prop oor:name="DocumentService"><value>com.sun.star.sheet.SpreadsheetDocument</value></prop>
 </node>
diff --git a/main/filter/source/config/fragments/types/MS_Excel_2007_XML.xcu b/main/filter/source/config/fragments/filters/calc_export_MS_Excel_2007_poi_XML_ui.xcu
similarity index 64%
copy from main/filter/source/config/fragments/types/MS_Excel_2007_XML.xcu
copy to main/filter/source/config/fragments/filters/calc_export_MS_Excel_2007_poi_XML_ui.xcu
index 91e549f..d31c4fe 100644
--- a/main/filter/source/config/fragments/types/MS_Excel_2007_XML.xcu
+++ b/main/filter/source/config/fragments/filters/calc_export_MS_Excel_2007_poi_XML_ui.xcu
@@ -19,13 +19,8 @@
  * 
  ***********************************************************-->
 
-<node oor:name="MS Excel 2007 XML" oor:op="replace" >
-	<prop oor:name="DetectService"><value>com.sun.star.comp.oox.FormatDetector</value></prop>
-	<prop oor:name="URLPattern"/>
-	<prop oor:name="Extensions"><value>xlsm xlsx</value></prop>
-	<prop oor:name="MediaType"/>
-	<prop oor:name="Preferred"><value>false</value></prop>
-	<prop oor:name="PreferredFilter"><value>Calc MS Excel 2007 XML</value></prop>
-	<prop oor:name="UIName"><value xml:lang="x-default">Microsoft Excel 2007 XML</value></prop>
-	<prop oor:name="ClipboardFormat"/>
+<node oor:name="Calc export MS Excel 2007 poi XML">
+	<prop oor:name="UIName">
+		<value xml:lang="en-US">Microsoft Excel 2007 XML</value>
+	</prop>
 </node>
diff --git a/main/filter/source/config/fragments/types/MS_Excel_2007_XML.xcu b/main/filter/source/config/fragments/types/MS_Excel_2007_XML.xcu
index 91e549f..6d66cfb 100644
--- a/main/filter/source/config/fragments/types/MS_Excel_2007_XML.xcu
+++ b/main/filter/source/config/fragments/types/MS_Excel_2007_XML.xcu
@@ -22,7 +22,7 @@
 <node oor:name="MS Excel 2007 XML" oor:op="replace" >
 	<prop oor:name="DetectService"><value>com.sun.star.comp.oox.FormatDetector</value></prop>
 	<prop oor:name="URLPattern"/>
-	<prop oor:name="Extensions"><value>xlsm xlsx</value></prop>
+	<prop oor:name="Extensions"><value>xlsx xlsm</value></prop>
 	<prop oor:name="MediaType"/>
 	<prop oor:name="Preferred"><value>false</value></prop>
 	<prop oor:name="PreferredFilter"><value>Calc MS Excel 2007 XML</value></prop>
diff --git a/main/poi-filter/Ant_poi-filter.mk b/main/poi-filter/Ant_poi-filter.mk
new file mode 100644
index 0000000..b8967c0
--- /dev/null
+++ b/main/poi-filter/Ant_poi-filter.mk
@@ -0,0 +1,29 @@
+#**************************************************************
+#  
+#  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.
+#  
+#**************************************************************
+
+
+
+$(eval $(call gb_Ant_Ant,poi-filter,$(SRCDIR)/poi-filter/java/poi-filter/build.xml))
+
+$(eval $(call gb_Ant_set_componentfile,poi-filter,poi-filter/java/poi-filter/poi-filter,OOO))
+
+# vim: set noet sw=4 ts=4:
+
diff --git a/main/poi-filter/Makefile b/main/poi-filter/Makefile
new file mode 100644
index 0000000..c1d144c
--- /dev/null
+++ b/main/poi-filter/Makefile
@@ -0,0 +1,32 @@
+#**************************************************************
+#  
+#  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.
+#  
+#**************************************************************
+
+ifeq ($(strip $(SOLARENV)),)
+$(error No environment set!)
+endif
+
+gb_PARTIALBUILD := T
+GBUILDDIR := $(SOLARENV)/gbuild
+include $(GBUILDDIR)/gbuild.mk
+
+$(eval $(call gb_Module_make_global_targets,$(shell ls $(dir $(realpath $(firstword $(MAKEFILE_LIST))))/Module*.mk)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/main/poi-filter/Module_poi-filter.mk b/main/poi-filter/Module_poi-filter.mk
new file mode 100644
index 0000000..872cda5
--- /dev/null
+++ b/main/poi-filter/Module_poi-filter.mk
@@ -0,0 +1,31 @@
+#**************************************************************
+#  
+#  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.
+#  
+#**************************************************************
+
+
+
+$(eval $(call gb_Module_Module,poi-filter))
+
+$(eval $(call gb_Module_add_targets,poi-filter,\
+	Ant_poi-filter \
+))
+
+
+# vim: set noet sw=4 ts=4:
diff --git a/main/poi-filter/java/poi-filter/MANIFEST.MF b/main/poi-filter/java/poi-filter/MANIFEST.MF
new file mode 100644
index 0000000..ed8498e
--- /dev/null
+++ b/main/poi-filter/java/poi-filter/MANIFEST.MF
@@ -0,0 +1,2 @@
+RegistrationClassName: org.apache.openoffice.poi.filter.POIFilterServiceProvider
+UNO-Type-Path: 
diff --git a/main/filter/source/config/fragments/types/MS_Excel_2007_XML.xcu b/main/poi-filter/java/poi-filter/build.xml
similarity index 57%
copy from main/filter/source/config/fragments/types/MS_Excel_2007_XML.xcu
copy to main/poi-filter/java/poi-filter/build.xml
index 91e549f..118e459 100644
--- a/main/filter/source/config/fragments/types/MS_Excel_2007_XML.xcu
+++ b/main/poi-filter/java/poi-filter/build.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
 <!--***********************************************************
  * 
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,13 +20,24 @@
  * 
  ***********************************************************-->
 
-<node oor:name="MS Excel 2007 XML" oor:op="replace" >
-	<prop oor:name="DetectService"><value>com.sun.star.comp.oox.FormatDetector</value></prop>
-	<prop oor:name="URLPattern"/>
-	<prop oor:name="Extensions"><value>xlsm xlsx</value></prop>
-	<prop oor:name="MediaType"/>
-	<prop oor:name="Preferred"><value>false</value></prop>
-	<prop oor:name="PreferredFilter"><value>Calc MS Excel 2007 XML</value></prop>
-	<prop oor:name="UIName"><value xml:lang="x-default">Microsoft Excel 2007 XML</value></prop>
-	<prop oor:name="ClipboardFormat"/>
-</node>
+
+  
+<project name="poi-filter" default="main" basedir=".">
+
+    <property file="../../../ant.properties"/>
+    <import file="${SRC_ROOT}/solenv/ant/aoo-ant.xml"/>
+
+    <target name="init-project">
+        <property name="jar.manifest" value="MANIFEST.MF"/>
+
+        <path id="main.classpath">
+            <pathelement location="${OUTDIR}/bin/unoil.jar"/>
+            <pathelement location="${OUTDIR}/bin/jurt.jar"/>
+            <pathelement location="${OUTDIR}/bin/ridl.jar"/>
+            <pathelement location="${OUTDIR}/bin/juh.jar"/>
+            <pathelement location="${OUTDIR}/bin/java_uno.jar"/>
+        </path>
+    </target>
+
+</project>
+
diff --git a/main/filter/source/config/fragments/types/MS_Excel_2007_XML.xcu b/main/poi-filter/java/poi-filter/poi-filter.component
similarity index 63%
copy from main/filter/source/config/fragments/types/MS_Excel_2007_XML.xcu
copy to main/poi-filter/java/poi-filter/poi-filter.component
index 91e549f..051e82e 100644
--- a/main/filter/source/config/fragments/types/MS_Excel_2007_XML.xcu
+++ b/main/poi-filter/java/poi-filter/poi-filter.component
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
 <!--***********************************************************
  * 
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,13 +20,16 @@
  * 
  ***********************************************************-->
 
-<node oor:name="MS Excel 2007 XML" oor:op="replace" >
-	<prop oor:name="DetectService"><value>com.sun.star.comp.oox.FormatDetector</value></prop>
-	<prop oor:name="URLPattern"/>
-	<prop oor:name="Extensions"><value>xlsm xlsx</value></prop>
-	<prop oor:name="MediaType"/>
-	<prop oor:name="Preferred"><value>false</value></prop>
-	<prop oor:name="PreferredFilter"><value>Calc MS Excel 2007 XML</value></prop>
-	<prop oor:name="UIName"><value xml:lang="x-default">Microsoft Excel 2007 XML</value></prop>
-	<prop oor:name="ClipboardFormat"/>
-</node>
+
+
+<component loader="com.sun.star.loader.Java2"
+    xmlns="http://openoffice.org/2010/uno-components">
+  <!--
+  <implementation name="org.apache.openoffice.ooxml2.FormatDetector">
+    <service name="com.sun.star.frame.ExtendedTypeDetection"/>
+  </implementation>
+  -->
+  <implementation name="org.apache.openoffice.poi.filter.ExcelFilter">
+    <service name="com.sun.star.document.ExportFilter"/>
+  </implementation>
+</component>
diff --git a/main/poi-filter/java/poi-filter/src/main/java/org/apache/openoffice/poi/filter/ExcelFilter.java b/main/poi-filter/java/poi-filter/src/main/java/org/apache/openoffice/poi/filter/ExcelFilter.java
new file mode 100644
index 0000000..50eb276
--- /dev/null
+++ b/main/poi-filter/java/poi-filter/src/main/java/org/apache/openoffice/poi/filter/ExcelFilter.java
@@ -0,0 +1,253 @@
+/**************************************************************
+ * 
+ * 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();
+                }
+            }   
+        }
+    }
+}
diff --git a/main/filter/source/config/fragments/types/MS_Excel_2007_XML.xcu b/main/poi-filter/java/poi-filter/src/main/java/org/apache/openoffice/poi/filter/FormatDetector.java
similarity index 50%
copy from main/filter/source/config/fragments/types/MS_Excel_2007_XML.xcu
copy to main/poi-filter/java/poi-filter/src/main/java/org/apache/openoffice/poi/filter/FormatDetector.java
index 91e549f..0bb5b43 100644
--- a/main/filter/source/config/fragments/types/MS_Excel_2007_XML.xcu
+++ b/main/poi-filter/java/poi-filter/src/main/java/org/apache/openoffice/poi/filter/FormatDetector.java
@@ -1,4 +1,4 @@
-<!--***********************************************************
+/**************************************************************
  * 
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -17,15 +17,23 @@
  * specific language governing permissions and limitations
  * under the License.
  * 
- ***********************************************************-->
+ *************************************************************/
 
-<node oor:name="MS Excel 2007 XML" oor:op="replace" >
-	<prop oor:name="DetectService"><value>com.sun.star.comp.oox.FormatDetector</value></prop>
-	<prop oor:name="URLPattern"/>
-	<prop oor:name="Extensions"><value>xlsm xlsx</value></prop>
-	<prop oor:name="MediaType"/>
-	<prop oor:name="Preferred"><value>false</value></prop>
-	<prop oor:name="PreferredFilter"><value>Calc MS Excel 2007 XML</value></prop>
-	<prop oor:name="UIName"><value xml:lang="x-default">Microsoft Excel 2007 XML</value></prop>
-	<prop oor:name="ClipboardFormat"/>
-</node>
+package org.apache.openoffice.poi.filter;
+
+import com.sun.star.beans.PropertyValue;
+import com.sun.star.document.XExtendedFilterDetection;
+import com.sun.star.lib.uno.helper.ComponentBase;
+
+public class FormatDetector extends ComponentBase implements XExtendedFilterDetection {
+    public static final String __serviceName = "com.sun.star.frame.ExtendedTypeDetection";
+    
+    @Override
+    public String detect(final PropertyValue[][] descriptor) {
+        final MediaDescriptor mediaDescriptor = new MediaDescriptor(descriptor[0]);
+        if (mediaDescriptor.getUnpackedValueOrDefault(MediaDescriptor.Aborted, false)) {
+            return "";
+        }
+        return "";
+    }
+}
diff --git a/main/poi-filter/java/poi-filter/src/main/java/org/apache/openoffice/poi/filter/MediaDescriptor.java b/main/poi-filter/java/poi-filter/src/main/java/org/apache/openoffice/poi/filter/MediaDescriptor.java
new file mode 100644
index 0000000..753bd82
--- /dev/null
+++ b/main/poi-filter/java/poi-filter/src/main/java/org/apache/openoffice/poi/filter/MediaDescriptor.java
@@ -0,0 +1,112 @@
+/**************************************************************
+ * 
+ * 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.util.HashMap;
+
+import com.sun.star.beans.PropertyValue;
+
+public class MediaDescriptor extends HashMap<String,Object> {
+    private static final long serialVersionUID = 1L;
+    
+    public static final String Aborted = "Aborted";
+    public static final String AsTemplate = "AsTemplate";
+    public static final String AuthenticationHandler = "AuthenticationHandler";
+    public static final String Author = "Author";
+    public static final String CharacterSet = "CharacterSet";
+    public static final String Comment = "Comment";
+    public static final String ComponentData = "ComponentData";
+    public static final String DeepDetection = "DeepDetection";
+    public static final String DetectService = "DetectService";
+    public static final String DocumentBaseURL = "DocumentBaseURL";
+    public static final String DocumentService = "DocumentService";
+    public static final String DocumentTitle = "DocumentTitle";
+    public static final String EncryptionData = "EncryptionData";
+    public static final String Extension = "Extension";
+    public static final String FileName = "FileName";
+    public static final String FilterData = "FilterData";
+    public static final String FilterFlags = "FilterFlags";
+    public static final String FilterName = "FilterName";
+    public static final String FilterOptions = "FilterOptions";
+    public static final String Format = "Format";
+    public static final String Frame = "Frame";
+    public static final String FrameName = "FrameName";
+    public static final String Hidden = "Hidden";
+    public static final String HierarchicalDocumentName = "HierarchicalDocumentName";
+    public static final String InputStream = "InputStream";
+    public static final String InteractionHandler = "InteractionHandler";
+    public static final String JumpMark = "JumpMark";
+    public static final String MacroExecutionMode = "MacroExecutionMode";
+    public static final String MediaType = "MediaType";
+    public static final String Minimized = "Minimized";
+    public static final String Model = "Model";
+    public static final String NoAutoSave = "NoAutoSave";
+    public static final String OpenFlags = "OpenFlags";
+    public static final String OpenNewView = "OpenNewView";
+    public static final String OutputStream = "OutputStream";
+    public static final String Overwrite = "Overwrite";
+    public static final String Password = "Password";
+    public static final String Pattern = "Pattern";
+    public static final String PosSize = "PosSize";
+    public static final String PostData = "PostData";
+    public static final String PostString = "PostString";
+    public static final String Preview = "Preview";
+    public static final String ReadOnly = "ReadOnly";
+    public static final String Referer = "Referer";
+    public static final String RepairPackage = "RepairPackage";
+    public static final String SalvagedFile = "SalvagedFile";
+    public static final String Silent = "Silent";
+    public static final String StartPresentation = "StartPresentation";
+    public static final String StatusIndicator = "StatusIndicator";
+    public static final String Stream = "Stream";
+    public static final String StreamForOutput = "StreamForOutput";
+    public static final String SuggestedSaveAsDir = "SuggestedSaveAsDir";
+    public static final String SuggestedSaveAsName = "SuggestedSaveAsName";
+    public static final String TemplateName = "TemplateName";
+    public static final String TemplateRegionName = "TemplateRegionName";
+    public static final String Title = "Title";
+    public static final String TypeName = "TypeName";
+    public static final String UCBContent = "UCBContent";
+    public static final String Unpacked = "Unpacked";
+    public static final String UpdateDocMode = "UpdateDocMode";
+    public static final String URL = "URL";
+    public static final String Version = "Version";
+    public static final String ViewControllerName = "ViewControllerName";
+    public static final String ViewData = "ViewData";
+    public static final String ViewId = "ViewId";
+    public static final String ViewOnly = "ViewOnly";
+
+    public MediaDescriptor(final PropertyValue[] properties) {
+        super();
+        for (final PropertyValue property : properties) {
+            put(property.Name, property.Value);
+        }
+    }
+    
+    @SuppressWarnings("unchecked")
+    public <T> T getUnpackedValueOrDefault(final String key, final T aDefault) {
+        final T t = (T) get(key);
+        if (t == null) {
+            return aDefault;
+        }
+        return t;
+    }
+}
diff --git a/main/poi-filter/java/poi-filter/src/main/java/org/apache/openoffice/poi/filter/POIFilterServiceProvider.java b/main/poi-filter/java/poi-filter/src/main/java/org/apache/openoffice/poi/filter/POIFilterServiceProvider.java
new file mode 100644
index 0000000..a2dea15
--- /dev/null
+++ b/main/poi-filter/java/poi-filter/src/main/java/org/apache/openoffice/poi/filter/POIFilterServiceProvider.java
@@ -0,0 +1,53 @@
+/**************************************************************
+ * 
+ * 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 com.sun.star.lib.uno.helper.Factory;;
+import com.sun.star.lang.XSingleComponentFactory;
+import com.sun.star.registry.XRegistryKey;
+
+public class POIFilterServiceProvider {
+    
+    public static XSingleComponentFactory __getComponentFactory(String implName) {
+        
+        System.out.println("Asked to create " + implName);
+
+        XSingleComponentFactory xSingleComponentFactory = null;
+//        if (implName.equals( FormatDetector.class.getName()) )
+//            xSingleComponentFactory = Factory.createComponentFactory( FormatDetector.class,
+//                   FormatDetector.__serviceName, multiFactory, regKey); 
+        if (implName.equals(ExcelFilter.class.getName()))
+            xSingleComponentFactory = Factory.createComponentFactory( ExcelFilter.class,
+                    ExcelFilter.class.getName(), ExcelFilter.getSupportedServiceNamesStatic());
+        System.out.println("Returning " + xSingleComponentFactory.toString());
+        return xSingleComponentFactory;
+    }
+
+    public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) {
+        boolean registered = true;
+        registered |= Factory.writeRegistryServiceInfo(
+            ExcelFilter.class.getName(),
+            ExcelFilter.getSupportedServiceNamesStatic(),
+            regKey);
+        return registered;
+    }
+}
diff --git a/main/poi-filter/prj/build.lst b/main/poi-filter/prj/build.lst
new file mode 100644
index 0000000..e7ffb68
--- /dev/null
+++ b/main/poi-filter/prj/build.lst
@@ -0,0 +1,2 @@
+poifilt      poi-filter     :    L10N:l10n rsc javaunohelper unoil jurt ridljar offapi udkapi NULL
+poifilt      poi-filter\prj                   nmake           -       all     poifilt_prj NULL
diff --git a/main/poi-filter/prj/d.lst b/main/poi-filter/prj/d.lst
new file mode 100644
index 0000000..e69de29
diff --git a/main/poi-filter/prj/makefile.mk b/main/poi-filter/prj/makefile.mk
new file mode 100644
index 0000000..353f9e0
--- /dev/null
+++ b/main/poi-filter/prj/makefile.mk
@@ -0,0 +1,44 @@
+#**************************************************************
+#  
+#  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.
+#  
+#**************************************************************
+
+
+
+PRJ=..
+TARGET=prj
+
+.INCLUDE : settings.mk
+
+.IF "$(VERBOSE)"!=""
+VERBOSEFLAG :=
+.ELSE
+VERBOSEFLAG := -s
+.ENDIF
+
+.IF "$(DEBUG)"!=""
+DEBUG_ARGUMENT=DEBUG=$(DEBUG)
+.ELIF "$(debug)"!=""
+DEBUG_ARGUMENT=debug=$(debug)
+.ELSE
+DEBUG_ARGUMENT=
+.ENDIF
+
+all:
+	cd $(PRJ) && $(GNUMAKE) $(VERBOSEFLAG) -r -j$(MAXPROCESS) $(gb_MAKETARGET) $(DEBUG_ARGUMENT) && $(GNUMAKE) $(VERBOSEFLAG) -r deliverlog
diff --git a/main/postprocess/packcomponents/makefile.mk b/main/postprocess/packcomponents/makefile.mk
index c4588cf..c07dbcb 100644
--- a/main/postprocess/packcomponents/makefile.mk
+++ b/main/postprocess/packcomponents/makefile.mk
@@ -286,6 +286,7 @@ my_components += \
     hsqldb \
     jdbc \
     postgresql \
+    component/poi-filter/java/poi-filter/poi-filter \
     component/wizards/com/sun/star/wizards/letter/letter \
     component/wizards/com/sun/star/wizards/query/query \
     component/wizards/com/sun/star/wizards/report/report \
diff --git a/main/postprocess/prj/build.lst b/main/postprocess/prj/build.lst
index 54b7a88..da75c32 100644
--- a/main/postprocess/prj/build.lst
+++ b/main/postprocess/prj/build.lst
@@ -1,4 +1,4 @@
-po      postprocess     ::      svgio accessibility automation basctl bean chart2 configmgr CRASHREP:crashrep COINMP:coinmp cui dbaccess desktop dtrans embeddedobj embedserv EPM:epm eventattacher extensions extras fileaccess filter forms fpicker helpcontent2 io JAVAINSTALLER2:javainstaller2 lingucomponent MATHMLDTD:MathMLDTD ODK:odk officecfg package padmin psprint_config remotebridges sc scaddins sccomp scp2 scripting sd setup_native slideshow starmath sw sysui test testtools ucb UnoCon [...]
+po      postprocess     ::      svgio accessibility automation basctl bean chart2 configmgr CRASHREP:crashrep COINMP:coinmp cui dbaccess desktop dtrans embeddedobj embedserv EPM:epm eventattacher extensions extras fileaccess filter forms fpicker helpcontent2 io JAVAINSTALLER2:javainstaller2 lingucomponent MATHMLDTD:MathMLDTD ODK:odk officecfg package padmin psprint_config remotebridges sc scaddins sccomp scp2 scripting sd setup_native slideshow starmath sw sysui test testtools ucb UnoCon [...]
 po	postprocess			    	usr1	-	all	po_mkout NULL
 po	postprocess\checkxml		nmake	-	all	po_checkxml NULL
 po	postprocess\checkdeliver	nmake	-	all	po_checkdlv NULL
diff --git a/main/scp2/source/ooo/file_ooo.scp b/main/scp2/source/ooo/file_ooo.scp
index a8a7cbc..ef55c06 100644
--- a/main/scp2/source/ooo/file_ooo.scp
+++ b/main/scp2/source/ooo/file_ooo.scp
@@ -381,6 +381,10 @@ End
 STD_JAR_FILE( gid_File_Jar_Bsh, bsh )
 #endif
 
+#if defined SOLAR_JAVA
+STD_JAR_FILE( gid_File_Jar_poi_filter, poi-filter )
+#endif
+
 #if defined SOLAR_JAVA && ! defined SYSTEM_LUCENE
 STD_JAR_FILE( gid_File_Jar_Lucene_Core, lucene-core-2.9.4-dev )
 STD_JAR_FILE( gid_File_Jar_Lucene_Analyzers, lucene-analyzers-2.9.4-dev )
diff --git a/main/scp2/source/ooo/module_hidden_ooo.scp b/main/scp2/source/ooo/module_hidden_ooo.scp
index 2533af1..0b19766 100644
--- a/main/scp2/source/ooo/module_hidden_ooo.scp
+++ b/main/scp2/source/ooo/module_hidden_ooo.scp
@@ -118,6 +118,7 @@ Module gid_Module_Root_Files_3
 	gid_File_Jar_Xflatxml,
 	gid_File_Jar_Xmerge,
 	gid_File_Jar_Xmergebridge,
+	gid_File_Jar_poi_filter,
 	gid_File_Jar_Lucene_Core,
 	gid_File_Jar_Lucene_Analyzers,
 	gid_File_Jar_Lucenehelpwrapper,