summaryrefslogtreecommitdiffstats
path: root/sc/source/filter/excel/xedbdata.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/filter/excel/xedbdata.cxx')
-rw-r--r--sc/source/filter/excel/xedbdata.cxx261
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: */