diff options
Diffstat (limited to 'sc/source/filter/excel/xedbdata.cxx')
-rw-r--r-- | sc/source/filter/excel/xedbdata.cxx | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/sc/source/filter/excel/xedbdata.cxx b/sc/source/filter/excel/xedbdata.cxx new file mode 100644 index 000000000..350f6f70e --- /dev/null +++ b/sc/source/filter/excel/xedbdata.cxx @@ -0,0 +1,261 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + */ + +#include <xedbdata.hxx> +#include <excrecds.hxx> +#include <dbdata.hxx> +#include <document.hxx> +#include <oox/export/utils.hxx> +#include <oox/token/namespaces.hxx> + +using namespace oox; + +namespace { + +/** (So far) dummy implementation of table export for BIFF5/BIFF7. */ +class XclExpTablesImpl5 : public XclExpTables +{ +public: + explicit XclExpTablesImpl5( const XclExpRoot& rRoot ); + + virtual void Save( XclExpStream& rStrm ) override; + virtual void SaveXml( XclExpXmlStream& rStrm ) override; +}; + +/** Implementation of table export for OOXML, so far dummy for BIFF8. */ +class XclExpTablesImpl8 : public XclExpTables +{ +public: + explicit XclExpTablesImpl8( const XclExpRoot& rRoot ); + + virtual void Save( XclExpStream& rStrm ) override; + virtual void SaveXml( XclExpXmlStream& rStrm ) override; +}; + +} + +XclExpTablesImpl5::XclExpTablesImpl5( const XclExpRoot& rRoot ) : + XclExpTables( rRoot ) +{ +} + +void XclExpTablesImpl5::Save( XclExpStream& /*rStrm*/ ) +{ + // not implemented +} + +void XclExpTablesImpl5::SaveXml( XclExpXmlStream& /*rStrm*/ ) +{ + // not applicable +} + + +XclExpTablesImpl8::XclExpTablesImpl8( const XclExpRoot& rRoot ) : + XclExpTables( rRoot ) +{ +} + +void XclExpTablesImpl8::Save( XclExpStream& /*rStrm*/ ) +{ + // not implemented +} + +void XclExpTablesImpl8::SaveXml( XclExpXmlStream& rStrm ) +{ + + sax_fastparser::FSHelperPtr& pWorksheetStrm = rStrm.GetCurrentStream(); + pWorksheetStrm->startElement(XML_tableParts); + for (auto const& it : maTables) + { + OUString aRelId; + sax_fastparser::FSHelperPtr pTableStrm = rStrm.CreateOutputStream( + XclXmlUtils::GetStreamName("xl/tables/", "table", it.mnTableId), + XclXmlUtils::GetStreamName("../tables/", "table", it.mnTableId), + pWorksheetStrm->getOutputStream(), + CREATE_XL_CONTENT_TYPE("table"), + CREATE_OFFICEDOC_RELATION_TYPE("table"), + &aRelId); + + pWorksheetStrm->singleElement(XML_tablePart, FSNS(XML_r, XML_id), aRelId.toUtf8()); + + rStrm.PushStream( pTableStrm); + SaveTableXml( rStrm, it); + rStrm.PopStream(); + } + pWorksheetStrm->endElement( XML_tableParts); +} + + +XclExpTablesManager::XclExpTablesManager( const XclExpRoot& rRoot ) : + XclExpRoot( rRoot ) +{ +} + +XclExpTablesManager::~XclExpTablesManager() +{ +} + +void XclExpTablesManager::Initialize() +{ + // All non-const to be able to call RefreshTableColumnNames(). + ScDocument& rDoc = GetDoc(); + ScDBCollection* pDBColl = rDoc.GetDBCollection(); + if (!pDBColl) + return; + + ScDBCollection::NamedDBs& rDBs = pDBColl->getNamedDBs(); + if (rDBs.empty()) + return; + + sal_Int32 nTableId = 0; + for (const auto& rxDB : rDBs) + { + ScDBData* pDBData = rxDB.get(); + pDBData->RefreshTableColumnNames( &rDoc); // currently not in sync, so refresh + ScRange aRange( ScAddress::UNINITIALIZED); + pDBData->GetArea( aRange); + SCTAB nTab = aRange.aStart.Tab(); + TablesMapType::iterator it = maTablesMap.find( nTab); + if (it == maTablesMap.end()) + { + rtl::Reference< XclExpTables > pNew; + switch( GetBiff() ) + { + case EXC_BIFF5: + pNew = new XclExpTablesImpl5( GetRoot()); + break; + case EXC_BIFF8: + pNew = new XclExpTablesImpl8( GetRoot()); + break; + default: + assert(!"Unknown BIFF type!"); + continue; // for + } + ::std::pair< TablesMapType::iterator, bool > ins( maTablesMap.insert( ::std::make_pair( nTab, pNew))); + if (!ins.second) + { + assert(!"XclExpTablesManager::Initialize - XclExpTables insert failed"); + continue; // for + } + it = ins.first; + } + it->second->AppendTable( pDBData, ++nTableId); + } +} + +rtl::Reference< XclExpTables > XclExpTablesManager::GetTablesBySheet( SCTAB nTab ) +{ + TablesMapType::iterator it = maTablesMap.find(nTab); + return it == maTablesMap.end() ? nullptr : it->second; +} + +XclExpTables::Entry::Entry( const ScDBData* pData, sal_Int32 nTableId ) : + mpData(pData), mnTableId(nTableId) +{ +} + +XclExpTables::XclExpTables( const XclExpRoot& rRoot ) : + XclExpRoot(rRoot) +{ +} + +XclExpTables::~XclExpTables() +{ +} + +void XclExpTables::AppendTable( const ScDBData* pData, sal_Int32 nTableId ) +{ + maTables.emplace_back( pData, nTableId); +} + +void XclExpTables::SaveTableXml( XclExpXmlStream& rStrm, const Entry& rEntry ) +{ + const ScDBData& rData = *rEntry.mpData; + ScRange aRange( ScAddress::UNINITIALIZED); + rData.GetArea( aRange); + sax_fastparser::FSHelperPtr& pTableStrm = rStrm.GetCurrentStream(); + pTableStrm->startElement( XML_table, + XML_xmlns, rStrm.getNamespaceURL(OOX_NS(xls)).toUtf8(), + XML_id, OString::number( rEntry.mnTableId), + XML_name, rData.GetName().toUtf8(), + XML_displayName, rData.GetName().toUtf8(), + XML_ref, XclXmlUtils::ToOString(rStrm.GetRoot().GetDoc(), aRange), + XML_headerRowCount, ToPsz10(rData.HasHeader()), + XML_totalsRowCount, ToPsz10(rData.HasTotals()), + XML_totalsRowShown, ToPsz10(rData.HasTotals()) // we don't support that but if there are totals they are shown + // OOXTODO: XML_comment, ..., + // OOXTODO: XML_connectionId, ..., + // OOXTODO: XML_dataCellStyle, ..., + // OOXTODO: XML_dataDxfId, ..., + // OOXTODO: XML_headerRowBorderDxfId, ..., + // OOXTODO: XML_headerRowCellStyle, ..., + // OOXTODO: XML_headerRowDxfId, ..., + // OOXTODO: XML_insertRow, ..., + // OOXTODO: XML_insertRowShift, ..., + // OOXTODO: XML_published, ..., + // OOXTODO: XML_tableBorderDxfId, ..., + // OOXTODO: XML_tableType, ..., + // OOXTODO: XML_totalsRowBorderDxfId, ..., + // OOXTODO: XML_totalsRowCellStyle, ..., + // OOXTODO: XML_totalsRowDxfId, ... + ); + + if (rData.HasAutoFilter()) + { + /* TODO: does this need to exclude totals row? */ + + /* TODO: in OOXML 12.3.21 Table Definition Part has information + * that an applied autoFilter has child elements + * <af:filterColumn><af:filters><af:filter>. + * When not applied but buttons hidden, Excel writes, for example, + * <filterColumn colId="0" hiddenButton="1"/> */ + + ExcAutoFilterRecs aAutoFilter( rStrm.GetRoot(), aRange.aStart.Tab(), &rData); + aAutoFilter.SaveXml( rStrm); + } + + const std::vector< OUString >& rColNames = rData.GetTableColumnNames(); + if (!rColNames.empty()) + { + pTableStrm->startElement(XML_tableColumns, + XML_count, OString::number(aRange.aEnd.Col() - aRange.aStart.Col() + 1)); + + for (size_t i=0, n=rColNames.size(); i < n; ++i) + { + // OOXTODO: write <calculatedColumnFormula> once we support it, in + // which case we'd need start/endElement XML_tableColumn for such + // column. + + // OOXTODO: write <totalsRowFormula> once we support it. + + pTableStrm->singleElement( XML_tableColumn, + XML_id, OString::number(i+1), + XML_name, rColNames[i].toUtf8() + // OOXTODO: XML_dataCellStyle, ..., + // OOXTODO: XML_dataDxfId, ..., + // OOXTODO: XML_headerRowCellStyle, ..., + // OOXTODO: XML_headerRowDxfId, ..., + // OOXTODO: XML_queryTableFieldId, ..., + // OOXTODO: XML_totalsRowCellStyle, ..., + // OOXTODO: XML_totalsRowDxfId, ..., + // OOXTODO: XML_totalsRowFunction, ..., + // OOXTODO: XML_totalsRowLabel, ..., + // OOXTODO: XML_uniqueName, ... + ); + } + + pTableStrm->endElement( XML_tableColumns); + } + + // OOXTODO: write <tableStyleInfo> once we have table styles. + + pTableStrm->endElement( XML_table); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |