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"
12 #include "xltools.hxx"
14 #include "document.hxx"
15 #include <oox/export/utils.hxx>
19 /** (So far) dummy implementation of table export for BIFF5/BIFF7. */
20 class XclExpTablesImpl5
: public XclExpTables
23 explicit XclExpTablesImpl5( const XclExpRoot
& rRoot
);
24 virtual ~XclExpTablesImpl5();
26 virtual void Save( XclExpStream
& rStrm
) override
;
27 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
30 /** Implementation of table export for OOXML, so far dummy for BIFF8. */
31 class XclExpTablesImpl8
: public XclExpTables
34 explicit XclExpTablesImpl8( const XclExpRoot
& rRoot
);
35 virtual ~XclExpTablesImpl8();
37 virtual void Save( XclExpStream
& rStrm
) override
;
38 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
42 XclExpTablesImpl5::XclExpTablesImpl5( const XclExpRoot
& rRoot
) :
47 XclExpTablesImpl5::~XclExpTablesImpl5()
51 void XclExpTablesImpl5::Save( XclExpStream
& /*rStrm*/ )
56 void XclExpTablesImpl5::SaveXml( XclExpXmlStream
& /*rStrm*/ )
62 XclExpTablesImpl8::XclExpTablesImpl8( const XclExpRoot
& rRoot
) :
67 XclExpTablesImpl8::~XclExpTablesImpl8()
71 void XclExpTablesImpl8::Save( XclExpStream
& /*rStrm*/ )
76 void XclExpTablesImpl8::SaveXml( XclExpXmlStream
& rStrm
)
79 sax_fastparser::FSHelperPtr
& pWorksheetStrm
= rStrm
.GetCurrentStream();
80 pWorksheetStrm
->startElement( XML_tableParts
, FSEND
);
81 for (auto const& it
: maTables
)
84 sax_fastparser::FSHelperPtr pTableStrm
= rStrm
.CreateOutputStream(
85 XclXmlUtils::GetStreamName("xl/tables/", "table", it
.mnTableId
),
86 XclXmlUtils::GetStreamName("../tables/", "table", it
.mnTableId
),
87 pWorksheetStrm
->getOutputStream(),
88 CREATE_XL_CONTENT_TYPE("table"),
89 CREATE_OFFICEDOC_RELATION_TYPE("table"),
92 pWorksheetStrm
->singleElement( XML_tablePart
,
93 FSNS(XML_r
, XML_id
), XclXmlUtils::ToOString(aRelId
).getStr(),
96 rStrm
.PushStream( pTableStrm
);
97 SaveTableXml( rStrm
, it
);
100 pWorksheetStrm
->endElement( XML_tableParts
);
104 XclExpTablesManager::XclExpTablesManager( const XclExpRoot
& rRoot
) :
109 XclExpTablesManager::~XclExpTablesManager()
113 void XclExpTablesManager::Initialize()
115 // All non-const to be able to call RefreshTableColumnNames().
116 ScDocument
& rDoc
= GetDoc();
117 ScDBCollection
* pDBColl
= rDoc
.GetDBCollection();
121 ScDBCollection::NamedDBs
& rDBs
= pDBColl
->getNamedDBs();
125 sal_Int32 nTableId
= 0;
126 for (ScDBCollection::NamedDBs::iterator
itDB(rDBs
.begin()); itDB
!= rDBs
.end(); ++itDB
)
128 ScDBData
* pDBData
= itDB
->get();
129 pDBData
->RefreshTableColumnNames( &rDoc
); // currently not in sync, so refresh
130 ScRange
aRange( ScAddress::UNINITIALIZED
);
131 pDBData
->GetArea( aRange
);
132 SCTAB nTab
= aRange
.aStart
.Tab();
133 TablesMapType::iterator it
= maTablesMap
.find( nTab
);
134 if (it
== maTablesMap
.end())
136 ::std::shared_ptr
< XclExpTables
> pNew
;
140 pNew
.reset( new XclExpTablesImpl5( GetRoot()));
143 pNew
.reset( new XclExpTablesImpl8( GetRoot()));
146 assert(!"Unknown BIFF type!");
149 ::std::pair
< TablesMapType::iterator
, bool > ins( maTablesMap
.insert( ::std::make_pair( nTab
, pNew
)));
152 assert(!"XclExpTablesManager::Initialize - XclExpTables insert failed");
157 it
->second
->AppendTable( pDBData
, ++nTableId
);
161 ::std::shared_ptr
< XclExpTables
> XclExpTablesManager::GetTablesBySheet( SCTAB nTab
)
163 TablesMapType::iterator it
= maTablesMap
.find(nTab
);
164 return it
== maTablesMap
.end() ? nullptr : it
->second
;
167 XclExpTables::Entry::Entry( const ScDBData
* pData
, sal_Int32 nTableId
) :
168 mpData(pData
), mnTableId(nTableId
)
172 XclExpTables::XclExpTables( const XclExpRoot
& rRoot
) :
177 XclExpTables::~XclExpTables()
181 void XclExpTables::AppendTable( const ScDBData
* pData
, sal_Int32 nTableId
)
183 maTables
.push_back( Entry( pData
, nTableId
));
186 void XclExpTables::SaveTableXml( XclExpXmlStream
& rStrm
, const Entry
& rEntry
)
188 const ScDBData
& rData
= *rEntry
.mpData
;
189 ScRange
aRange( ScAddress::UNINITIALIZED
);
190 rData
.GetArea( aRange
);
191 sax_fastparser::FSHelperPtr
& pTableStrm
= rStrm
.GetCurrentStream();
192 pTableStrm
->startElement( XML_table
,
193 XML_xmlns
, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
194 XML_id
, OString::number( rEntry
.mnTableId
).getStr(),
195 XML_name
, XclXmlUtils::ToOString( rData
.GetName()).getStr(),
196 XML_displayName
, XclXmlUtils::ToOString( rData
.GetName()).getStr(),
197 XML_ref
, XclXmlUtils::ToOString(aRange
),
198 XML_headerRowCount
, BS(rData
.HasHeader()),
199 XML_totalsRowCount
, BS(rData
.HasTotals()),
200 XML_totalsRowShown
, BS(rData
.HasTotals()), // we don't support that but if there are totals they are shown
201 // OOXTODO: XML_comment, ...,
202 // OOXTODO: XML_connectionId, ...,
203 // OOXTODO: XML_dataCellStyle, ...,
204 // OOXTODO: XML_dataDxfId, ...,
205 // OOXTODO: XML_headerRowBorderDxfId, ...,
206 // OOXTODO: XML_headerRowCellStyle, ...,
207 // OOXTODO: XML_headerRowDxfId, ...,
208 // OOXTODO: XML_insertRow, ...,
209 // OOXTODO: XML_insertRowShift, ...,
210 // OOXTODO: XML_published, ...,
211 // OOXTODO: XML_tableBorderDxfId, ...,
212 // OOXTODO: XML_tableType, ...,
213 // OOXTODO: XML_totalsRowBorderDxfId, ...,
214 // OOXTODO: XML_totalsRowCellStyle, ...,
215 // OOXTODO: XML_totalsRowDxfId, ...,
218 if (rData
.HasAutoFilter())
220 /* TODO: does this need to exclude totals row? */
222 /* TODO: in OOXML 12.3.21 Table Definition Part has information
223 * that an applied autoFilter has child elements
224 * <af:filterColumn><af:filters><af:filter>.
225 * When not applied but buttons hidden, Excel writes, for example,
226 * <filterColumn colId="0" hiddenButton="1"/> */
228 ExcAutoFilterRecs
aAutoFilter( rStrm
.GetRoot(), aRange
.aStart
.Tab(), &rData
);
229 aAutoFilter
.SaveXml( rStrm
);
232 const std::vector
< OUString
>& rColNames
= rData
.GetTableColumnNames();
233 if (!rColNames
.empty())
235 pTableStrm
->startElement( XML_tableColumns
,
236 XML_count
, OString::number( aRange
.aEnd
.Col() - aRange
.aStart
.Col() + 1).getStr(),
239 for (size_t i
=0, n
=rColNames
.size(); i
< n
; ++i
)
241 // OOXTODO: write <calculatedColumnFormula> once we support it, in
242 // which case we'd need start/endElement XML_tableColumn for such
245 // OOXTODO: write <totalsRowFormula> once we support it.
247 pTableStrm
->singleElement( XML_tableColumn
,
248 XML_id
, OString::number(i
+1).getStr(),
249 XML_name
, OUStringToOString( rColNames
[i
], RTL_TEXTENCODING_UTF8
).getStr(),
250 // OOXTODO: XML_dataCellStyle, ...,
251 // OOXTODO: XML_dataDxfId, ...,
252 // OOXTODO: XML_headerRowCellStyle, ...,
253 // OOXTODO: XML_headerRowDxfId, ...,
254 // OOXTODO: XML_queryTableFieldId, ...,
255 // OOXTODO: XML_totalsRowCellStyle, ...,
256 // OOXTODO: XML_totalsRowDxfId, ...,
257 // OOXTODO: XML_totalsRowFunction, ...,
258 // OOXTODO: XML_totalsRowLabel, ...,
259 // OOXTODO: XML_uniqueName, ...,
263 pTableStrm
->endElement( XML_tableColumns
);
266 // OOXTODO: write <tableStyleInfo> once we have table styles.
268 pTableStrm
->endElement( XML_table
);
271 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */