better OOXML VBA export

Change-Id: If02aa26e974b0f16b45c5476234c6425fd128ae4
This commit is contained in:
Markus Mohrhard
2015-09-25 06:39:40 +02:00
parent 14c521c879
commit c52982e741
7 changed files with 95 additions and 18 deletions

View File

@@ -546,6 +546,7 @@ $(eval $(call filter_Configuration_add_filters,fcfg_langpack,fcfg_calc_filters.x
calc8 \
calc8_template \
calc_MS_Excel_2007_XML \
calc_MS_Excel_2007_VBA_XML \
calc_MS_Excel_2007_XML_Template \
calc_MS_Excel_2007_Binary \
calc_OOXML \

View File

@@ -0,0 +1,30 @@
<!--
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* 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 .
-->
<node oor:name="Calc MS Excel 2007 VBA XML" oor:op="replace">
<prop oor:name="Flags"><value>IMPORT EXPORT ALIEN 3RDPARTYFILTER PREFERRED ENCRYPTION PASSWORDTOMODIFY</value></prop>
<prop oor:name="UIComponent"/>
<prop oor:name="FilterService"><value>com.sun.star.comp.oox.xls.ExcelFilter</value></prop>
<prop oor:name="UserData"><value>macro-enabled</value></prop>
<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>
<prop oor:name="UIName">
<value xml:lang="en-US">Microsoft Excel 2007-2016 XML (macro enabled)</value>
</prop>
</node>

View File

@@ -245,6 +245,7 @@ public:
virtual void SAL_CALL cancel()
throw( ::com::sun::star::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
bool exportVBA() const;
protected:
virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >

View File

@@ -148,6 +148,8 @@ struct FilterBaseImpl
Reference< XInteractionHandler > mxInteractionHandler;
Reference< XShape > mxParentShape;
bool mbExportVBA;
explicit FilterBaseImpl( const Reference< XComponentContext >& rxContext ) throw( RuntimeException );
void setDocumentModel( const Reference< XComponent >& rxComponent ) throw( IllegalArgumentException );
@@ -159,7 +161,8 @@ FilterBaseImpl::FilterBaseImpl( const Reference< XComponentContext >& rxContext
meDirection( FILTERDIRECTION_UNKNOWN ),
meVersion( ECMA_DIALECT ),
mxComponentContext( rxContext, UNO_SET_THROW ),
mxComponentFactory( rxContext->getServiceManager(), UNO_SET_THROW )
mxComponentFactory( rxContext->getServiceManager(), UNO_SET_THROW ),
mbExportVBA(false)
{
}
@@ -417,6 +420,30 @@ void SAL_CALL FilterBase::initialize( const Sequence< Any >& rArgs ) throw( Exce
catch( Exception& )
{
}
if (rArgs.getLength() >= 1)
{
Sequence<css::beans::PropertyValue> aSeq;
rArgs[0] >>= aSeq;
sal_Int32 nLen = aSeq.getLength();
for (sal_Int32 i = 0; i < nLen; ++i)
{
css::beans::PropertyValue& rVal = aSeq[i];
if (rVal.Name == "UserData")
{
css::uno::Sequence<OUString> aUserDataSeq;
rVal.Value >>= aUserDataSeq;
sal_Int32 nUserDataSeqLen = aUserDataSeq.getLength();
for (sal_Int32 j = 0; j < nUserDataSeqLen; ++j)
{
if (aUserDataSeq[j] == "macro-enabled")
{
mxImpl->mbExportVBA = true;
}
}
}
}
}
}
// com.sun.star.document.XImporter interface
@@ -553,6 +580,11 @@ GraphicHelper* FilterBase::implCreateGraphicHelper() const
return new GraphicHelper( mxImpl->mxComponentContext, mxImpl->mxTargetFrame, mxImpl->mxStorage );
}
bool FilterBase::exportVBA() const
{
return mxImpl->mbExportVBA;
}
} // namespace core
} // namespace oox

View File

@@ -928,9 +928,10 @@ sax_fastparser::FSHelperPtr XclXmlUtils::WriteFontData( sax_fastparser::FSHelper
return pStream;
}
XclExpXmlStream::XclExpXmlStream( const Reference< XComponentContext >& rCC )
XclExpXmlStream::XclExpXmlStream( const Reference< XComponentContext >& rCC, bool bExportVBA )
: XmlFilterBase( rCC ),
mpRoot( NULL )
mpRoot( NULL ),
mbExportVBA(bExportVBA)
{
}
@@ -1088,25 +1089,34 @@ bool XclExpXmlStream::exportDocument()
ScDocShell::GetViewData()->WriteExtOptions( mpRoot->GetExtDocOptions() );
OUString const workbook = "xl/workbook.xml";
const char* pWorkbookContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml";
if (mbExportVBA)
pWorkbookContentType = "application/vnd.ms-excel.sheet.macroEnabled.main+xml";
PushStream( CreateOutputStream( workbook, workbook,
Reference <XOutputStream>(),
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml",
pWorkbookContentType,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" ) );
VbaExport aExport(getModel());
if (aExport.containsVBAProject())
if (mbExportVBA)
{
SvMemoryStream aVbaStream(4096, 4096);
tools::SvRef<SotStorage> pVBAStorage(new SotStorage(aVbaStream));
aExport.exportVBA(pVBAStorage);
aVbaStream.Seek(0);
css::uno::Reference<css::io::XInputStream> xVBAStream(
new utl::OInputStreamWrapper(aVbaStream));
css::uno::Reference<css::io::XOutputStream> xVBAOutput =
openFragmentStream("xl/vbaProject.bin", "VBA");
comphelper::OStorageHelper::CopyInputToOutput(xVBAStream, xVBAOutput);
VbaExport aExport(getModel());
if (aExport.containsVBAProject())
{
SvMemoryStream aVbaStream(4096, 4096);
tools::SvRef<SotStorage> pVBAStorage(new SotStorage(aVbaStream));
aExport.exportVBA(pVBAStorage);
aVbaStream.Seek(0);
css::uno::Reference<css::io::XInputStream> xVBAStream(
new utl::OInputStreamWrapper(aVbaStream));
css::uno::Reference<css::io::XOutputStream> xVBAOutput =
openFragmentStream("xl/vbaProject.bin", "application/vnd.ms-office.vbaProject");
comphelper::OStorageHelper::CopyInputToOutput(xVBAStream, xVBAOutput);
addRelation(GetCurrentStream()->getOutputStream(), "http://schemas.microsoft.com/office/2006/relationships/vbaProject", "vbaProject.bin");
addRelation(GetCurrentStream()->getOutputStream(), "http://schemas.microsoft.com/office/2006/relationships/vbaProject", "vbaProject.bin");
}
}
// destruct at the end of the block

View File

@@ -293,7 +293,7 @@ public:
class XclExpXmlStream : public oox::core::XmlFilterBase
{
public:
XclExpXmlStream( const com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >& rCC );
XclExpXmlStream( const com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >& rCC, bool bExportVBA );
virtual ~XclExpXmlStream();
/** Returns the filter root data. */
@@ -374,6 +374,8 @@ private:
const XclExpRoot* mpRoot;
std::stack< sax_fastparser::FSHelperPtr > maStreams;
XclExpXmlPathToStateMap maOpenedStreamMap;
bool mbExportVBA;
};
#endif

View File

@@ -158,8 +158,9 @@ sal_Bool SAL_CALL ExcelFilter::filter( const ::com::sun::star::uno::Sequence< ::
if ( isExportFilter() )
{
bool bExportVBA = exportVBA();
Reference< XExporter > xExporter(
new XclExpXmlStream( getComponentContext() ) );
new XclExpXmlStream( getComponentContext(), bExportVBA ) );
Reference< XComponent > xDocument( getModel(), UNO_QUERY );
Reference< XFilter > xFilter( xExporter, UNO_QUERY );