1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <xedbdata.hxx>
11 #include <excrecds.hxx>
13 #include <document.hxx>
14 #include <oox/export/utils.hxx>
15 #include <oox/token/namespaces.hxx>
21 /** (So far) dummy implementation of table export for BIFF5/BIFF7. */
22 class XclExpTablesImpl5
: public XclExpTables
25 explicit XclExpTablesImpl5( const XclExpRoot
& rRoot
);
27 virtual void Save( XclExpStream
& rStrm
) override
;
28 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
31 /** Implementation of table export for OOXML, so far dummy for BIFF8. */
32 class XclExpTablesImpl8
: public XclExpTables
35 explicit XclExpTablesImpl8( const XclExpRoot
& rRoot
);
37 virtual void Save( XclExpStream
& rStrm
) override
;
38 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
43 XclExpTablesImpl5::XclExpTablesImpl5( const XclExpRoot
& rRoot
) :
48 void XclExpTablesImpl5::Save( XclExpStream
& /*rStrm*/ )
53 void XclExpTablesImpl5::SaveXml( XclExpXmlStream
& /*rStrm*/ )
59 XclExpTablesImpl8::XclExpTablesImpl8( const XclExpRoot
& rRoot
) :
64 void XclExpTablesImpl8::Save( XclExpStream
& /*rStrm*/ )
69 void XclExpTablesImpl8::SaveXml( XclExpXmlStream
& rStrm
)
72 sax_fastparser::FSHelperPtr
& pWorksheetStrm
= rStrm
.GetCurrentStream();
73 pWorksheetStrm
->startElement(XML_tableParts
);
74 for (auto const& it
: maTables
)
77 sax_fastparser::FSHelperPtr pTableStrm
= rStrm
.CreateOutputStream(
78 XclXmlUtils::GetStreamName("xl/tables/", "table", it
.mnTableId
),
79 XclXmlUtils::GetStreamName("../tables/", "table", it
.mnTableId
),
80 pWorksheetStrm
->getOutputStream(),
81 CREATE_XL_CONTENT_TYPE("table"),
82 CREATE_OFFICEDOC_RELATION_TYPE("table"),
85 pWorksheetStrm
->singleElement(XML_tablePart
, FSNS(XML_r
, XML_id
), aRelId
.toUtf8());
87 rStrm
.PushStream( pTableStrm
);
88 SaveTableXml( rStrm
, it
);
91 pWorksheetStrm
->endElement( XML_tableParts
);
95 XclExpTablesManager::XclExpTablesManager( const XclExpRoot
& rRoot
) :
100 XclExpTablesManager::~XclExpTablesManager()
104 void XclExpTablesManager::Initialize()
106 // All non-const to be able to call RefreshTableColumnNames().
107 ScDocument
& rDoc
= GetDoc();
108 ScDBCollection
* pDBColl
= rDoc
.GetDBCollection();
112 ScDBCollection::NamedDBs
& rDBs
= pDBColl
->getNamedDBs();
116 sal_Int32 nTableId
= 0;
117 for (const auto& rxDB
: rDBs
)
119 ScDBData
* pDBData
= rxDB
.get();
120 pDBData
->RefreshTableColumnNames( &rDoc
); // currently not in sync, so refresh
121 ScRange
aRange( ScAddress::UNINITIALIZED
);
122 pDBData
->GetArea( aRange
);
123 SCTAB nTab
= aRange
.aStart
.Tab();
124 TablesMapType::iterator it
= maTablesMap
.find( nTab
);
125 if (it
== maTablesMap
.end())
127 rtl::Reference
< XclExpTables
> pNew
;
131 pNew
= new XclExpTablesImpl5( GetRoot());
134 pNew
= new XclExpTablesImpl8( GetRoot());
137 assert(!"Unknown BIFF type!");
140 ::std::pair
< TablesMapType::iterator
, bool > ins( maTablesMap
.insert( ::std::make_pair( nTab
, pNew
)));
143 assert(!"XclExpTablesManager::Initialize - XclExpTables insert failed");
148 it
->second
->AppendTable( pDBData
, ++nTableId
);
152 rtl::Reference
< XclExpTables
> XclExpTablesManager::GetTablesBySheet( SCTAB nTab
)
154 TablesMapType::iterator it
= maTablesMap
.find(nTab
);
155 return it
== maTablesMap
.end() ? nullptr : it
->second
;
158 XclExpTables::Entry::Entry( const ScDBData
* pData
, sal_Int32 nTableId
) :
159 mpData(pData
), mnTableId(nTableId
)
163 XclExpTables::XclExpTables( const XclExpRoot
& rRoot
) :
168 XclExpTables::~XclExpTables()
172 void XclExpTables::AppendTable( const ScDBData
* pData
, sal_Int32 nTableId
)
174 maTables
.emplace_back( pData
, nTableId
);
177 void XclExpTables::SaveTableXml( XclExpXmlStream
& rStrm
, const Entry
& rEntry
)
179 const ScDBData
& rData
= *rEntry
.mpData
;
180 ScRange
aRange( ScAddress::UNINITIALIZED
);
181 rData
.GetArea( aRange
);
182 sax_fastparser::FSHelperPtr
& pTableStrm
= rStrm
.GetCurrentStream();
183 pTableStrm
->startElement( XML_table
,
184 XML_xmlns
, rStrm
.getNamespaceURL(OOX_NS(xls
)).toUtf8(),
185 XML_id
, OString::number( rEntry
.mnTableId
),
186 XML_name
, rData
.GetName().toUtf8(),
187 XML_displayName
, rData
.GetName().toUtf8(),
188 XML_ref
, XclXmlUtils::ToOString(rStrm
.GetRoot().GetDoc(), aRange
),
189 XML_headerRowCount
, ToPsz10(rData
.HasHeader()),
190 XML_totalsRowCount
, ToPsz10(rData
.HasTotals()),
191 XML_totalsRowShown
, ToPsz10(rData
.HasTotals()) // we don't support that but if there are totals they are shown
192 // OOXTODO: XML_comment, ...,
193 // OOXTODO: XML_connectionId, ...,
194 // OOXTODO: XML_dataCellStyle, ...,
195 // OOXTODO: XML_dataDxfId, ...,
196 // OOXTODO: XML_headerRowBorderDxfId, ...,
197 // OOXTODO: XML_headerRowCellStyle, ...,
198 // OOXTODO: XML_headerRowDxfId, ...,
199 // OOXTODO: XML_insertRow, ...,
200 // OOXTODO: XML_insertRowShift, ...,
201 // OOXTODO: XML_published, ...,
202 // OOXTODO: XML_tableBorderDxfId, ...,
203 // OOXTODO: XML_tableType, ...,
204 // OOXTODO: XML_totalsRowBorderDxfId, ...,
205 // OOXTODO: XML_totalsRowCellStyle, ...,
206 // OOXTODO: XML_totalsRowDxfId, ...
209 if (rData
.HasAutoFilter())
211 /* TODO: does this need to exclude totals row? */
213 /* TODO: in OOXML 12.3.21 Table Definition Part has information
214 * that an applied autoFilter has child elements
215 * <af:filterColumn><af:filters><af:filter>.
216 * When not applied but buttons hidden, Excel writes, for example,
217 * <filterColumn colId="0" hiddenButton="1"/> */
219 ExcAutoFilterRecs
aAutoFilter( rStrm
.GetRoot(), aRange
.aStart
.Tab(), &rData
);
220 aAutoFilter
.SaveXml( rStrm
);
223 const std::vector
< OUString
>& rColNames
= rData
.GetTableColumnNames();
224 const std::vector
< TableColumnAttributes
>& rColAttributes
= rData
.GetTableColumnAttributes();
225 if (!rColNames
.empty())
227 pTableStrm
->startElement(XML_tableColumns
,
228 XML_count
, OString::number(aRange
.aEnd
.Col() - aRange
.aStart
.Col() + 1));
230 for (size_t i
=0, n
=rColNames
.size(); i
< n
; ++i
)
232 // OOXTODO: write <calculatedColumnFormula> once we support it, in
233 // which case we'd need start/endElement XML_tableColumn for such
236 // OOXTODO: write <totalsRowFormula> once we support it.
238 pTableStrm
->singleElement( XML_tableColumn
,
239 XML_id
, OString::number(i
+1),
240 XML_name
, rColNames
[i
].toUtf8(),
241 XML_totalsRowFunction
, (i
< rColAttributes
.size() ? rColAttributes
[i
].maTotalsFunction
: std::nullopt
)
242 // OOXTODO: XML_dataCellStyle, ...,
243 // OOXTODO: XML_dataDxfId, ...,
244 // OOXTODO: XML_headerRowCellStyle, ...,
245 // OOXTODO: XML_headerRowDxfId, ...,
246 // OOXTODO: XML_queryTableFieldId, ...,
247 // OOXTODO: XML_totalsRowCellStyle, ...,
248 // OOXTODO: XML_totalsRowDxfId, ...,
249 // OOXTODO: XML_totalsRowLabel, ...,
250 // OOXTODO: XML_uniqueName, ...
254 pTableStrm
->endElement( XML_tableColumns
);
257 // OOXTODO: write <tableStyleInfo> once we have table styles.
259 pTableStrm
->endElement( XML_table
);
262 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */