1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef SC_XEPIVOT_HXX 25 #define SC_XEPIVOT_HXX 26 27 #include <map> 28 #include "xerecord.hxx" 29 #include "xlpivot.hxx" 30 #include "xeroot.hxx" 31 32 class ScDPObject; 33 class ScDPSaveData; 34 class ScDPSaveDimension; 35 class ScDPSaveMember; 36 class ScDPDimensionSaveData; 37 class ScDPSaveGroupDimension; 38 class ScDPSaveNumGroupDimension; 39 struct ScDPNumGroupInfo; 40 41 // ============================================================================ 42 // Pivot cache 43 // ============================================================================ 44 45 /** Represents a data item in a pivot cache containing data of any type. */ 46 class XclExpPCItem : public XclExpRecord, public XclPCItem 47 { 48 public: 49 explicit XclExpPCItem( const String& rText ); 50 explicit XclExpPCItem( double fValue ); 51 explicit XclExpPCItem( const DateTime& rDateTime ); 52 explicit XclExpPCItem( sal_Int16 nValue ); 53 explicit XclExpPCItem( bool bValue ); 54 GetTypeFlag() const55 inline sal_uInt16 GetTypeFlag() const { return mnTypeFlag; } 56 57 bool EqualsText( const String& rText ) const; 58 bool EqualsDouble( double fValue ) const; 59 bool EqualsDateTime( const DateTime& rDateTime ) const; 60 bool EqualsBool( bool bValue ) const; 61 62 private: 63 virtual void WriteBody( XclExpStream& rStrm ); 64 65 private: 66 sal_uInt16 mnTypeFlag; /// Data type flag. 67 }; 68 69 // ============================================================================ 70 71 class XclExpPivotCache; 72 73 class XclExpPCField : public XclExpRecord, public XclPCField, protected XclExpRoot 74 { 75 public: 76 /** Creates a standard pivot cache field, filled from sheet source data. */ 77 explicit XclExpPCField( const XclExpRoot& rRoot, 78 const XclExpPivotCache& rPCache, sal_uInt16 nFieldIdx, 79 const ScDPObject& rDPObj, const ScRange& rRange ); 80 /** Creates a child grouping pivot cache field, filled from the passed grouping info. */ 81 explicit XclExpPCField( const XclExpRoot& rRoot, 82 const XclExpPivotCache& rPCache, sal_uInt16 nFieldIdx, 83 const ScDPObject& rDPObj, const ScDPSaveGroupDimension& rGroupDim, 84 const XclExpPCField& rBaseField ); 85 virtual ~XclExpPCField(); 86 87 /** Sets the passed field as direct grouping child field of this field. */ 88 void SetGroupChildField( const XclExpPCField& rChildField ); 89 /** Converts this standard field into a numeric grouping field. */ 90 void ConvertToNumGroup( const ScDPObject& rDPObj, const ScDPSaveNumGroupDimension& rNumGroupDim ); 91 92 /** Returns the name of this cache field. */ GetFieldName() const93 inline const String& GetFieldName() const { return maFieldInfo.maName; } 94 95 /** Returns the number of visible items of this field. */ 96 sal_uInt16 GetItemCount() const; 97 /** Returns the specified pivot cache item (returns visible items in groupings). */ 98 const XclExpPCItem* GetItem( sal_uInt16 nItemIdx ) const; 99 /** Returns the index of a pivot cache item, or EXC_PC_NOITEM on error. */ 100 sal_uInt16 GetItemIndex( const String& rItemName ) const; 101 102 /** Returns the size an item index needs to write out. */ 103 sal_Size GetIndexSize() const; 104 /** Writes the item index at the passed source row position as part of the SXINDEXLIST record. */ 105 void WriteIndex( XclExpStream& rStrm, sal_uInt32 nSrcRow ) const; 106 107 /** Writes the pivot cache field and all items and other related records. */ 108 virtual void Save( XclExpStream& rStrm ); 109 110 private: 111 typedef XclExpRecordList< XclExpPCItem > XclExpPCItemList; 112 113 /** Returns the item list that contains the visible items. 114 @descr Visible items are equal to source items in standard fields, 115 but are generated items in grouping and calculated fields. */ 116 const XclExpPCItemList& GetVisItemList() const; 117 118 /** Initializes a standard field. Inserts all original source items. */ 119 void InitStandardField( const ScRange& rRange ); 120 /** Initializes a standard grouping field. Inserts all visible grouping items. */ 121 void InitStdGroupField( const XclExpPCField& rBaseField, const ScDPSaveGroupDimension& rGroupDim ); 122 /** Initializes a numeric grouping field. Inserts all visible grouping items and the limit settings. */ 123 void InitNumGroupField( const ScDPObject& rDPObj, const ScDPNumGroupInfo& rNumInfo ); 124 /** Initializes a date grouping field. Inserts all visible grouping items and the limit settings. */ 125 void InitDateGroupField( const ScDPObject& rDPObj, const ScDPNumGroupInfo& rDateInfo, sal_Int32 nDatePart ); 126 127 /** Inserts the passed index into the item index array of original items. */ 128 void InsertItemArrayIndex( size_t nListPos ); 129 /** Inserts an original source item. Updates item index array. */ 130 void InsertOrigItem( XclExpPCItem* pNewItem ); 131 /** Inserts an original text item, if it is not contained already. */ 132 void InsertOrigTextItem( const String& rText ); 133 /** Inserts an original value item, if it is not contained already. */ 134 void InsertOrigDoubleItem( double fValue ); 135 /** Inserts an original date/time item, if it is not contained already. */ 136 void InsertOrigDateTimeItem( const DateTime& rDateTime ); 137 /** Inserts an original boolean item, if it is not contained already. */ 138 void InsertOrigBoolItem( bool bValue ); 139 140 /** Inserts an item into the grouping item list. Does not change anything else. 141 @return The list index of the new item. */ 142 sal_uInt16 InsertGroupItem( XclExpPCItem* pNewItem ); 143 /** Generates and inserts all visible items for numeric or date grouping. */ 144 void InsertNumDateGroupItems( const ScDPObject& rDPObj, const ScDPNumGroupInfo& rNumInfo, sal_Int32 nDatePart = 0 ); 145 146 /** Inserts the SXDOUBLE items that specify the limits for a numeric grouping. */ 147 void SetNumGroupLimit( const ScDPNumGroupInfo& rNumInfo ); 148 /** Inserts the SXDATETIME/SXINTEGER items that specify the limits for a date grouping. 149 @param bUseStep true = Insert the passed step value; false = always insert 1. */ 150 void SetDateGroupLimit( const ScDPNumGroupInfo& rDateInfo, bool bUseStep ); 151 152 /** Initializes flags and item count fields. */ 153 void Finalize(); 154 155 /** Writes an SXNUMGROUP record and the additional items for a numeric grouping field. */ 156 void WriteSxnumgroup( XclExpStream& rStrm ); 157 /** Writes an SXGROUPINFO record describing the item order in grouping fields. */ 158 void WriteSxgroupinfo( XclExpStream& rStrm ); 159 160 /** Writes the contents of the SXFIELD record for this field. */ 161 virtual void WriteBody( XclExpStream& rStrm ); 162 163 private: 164 const XclExpPivotCache& mrPCache; /// Parent pivot cache containing this field. 165 XclExpPCItemList maOrigItemList; /// List with original items. 166 XclExpPCItemList maGroupItemList; /// List with grouping items. 167 ScfUInt16Vec maIndexVec; /// Indexes into maItemList. 168 XclExpPCItemList maNumGroupLimits; /// List with limit values for numeric grouping. 169 sal_uInt16 mnTypeFlags; /// Collected item data type flags. 170 }; 171 172 // ============================================================================ 173 174 class XclExpPivotCache : protected XclExpRoot 175 { 176 public: 177 explicit XclExpPivotCache( const XclExpRoot& rRoot, 178 const ScDPObject& rDPObj, sal_uInt16 nListIdx ); 179 180 /** Returns true, if the cache has been constructed successfully. */ IsValid() const181 inline bool IsValid() const { return mbValid; } 182 /** Returns true, if the item index list will be written. */ 183 bool HasItemIndexList() const; 184 185 /** Returns the stream identifier used to create the cache stream. */ GetStreamId() const186 inline sal_uInt16 GetStreamId() const { return maPCInfo.mnStrmId; } 187 /** Returns the list index of the cache used in pivot table records. */ GetCacheIndex() const188 inline sal_uInt16 GetCacheIndex() const { return mnListIdx; } 189 190 /** Returns the number of pivot cache fields. */ 191 sal_uInt16 GetFieldCount() const; 192 /** Returns the specified pivot cache field. */ 193 const XclExpPCField* GetField( sal_uInt16 nFieldIdx ) const; 194 //UNUSED2009-05 /** Returns a pivot cache field by its name. */ 195 //UNUSED2009-05 const XclExpPCField* GetField( const String& rFieldName ) const; 196 /** Returns true, if this pivot cache contains non-standard fields (e.g. grouping fields). */ 197 bool HasAddFields() const; 198 199 /** Returns true, if the passed DP object has the same data source as this cache. */ 200 bool HasEqualDataSource( const ScDPObject& rDPObj ) const; 201 202 /** Writes related records into Workbook stream and creates the pivot cache storage stream. */ 203 virtual void Save( XclExpStream& rStrm ); 204 virtual void SaveXml( XclExpXmlStream& rStrm ); 205 206 private: 207 /** Returns read/write access to a pivot cache field. */ 208 XclExpPCField* GetFieldAcc( sal_uInt16 nFieldIdx ); 209 /** Returns read/write access to a pivot cache field. */ 210 XclExpPCField* GetFieldAcc( const String& rFieldName ); 211 212 /** Adds all pivot cache fields. */ 213 void AddFields( const ScDPObject& rDPObj ); 214 215 /** Adds all standard pivot cache fields based on source data. */ 216 void AddStdFields( const ScDPObject& rDPObj ); 217 /** Adds all grouping pivot cache fields. */ 218 void AddGroupFields( const ScDPObject& rDPObj ); 219 /** Adds all calculated pivot cache fields. */ 220 void AddCalcFields( const ScDPObject& rDPObj ); 221 222 /** Writes the DCONREF record containing the source range. */ 223 void WriteDconref( XclExpStream& rStrm ) const; 224 225 /** Creates the pivot cache storage stream and writes the cache. */ 226 void WriteCacheStream(); 227 /** Writes the SXDB record. */ 228 void WriteSxdb( XclExpStream& rStrm ) const; 229 /** Writes the SXDBEX record. */ 230 void WriteSxdbex( XclExpStream& rStrm ) const; 231 /** Writes the SXINDEXLIST record list containing the item index table. */ 232 void WriteSxindexlistList( XclExpStream& rStrm ) const; 233 234 private: 235 typedef XclExpRecordList< XclExpPCField > XclExpPCFieldList; 236 typedef XclExpPCFieldList::RecordRefType XclExpPCFieldRef; 237 238 XclPCInfo maPCInfo; /// Pivot cache settings (SXDB record). 239 XclExpPCFieldList maFieldList; /// List of all pivot cache fields. 240 String maTabName; /// Name of source data sheet. 241 ScRange maOrigSrcRange; /// The original sheet source range. 242 ScRange maExpSrcRange; /// The exported sheet source range. 243 ScRange maDocSrcRange; /// The range used to build the cache fields and items. 244 sal_uInt16 mnListIdx; /// List index in pivot cache buffer. 245 bool mbValid; /// true = The cache is valid for export. 246 }; 247 248 // ============================================================================ 249 // Pivot table 250 // ============================================================================ 251 252 class XclExpPivotTable; 253 254 /** Data field position specifying the pivot table field index (first) and data info index (second). */ 255 typedef ::std::pair< sal_uInt16, sal_uInt16 > XclPTDataFieldPos; 256 257 // ============================================================================ 258 259 class XclExpPTItem : public XclExpRecord 260 { 261 public: 262 explicit XclExpPTItem( const XclExpPCField& rCacheField, sal_uInt16 nCacheIdx ); 263 explicit XclExpPTItem( sal_uInt16 nItemType, sal_uInt16 nCacheIdx, bool bUseCache ); 264 265 /** Returns the internal name of this item. */ 266 const String& GetItemName() const; 267 268 /** Fills this item with properties from the passed save member. */ 269 void SetPropertiesFromMember( const ScDPSaveMember& rSaveMem ); 270 271 private: 272 /** Writes the SXVI record body describing the pivot table item. */ 273 virtual void WriteBody( XclExpStream& rStrm ); 274 275 private: 276 const XclExpPCItem* mpCacheItem; /// The referred pivot cache item. 277 XclPTItemInfo maItemInfo; /// General data for this item. 278 }; 279 280 // ============================================================================ 281 282 class XclExpPTField : public XclExpRecordBase 283 { 284 public: 285 explicit XclExpPTField( const XclExpPivotTable& rPTable, sal_uInt16 nCacheIdx ); 286 287 // data access ------------------------------------------------------------ 288 289 /** Returns the name of this field. */ 290 const String& GetFieldName() const; 291 /** Returns the pivot table field list index of this field. */ 292 sal_uInt16 GetFieldIndex() const; 293 294 /** Returns the index of the last inserted data info struct. */ 295 sal_uInt16 GetLastDataInfoIndex() const; 296 297 //UNUSED2009-05 /** Returns an item by its name. */ 298 //UNUSED2009-05 const XclExpPTItem* GetItem( const String& rName ) const; 299 /** Returns the list index of an item by its name. 300 @param nDefaultIdx This value will be returned, if the item could not be found. */ 301 sal_uInt16 GetItemIndex( const String& rName, sal_uInt16 nDefaultIdx ) const; 302 303 // fill data -------------------------------------------------------------- 304 305 /** Fills this field with row/column/page properties from the passed save dimension. */ 306 void SetPropertiesFromDim( const ScDPSaveDimension& rSaveDim ); 307 /** Fills this field with data field properties from the passed save dimension. */ 308 void SetDataPropertiesFromDim( const ScDPSaveDimension& rSaveDim ); 309 310 /** Appends special items describing the field subtotal entries. */ 311 void AppendSubtotalItems(); 312 313 // records ---------------------------------------------------------------- 314 315 /** Writes an entry for an SXPI record containing own page field info. */ 316 void WriteSxpiEntry( XclExpStream& rStrm ) const; 317 /** Writes an SXDI records containing info about a data field. */ 318 void WriteSxdi( XclExpStream& rStrm, sal_uInt16 nDataInfoIdx ) const; 319 320 /** Writes the entire pivot table field. */ 321 virtual void Save( XclExpStream& rStrm ); 322 323 // ------------------------------------------------------------------------ 324 private: 325 /** Returns an item by its name. */ 326 XclExpPTItem* GetItemAcc( const String& rName ); 327 328 /** Appends a special item describing a field subtotal entry. */ 329 void AppendSubtotalItem( sal_uInt16 nItemType ); 330 331 /** Writes the SXVD record introducing the field. */ 332 void WriteSxvd( XclExpStream& rStrm ) const; 333 /** Writes the SXVDEX record containing additional settings. */ 334 void WriteSxvdex( XclExpStream& rStrm ) const; 335 336 private: 337 typedef ::std::vector< XclPTDataFieldInfo > XclPTDataFieldInfoVec; 338 typedef XclExpRecordList< XclExpPTItem > XclExpPTItemList; 339 340 const XclExpPivotTable& mrPTable; /// Parent pivot table containing this field. 341 const XclExpPCField* mpCacheField; /// The referred pivot cache field. 342 XclPTFieldInfo maFieldInfo; /// General field info (SXVD record). 343 XclPTFieldExtInfo maFieldExtInfo; /// Extended field info (SXVDEX record). 344 XclPTPageFieldInfo maPageInfo; /// Page field info (entry in SXPI record). 345 XclPTDataFieldInfoVec maDataInfoVec; /// List of extended data field info (SXDI records). 346 XclExpPTItemList maItemList; /// List of all items of this field. 347 }; 348 349 // ============================================================================ 350 351 class XclExpPivotTable : public XclExpRecordBase, protected XclExpRoot 352 { 353 public: 354 explicit XclExpPivotTable( const XclExpRoot& rRoot, 355 const ScDPObject& rDPObj, const XclExpPivotCache& rPCache ); 356 357 /** Returns a pivot cache field. */ 358 const XclExpPCField* GetCacheField( sal_uInt16 nCacheIdx ) const; 359 360 /** Returns the output range of the pivot table. */ GetScTab() const361 inline SCTAB GetScTab() const { return mnOutScTab; } 362 363 /** Returns a pivot table field by its name. */ 364 const XclExpPTField* GetField( sal_uInt16 nFieldIdx ) const; 365 /** Returns a pivot table field by its name. */ 366 const XclExpPTField* GetField( const String& rName ) const; 367 368 /** Returns the data-field-only index of the first data field with the passed name. 369 @param nDefaultIdx This value will be returned, if the field could not be found. */ 370 sal_uInt16 GetDataFieldIndex( const String& rName, sal_uInt16 nDefaultIdx ) const; 371 372 /** Writes the entire pivot table. */ 373 virtual void Save( XclExpStream& rStrm ); 374 375 // ------------------------------------------------------------------------ 376 private: 377 /** Returns a pivot table field by its name. */ 378 XclExpPTField* GetFieldAcc( const String& rName ); 379 /** Returns a pivot table field corresponding to the passed save dimension. */ 380 XclExpPTField* GetFieldAcc( const ScDPSaveDimension& rSaveDim ); 381 382 // fill data -------------------------------------------------------------- 383 384 /** Fills internal members with all properties from the passed save data. */ 385 void SetPropertiesFromDP( const ScDPSaveData& rSaveData ); 386 /** Fills a pivot table field with all properties from the passed save dimension. */ 387 void SetFieldPropertiesFromDim( const ScDPSaveDimension& rSaveDim ); 388 /** Fills a pivot table data field with all properties from the passed save dimension. */ 389 void SetDataFieldPropertiesFromDim( const ScDPSaveDimension& rSaveDim ); 390 391 /** Initializes any data after processing the entire source DataPilot. */ 392 void Finalize(); 393 394 // records ---------------------------------------------------------------- 395 396 /** Writes the SXVIEW record starting the pivot table. */ 397 void WriteSxview( XclExpStream& rStrm ) const; 398 /** Writes an SXIVD record for row field or column field order. */ 399 void WriteSxivd( XclExpStream& rStrm, const ScfUInt16Vec& rFields ) const; 400 /** Writes the SXPI record containing page field info. */ 401 void WriteSxpi( XclExpStream& rStrm ) const; 402 /** Writes all SXDI records containing info about the data fields. */ 403 void WriteSxdiList( XclExpStream& rStrm ) const; 404 /** Writes a dummy SXLI records containing item layout info. */ 405 void WriteSxli( XclExpStream& rStrm, sal_uInt16 nLineCount, sal_uInt16 nIndexCount ) const; 406 /** Writes the SXEX records containing additional pivot table info. */ 407 void WriteSxex( XclExpStream& rStrm ) const; 408 409 void WriteQsiSxTag( XclExpStream& rStrm ) const; 410 /** Writes the SX_AUTOFORMAT records with the autoformat id and header layout */ 411 void WriteSxViewEx9( XclExpStream& rStrm ) const; 412 413 // ------------------------------------------------------------------------ 414 private: 415 typedef XclExpRecordList< XclExpPTField > XclExpPTFieldList; 416 typedef XclExpPTFieldList::RecordRefType XclExpPTFieldRef; 417 typedef ::std::vector< XclPTDataFieldPos > XclPTDataFieldPosVec; 418 419 const XclExpPivotCache& mrPCache; /// The pivot cache this pivot table bases on. 420 XclPTInfo maPTInfo; /// Info about the pivot table (SXVIEW record). 421 XclPTExtInfo maPTExtInfo; /// Extended info about the pivot table (SXEX record). 422 XclPTViewEx9Info maPTViewEx9Info; /// The selected autoformat (SXVIEWEX9) 423 XclExpPTFieldList maFieldList; /// All fields in pivot cache order. 424 ScfUInt16Vec maRowFields; /// Row field indexes. 425 ScfUInt16Vec maColFields; /// Column field indexes. 426 ScfUInt16Vec maPageFields; /// Page field indexes. 427 XclPTDataFieldPosVec maDataFields; /// Data field indexes. 428 XclExpPTField maDataOrientField; /// Special data field orientation field. 429 SCTAB mnOutScTab; /// Sheet index of the output range. 430 bool mbValid; /// true = The pivot table is valid for export. 431 bool mbFilterBtn; /// true = DataPilot has filter button. 432 }; 433 434 // ============================================================================ 435 436 /** The main class for pivot table export. 437 438 This class contains all pivot caches and pivot tables in a Calc document. 439 It creates the pivot cache streams and pivot table records in the main 440 workbook stream. It supports sharing of pivot caches between multiple pivot 441 tables to decrease file size. 442 */ 443 class XclExpPivotTableManager : protected XclExpRoot 444 { 445 public: 446 explicit XclExpPivotTableManager( const XclExpRoot& rRoot ); 447 448 /** Creates all pivot tables and caches from the Calc DataPilot objects. */ 449 void CreatePivotTables(); 450 451 /** Creates a record wrapper for exporting all pivot caches. */ 452 XclExpRecordRef CreatePivotCachesRecord(); 453 /** Creates a record wrapper for exporting all pivot tables of the specified sheet. */ 454 XclExpRecordRef CreatePivotTablesRecord( SCTAB nScTab ); 455 456 /** Writes all pivot caches (all Workbook records and cache streams). */ 457 void WritePivotCaches( XclExpStream& rStrm ); 458 void WritePivotCachesXml( XclExpXmlStream& rStrm ); 459 /** Writes all pivot tables of the specified Calc sheet. */ 460 void WritePivotTables( XclExpStream& rStrm, SCTAB nScTab ); 461 void WritePivotTablesXml( XclExpXmlStream& rStrm, SCTAB nScTab ); 462 463 private: 464 /** Finds an existing (if enabled in mbShareCaches) or creates a new pivot cache. 465 @return Pointer to the pivot cache or 0, if the passed source range was invalid. */ 466 const XclExpPivotCache* CreatePivotCache( const ScDPObject& rDPObj ); 467 468 private: 469 typedef XclExpRecordList< XclExpPivotCache > XclExpPivotCacheList; 470 typedef XclExpPivotCacheList::RecordRefType XclExpPivotCacheRef; 471 typedef XclExpRecordList< XclExpPivotTable > XclExpPivotTableList; 472 typedef XclExpPivotTableList::RecordRefType XclExpPivotTableRef; 473 474 XclExpPivotCacheList maPCacheList; /// List of all pivot caches. 475 XclExpPivotTableList maPTableList; /// List of all pivot tables. 476 bool mbShareCaches; /// true = Tries to share caches between tables. 477 }; 478 479 // ============================================================================ 480 481 #endif 482 483