tdf#99438: sc: support for .xltx export
Added support for content types for template and template
with macros (.xltm, but no user interface for this yet).
Fixed preferred extension for template: by default it is .xltx
and not .xltm (macro-enabled), because MS Excel is very strict
about matching of content-type and extension here.
Fixed wrong namespace in FilterService for ExcelFilter.
Change-Id: Ie717d31d72203601324860f069918d75082add4a
Reviewed-on: https://gerrit.libreoffice.org/65111
Tested-by: Jenkins
Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
diff --git a/filter/source/config/fragments/filters/calc_MS_Excel_2007_XML_Template.xcu b/filter/source/config/fragments/filters/calc_MS_Excel_2007_XML_Template.xcu
index f42c60d..db5cb9a 100644
--- a/filter/source/config/fragments/filters/calc_MS_Excel_2007_XML_Template.xcu
+++ b/filter/source/config/fragments/filters/calc_MS_Excel_2007_XML_Template.xcu
@@ -16,7 +16,7 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
-->
<node oor:name="Calc MS Excel 2007 XML Template" oor:op="replace">
<prop oor:name="Flags"><value>IMPORT ALIEN 3RDPARTYFILTER TEMPLATE TEMPLATEPATH</value></prop>
<prop oor:name="Flags"><value>IMPORT EXPORT ALIEN 3RDPARTYFILTER TEMPLATE TEMPLATEPATH</value></prop>
<prop oor:name="UIComponent"/>
<prop oor:name="FilterService"><value>com.sun.star.comp.oox.xls.ExcelFilter</value></prop>
<prop oor:name="UserData"/>
diff --git a/filter/source/config/fragments/filters/calc_OOXML_Template.xcu b/filter/source/config/fragments/filters/calc_OOXML_Template.xcu
index 848e7ee..b65a756 100644
--- a/filter/source/config/fragments/filters/calc_OOXML_Template.xcu
+++ b/filter/source/config/fragments/filters/calc_OOXML_Template.xcu
@@ -18,7 +18,7 @@
<node oor:name="Calc Office Open XML Template" oor:op="replace">
<prop oor:name="Flags"><value>IMPORT ALIEN 3RDPARTYFILTER TEMPLATE TEMPLATEPATH</value></prop>
<prop oor:name="UIComponent"/>
<prop oor:name="FilterService"><value>com.sun.star.comp.oox.ExcelFilter</value></prop>
<prop oor:name="FilterService"><value>com.sun.star.comp.oox.xls.ExcelFilter</value></prop>
<prop oor:name="UserData"><value>OOXML</value></prop>
<prop oor:name="FileFormatVersion"><value>1</value></prop>
<prop oor:name="Type"><value>Office Open XML Spreadsheet Template</value></prop>
diff --git a/filter/source/config/fragments/types/MS_Excel_2007_XML_Template.xcu b/filter/source/config/fragments/types/MS_Excel_2007_XML_Template.xcu
index c55f639..35c18e4 100644
--- a/filter/source/config/fragments/types/MS_Excel_2007_XML_Template.xcu
+++ b/filter/source/config/fragments/types/MS_Excel_2007_XML_Template.xcu
@@ -18,7 +18,7 @@
<node oor:name="MS Excel 2007 XML Template" 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>xltm xltx</value></prop>
<prop oor:name="Extensions"><value>xltx xltm</value></prop>
<prop oor:name="MediaType"><value>application/vnd.openxmlformats-officedocument.spreadsheetml.template</value></prop>
<prop oor:name="Preferred"><value>false</value></prop>
<prop oor:name="PreferredFilter"><value>Calc MS Excel 2007 XML Template</value></prop>
diff --git a/sc/qa/unit/helper/qahelper.cxx b/sc/qa/unit/helper/qahelper.cxx
index e3b2db0..81c4431 100644
--- a/sc/qa/unit/helper/qahelper.cxx
+++ b/sc/qa/unit/helper/qahelper.cxx
@@ -87,7 +87,8 @@
{ "xml", "MS Excel 2003 XML Orcus", "calc_MS_Excel_2003_XML", XLS_XML_FORMAT_TYPE },
{ "xlsb", "Calc MS Excel 2007 Binary", "MS Excel 2007 Binary", XLSB_XML_FORMAT_TYPE },
{ "fods", "OpenDocument Spreadsheet Flat XML", "calc_ODS_FlatXML", FODS_FORMAT_TYPE },
{ "gnumeric", "Gnumeric Spreadsheet", "Gnumeric XML", GNUMERIC_FORMAT_TYPE }
{ "gnumeric", "Gnumeric Spreadsheet", "Gnumeric XML", GNUMERIC_FORMAT_TYPE },
{ "xltx", "Calc Office Open XML Template", "Office Open XML Spreadsheet Template", XLTX_FORMAT_TYPE }
};
bool testEqualsWithTolerance( long nVal1, long nVal2, long nTol )
diff --git a/sc/qa/unit/helper/qahelper.hxx b/sc/qa/unit/helper/qahelper.hxx
index 2482248..96268db 100644
--- a/sc/qa/unit/helper/qahelper.hxx
+++ b/sc/qa/unit/helper/qahelper.hxx
@@ -47,6 +47,7 @@
#define XLSB_XML_FORMAT_TYPE (SfxFilterFlags::IMPORT | SfxFilterFlags::ALIEN | SfxFilterFlags::STARONEFILTER | SfxFilterFlags::PREFERED)
#define FODS_FORMAT_TYPE (SfxFilterFlags::IMPORT | SfxFilterFlags::EXPORT | SfxFilterFlags::OWN | SfxFilterFlags::STARONEFILTER )
#define GNUMERIC_FORMAT_TYPE (SfxFilterFlags::IMPORT | SfxFilterFlags::ALIEN | SfxFilterFlags::PREFERED )
#define XLTX_FORMAT_TYPE (SfxFilterFlags::IMPORT | SfxFilterFlags::EXPORT | SfxFilterFlags::TEMPLATE |SfxFilterFlags::ALIEN | SfxFilterFlags::STARONEFILTER | SfxFilterFlags::PREFERED)
#define FORMAT_ODS 0
#define FORMAT_XLS 1
@@ -60,6 +61,7 @@
#define FORMAT_XLSB 9
#define FORMAT_FODS 10
#define FORMAT_GNUMERIC 11
#define FORMAT_XLTX 12
enum class StringType { PureString, StringValue };
diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx
index fcfb60f..5b1ff5f 100644
--- a/sc/qa/unit/subsequent_export-test.cxx
+++ b/sc/qa/unit/subsequent_export-test.cxx
@@ -209,6 +209,8 @@
void testTdf118990();
void testTdf121612();
void testXltxExport();
CPPUNIT_TEST_SUITE(ScExportTest);
CPPUNIT_TEST(test);
CPPUNIT_TEST(testTdf111876);
@@ -323,6 +325,8 @@
CPPUNIT_TEST(testTdf118990);
CPPUNIT_TEST(testTdf121612);
CPPUNIT_TEST(testXltxExport);
CPPUNIT_TEST_SUITE_END();
private:
@@ -356,6 +360,7 @@
{ BAD_CAST("r"), BAD_CAST("http://schemas.openxmlformats.org/package/2006/relationships") },
{ BAD_CAST("number"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0") },
{ BAD_CAST("loext"), BAD_CAST("urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0") },
{ BAD_CAST("ContentType"), BAD_CAST("http://schemas.openxmlformats.org/package/2006/content-types") },
};
for(size_t i = 0; i < SAL_N_ELEMENTS(aNamespaces); ++i)
{
@@ -4189,6 +4194,22 @@
CPPUNIT_ASSERT_EQUAL(size_t(1), pDPColl->GetCount());
}
void ScExportTest::testXltxExport()
{
// Create new document
ScDocShell* pShell = new ScDocShell(
SfxModelFlags::EMBEDDED_OBJECT |
SfxModelFlags::DISABLE_EMBEDDED_SCRIPTS |
SfxModelFlags::DISABLE_DOCUMENT_RECOVERY);
pShell->DoInitNew();
// Export as template and check content type
xmlDocPtr pDoc = XPathHelper::parseExport2(*this, *pShell, m_xSFactory, "[Content_Types].xml", FORMAT_XLTX);
CPPUNIT_ASSERT(pDoc);
assertXPath(pDoc, "/ContentType:Types/ContentType:Override[@PartName='/xl/workbook.xml']",
"ContentType", "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml");
}
CPPUNIT_TEST_SUITE_REGISTRATION(ScExportTest);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sc/source/filter/excel/xestream.cxx b/sc/source/filter/excel/xestream.cxx
index 45178df..3455b74 100644
--- a/sc/source/filter/excel/xestream.cxx
+++ b/sc/source/filter/excel/xestream.cxx
@@ -911,10 +911,11 @@
return pStream;
}
XclExpXmlStream::XclExpXmlStream( const uno::Reference< XComponentContext >& rCC, bool bExportVBA )
XclExpXmlStream::XclExpXmlStream( const uno::Reference< XComponentContext >& rCC, bool bExportVBA, bool bExportTemplate )
: XmlFilterBase( rCC ),
mpRoot( nullptr ),
mbExportVBA(bExportVBA)
mbExportVBA(bExportVBA),
mbExportTemplate(bExportTemplate)
{
}
@@ -1076,11 +1077,29 @@
ScDocShell::GetViewData()->WriteExtOptions( mpRoot->GetExtDocOptions() );
OUString const workbook = "xl/workbook.xml";
const char* pWorkbookContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml";
const char* pWorkbookContentType = nullptr;
if (mbExportVBA)
pWorkbookContentType = "application/vnd.ms-excel.sheet.macroEnabled.main+xml";
{
if (mbExportTemplate)
{
pWorkbookContentType = "application/vnd.ms-excel.template.macroEnabled.main+xml";
}
else
{
pWorkbookContentType = "application/vnd.ms-excel.sheet.macroEnabled.main+xml";
}
}
else
{
if (mbExportTemplate)
{
pWorkbookContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml";
}
else
{
pWorkbookContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml";
}
}
PushStream( CreateOutputStream( workbook, workbook,
uno::Reference <XOutputStream>(),
diff --git a/sc/source/filter/inc/xestream.hxx b/sc/source/filter/inc/xestream.hxx
index 5b10d6a..20cd690 100644
--- a/sc/source/filter/inc/xestream.hxx
+++ b/sc/source/filter/inc/xestream.hxx
@@ -275,7 +275,7 @@
class XclExpXmlStream : public oox::core::XmlFilterBase
{
public:
XclExpXmlStream( const css::uno::Reference< css::uno::XComponentContext >& rCC, bool bExportVBA );
XclExpXmlStream( const css::uno::Reference< css::uno::XComponentContext >& rCC, bool bExportVBA, bool bExportTemplate );
virtual ~XclExpXmlStream() override;
/** Returns the filter root data. */
@@ -355,6 +355,7 @@
XclExpXmlPathToStateMap maOpenedStreamMap;
bool const mbExportVBA;
bool const mbExportTemplate;
};
#endif
diff --git a/sc/source/filter/oox/excelfilter.cxx b/sc/source/filter/oox/excelfilter.cxx
index e638d0d..c5fda17 100644
--- a/sc/source/filter/oox/excelfilter.cxx
+++ b/sc/source/filter/oox/excelfilter.cxx
@@ -227,7 +227,7 @@
{
bool bExportVBA = exportVBA();
Reference< XExporter > xExporter(
new XclExpXmlStream( getComponentContext(), bExportVBA ) );
new XclExpXmlStream( getComponentContext(), bExportVBA, isExportTemplate() ) );
Reference< XComponent > xDocument( getModel(), UNO_QUERY );
Reference< XFilter > xFilter( xExporter, UNO_QUERY );