Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / sc / source / filter / excel / excdoc.cxx
blob4d9975d034ccf12299012fe8d84310c1f7010323
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sfx2/objsh.hxx>
21 #include <rtl/ustring.hxx>
23 #include <document.hxx>
24 #include <scextopt.hxx>
25 #include <docoptio.hxx>
26 #include <tabprotection.hxx>
27 #include <postit.hxx>
28 #include <root.hxx>
30 #include <excdoc.hxx>
31 #include <xeextlst.hxx>
32 #include <biffhelper.hxx>
34 #include <xcl97rec.hxx>
35 #include <xetable.hxx>
36 #include <xelink.hxx>
37 #include <xepage.hxx>
38 #include <xeview.hxx>
39 #include <xecontent.hxx>
40 #include <xeescher.hxx>
41 #include <xepivot.hxx>
42 #include <XclExpChangeTrack.hxx>
43 #include <xepivotxml.hxx>
44 #include <xedbdata.hxx>
45 #include <xlcontent.hxx>
46 #include <xlname.hxx>
47 #include <xllink.hxx>
48 #include <xltools.hxx>
50 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
51 #include <oox/token/tokens.hxx>
52 #include <oox/token/namespaces.hxx>
53 #include <memory>
55 using namespace oox;
57 static OUString lcl_GetVbaTabName( SCTAB n )
59 OUString aRet = "__VBA__" + OUString::number( static_cast<sal_uInt16>(n) );
60 return aRet;
63 static void lcl_AddBookviews( XclExpRecordList<>& aRecList, const ExcTable& self )
65 aRecList.AppendNewRecord( new XclExpXmlStartElementRecord( XML_bookViews ) );
66 aRecList.AppendNewRecord( new XclExpWindow1( self.GetRoot() ) );
67 aRecList.AppendNewRecord( new XclExpXmlEndElementRecord( XML_bookViews ) );
70 static void lcl_AddCalcPr( XclExpRecordList<>& aRecList, const ExcTable& self )
72 ScDocument& rDoc = self.GetDoc();
74 aRecList.AppendNewRecord( new XclExpXmlStartSingleElementRecord( XML_calcPr ) );
75 // OOXTODO: calcCompleted, calcId, calcMode, calcOnSave,
76 // concurrentCalc, concurrentManualCount,
77 // forceFullCalc, fullCalcOnLoad, fullPrecision
78 aRecList.AppendNewRecord( new XclCalccount( rDoc ) );
79 aRecList.AppendNewRecord( new XclRefmode( rDoc ) );
80 aRecList.AppendNewRecord( new XclIteration( rDoc ) );
81 aRecList.AppendNewRecord( new XclDelta( rDoc ) );
82 aRecList.AppendNewRecord( new XclExpBoolRecord(oox::xls::BIFF_ID_SAVERECALC, true) );
83 aRecList.AppendNewRecord( new XclExpXmlEndSingleElementRecord() ); // XML_calcPr
86 static void lcl_AddWorkbookProtection( XclExpRecordList<>& aRecList, const ExcTable& self )
88 aRecList.AppendNewRecord( new XclExpXmlStartSingleElementRecord( XML_workbookProtection ) );
90 const ScDocProtection* pProtect = self.GetDoc().GetDocProtection();
91 if (pProtect && pProtect->isProtected())
93 aRecList.AppendNewRecord( new XclExpWindowProtection(pProtect->isOptionEnabled(ScDocProtection::WINDOWS)) );
94 aRecList.AppendNewRecord( new XclExpProtection(pProtect->isOptionEnabled(ScDocProtection::STRUCTURE)) );
95 aRecList.AppendNewRecord( new XclExpPassHash(pProtect->getPasswordHash(PASSHASH_XL)) );
98 aRecList.AppendNewRecord( new XclExpXmlEndSingleElementRecord() ); // XML_workbookProtection
101 static void lcl_AddScenariosAndFilters( XclExpRecordList<>& aRecList, const XclExpRoot& rRoot, SCTAB nScTab )
103 // Scenarios
104 aRecList.AppendNewRecord( new ExcEScenarioManager( rRoot, nScTab ) );
105 // filter
106 aRecList.AppendRecord( rRoot.GetFilterManager().CreateRecord( nScTab ) );
109 ExcTable::ExcTable( const XclExpRoot& rRoot ) :
110 XclExpRoot( rRoot ),
111 mnScTab( SCTAB_GLOBAL ),
112 nExcTab( EXC_NOTAB ),
113 mxNoteList( new XclExpNoteList )
117 ExcTable::ExcTable( const XclExpRoot& rRoot, SCTAB nScTab ) :
118 XclExpRoot( rRoot ),
119 mnScTab( nScTab ),
120 nExcTab( rRoot.GetTabInfo().GetXclTab( nScTab ) ),
121 mxNoteList( new XclExpNoteList )
125 ExcTable::~ExcTable()
129 void ExcTable::Add( XclExpRecordBase* pRec )
131 OSL_ENSURE( pRec, "-ExcTable::Add(): pRec is NULL!" );
132 aRecList.AppendNewRecord( pRec );
135 void ExcTable::FillAsHeaderBinary( ExcBoundsheetList& rBoundsheetList )
137 InitializeGlobals();
139 RootData& rR = GetOldRoot();
140 ScDocument& rDoc = GetDoc();
141 XclExpTabInfo& rTabInfo = GetTabInfo();
143 if ( GetBiff() <= EXC_BIFF5 )
144 Add( new ExcBofW );
145 else
146 Add( new ExcBofW8 );
148 sal_uInt16 nExcTabCount = rTabInfo.GetXclTabCount();
149 sal_uInt16 nCodenames = static_cast< sal_uInt16 >( GetExtDocOptions().GetCodeNameCount() );
151 SfxObjectShell* pShell = GetDocShell();
152 sal_uInt16 nWriteProtHash = pShell ? pShell->GetModifyPasswordHash() : 0;
153 bool bRecommendReadOnly = pShell && pShell->IsLoadReadonly();
155 if( (nWriteProtHash > 0) || bRecommendReadOnly )
156 Add( new XclExpEmptyRecord( EXC_ID_WRITEPROT ) );
158 // TODO: correct codepage for BIFF5?
159 sal_uInt16 nCodePage = XclTools::GetXclCodePage( (GetBiff() <= EXC_BIFF5) ? RTL_TEXTENCODING_MS_1252 : RTL_TEXTENCODING_UNICODE );
161 if( GetBiff() <= EXC_BIFF5 )
163 Add( new XclExpEmptyRecord( EXC_ID_INTERFACEHDR ) );
164 Add( new XclExpUInt16Record( EXC_ID_MMS, 0 ) );
165 Add( new XclExpEmptyRecord( EXC_ID_TOOLBARHDR ) );
166 Add( new XclExpEmptyRecord( EXC_ID_TOOLBAREND ) );
167 Add( new XclExpEmptyRecord( EXC_ID_INTERFACEEND ) );
168 Add( new ExcDummy_00 );
170 else
172 if( IsDocumentEncrypted() )
173 Add( new XclExpFileEncryption( GetRoot() ) );
174 Add( new XclExpInterfaceHdr( nCodePage ) );
175 Add( new XclExpUInt16Record( EXC_ID_MMS, 0 ) );
176 Add( new XclExpInterfaceEnd );
177 Add( new XclExpWriteAccess );
180 Add( new XclExpFileSharing( GetRoot(), nWriteProtHash, bRecommendReadOnly ) );
181 Add( new XclExpUInt16Record( EXC_ID_CODEPAGE, nCodePage ) );
183 if( GetBiff() == EXC_BIFF8 )
185 Add( new XclExpBoolRecord( EXC_ID_DSF, false ) );
186 Add( new XclExpEmptyRecord( EXC_ID_XL9FILE ) );
187 rR.pTabId = new XclExpChTrTabId( std::max( nExcTabCount, nCodenames ) );
188 Add( rR.pTabId );
189 if( HasVbaStorage() )
191 Add( new XclObproj );
192 const OUString& rCodeName = GetExtDocOptions().GetDocSettings().maGlobCodeName;
193 if( !rCodeName.isEmpty() )
194 Add( new XclCodename( rCodeName ) );
198 Add( new XclExpUInt16Record( EXC_ID_FNGROUPCOUNT, 14 ) );
200 if ( GetBiff() <= EXC_BIFF5 )
202 // global link table: EXTERNCOUNT, EXTERNSHEET, NAME
203 aRecList.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET ) );
204 aRecList.AppendRecord( CreateRecord( EXC_ID_NAME ) );
207 // document protection options
208 lcl_AddWorkbookProtection( aRecList, *this );
210 if( GetBiff() == EXC_BIFF8 )
212 Add( new XclExpProt4Rev );
213 Add( new XclExpProt4RevPass );
216 lcl_AddBookviews( aRecList, *this );
218 Add( new XclExpXmlStartSingleElementRecord( XML_workbookPr ) );
219 if ( GetBiff() == EXC_BIFF8 && GetOutput() != EXC_OUTPUT_BINARY )
221 Add( new XclExpBoolRecord(0x0040, false, XML_backupFile ) ); // BACKUP
222 Add( new XclExpBoolRecord(0x008D, false, XML_showObjects ) ); // HIDEOBJ
225 if ( GetBiff() == EXC_BIFF8 )
227 Add( new XclExpBoolRecord(0x0040, false) ); // BACKUP
228 Add( new XclExpBoolRecord(0x008D, false) ); // HIDEOBJ
231 if( GetBiff() <= EXC_BIFF5 )
233 Add( new ExcDummy_040 );
234 Add( new Exc1904( rDoc ) );
235 Add( new ExcDummy_041 );
237 else
239 // BIFF8
240 Add( new Exc1904( rDoc ) );
241 Add( new XclExpBoolRecord( 0x000E, !rDoc.GetDocOptions().IsCalcAsShown() ) );
242 Add( new XclExpBoolRecord(0x01B7, false) ); // REFRESHALL
243 Add( new XclExpBoolRecord(0x00DA, false) ); // BOOKBOOL
246 // Formatting: FONT, FORMAT, XF, STYLE, PALETTE
247 aRecList.AppendRecord( CreateRecord( EXC_ID_FONTLIST ) );
248 aRecList.AppendRecord( CreateRecord( EXC_ID_FORMATLIST ) );
249 aRecList.AppendRecord( CreateRecord( EXC_ID_XFLIST ) );
250 aRecList.AppendRecord( CreateRecord( EXC_ID_PALETTE ) );
252 SCTAB nC;
253 SCTAB nScTabCount = rTabInfo.GetScTabCount();
254 if( GetBiff() <= EXC_BIFF5 )
256 // Bundlesheet
257 for( nC = 0 ; nC < nScTabCount ; nC++ )
258 if( rTabInfo.IsExportTab( nC ) )
260 ExcBoundsheetList::RecordRefType xBoundsheet( new ExcBundlesheet( rR, nC ) );
261 aRecList.AppendRecord( xBoundsheet );
262 rBoundsheetList.AppendRecord( xBoundsheet );
265 else
267 // Pivot Cache
268 GetPivotTableManager().CreatePivotTables();
269 aRecList.AppendRecord( GetPivotTableManager().CreatePivotCachesRecord() );
271 // Change tracking
272 if( rDoc.GetChangeTrack() )
274 rR.pUserBViewList = new XclExpUserBViewList( *rDoc.GetChangeTrack() );
275 Add( rR.pUserBViewList );
278 // Natural Language Formulas Flag
279 aRecList.AppendNewRecord( new XclExpBoolRecord( EXC_ID_USESELFS, GetDoc().GetDocOptions().IsLookUpColRowNames() ) );
281 // Bundlesheet
282 for( nC = 0 ; nC < nScTabCount ; nC++ )
283 if( rTabInfo.IsExportTab( nC ) )
285 ExcBoundsheetList::RecordRefType xBoundsheet( new ExcBundlesheet8( rR, nC ) );
286 aRecList.AppendRecord( xBoundsheet );
287 rBoundsheetList.AppendRecord( xBoundsheet );
290 OUString aTmpString;
291 for( SCTAB nAdd = 0; nC < static_cast<SCTAB>(nCodenames) ; nC++, nAdd++ )
293 aTmpString = lcl_GetVbaTabName( nAdd );
294 ExcBoundsheetList::RecordRefType xBoundsheet( new ExcBundlesheet8( aTmpString ) );
295 aRecList.AppendRecord( xBoundsheet );
296 rBoundsheetList.AppendRecord( xBoundsheet );
299 // COUNTRY - in BIFF8 in workbook globals
300 Add( new XclExpCountry( GetRoot() ) );
302 // link table: SUPBOOK, XCT, CRN, EXTERNNAME, EXTERNSHEET, NAME
303 aRecList.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET ) );
304 aRecList.AppendRecord( CreateRecord( EXC_ID_NAME ) );
306 Add( new XclExpRecalcId );
308 // MSODRAWINGGROUP per-document data
309 aRecList.AppendRecord( GetObjectManager().CreateDrawingGroup() );
310 // Shared string table: SST, EXTSST
311 aRecList.AppendRecord( CreateRecord( EXC_ID_SST ) );
313 Add( new XclExpBookExt );
316 Add( new ExcEof );
319 void ExcTable::FillAsHeaderXml( ExcBoundsheetList& rBoundsheetList )
321 InitializeGlobals();
323 RootData& rR = GetOldRoot();
324 ScDocument& rDoc = GetDoc();
325 XclExpTabInfo& rTabInfo = GetTabInfo();
327 sal_uInt16 nExcTabCount = rTabInfo.GetXclTabCount();
328 sal_uInt16 nCodenames = static_cast< sal_uInt16 >( GetExtDocOptions().GetCodeNameCount() );
330 rR.pTabId = new XclExpChTrTabId( std::max( nExcTabCount, nCodenames ) );
331 Add( rR.pTabId );
333 Add( new XclExpXmlStartSingleElementRecord( XML_workbookPr ) );
334 Add( new XclExpBoolRecord(0x0040, false, XML_backupFile ) ); // BACKUP
335 Add( new XclExpBoolRecord(0x008D, false, XML_showObjects ) ); // HIDEOBJ
337 Add( new Exc1904( rDoc ) );
338 // OOXTODO: The following /workbook/workbookPr attributes are mapped
339 // to various BIFF records that are not currently supported:
341 // XML_allowRefreshQuery: QSISTAG 802h: fEnableRefresh
342 // XML_autoCompressPictures: COMPRESSPICTURES 89Bh: fAutoCompressPictures
343 // XML_checkCompatibility: COMPAT12 88Ch: fNoCompatChk
344 // XML_codeName: "Calc"
345 // XML_defaultThemeVersion: ???
346 // XML_filterPrivacy: BOOKEXT 863h: fFilterPrivacy
347 // XML_hidePivotFieldList: BOOKBOOL DAh: fHidePivotTableFList
348 // XML_promptedSolutions: BOOKEXT 863h: fBuggedUserAboutSolution
349 // XML_publishItems: NAMEPUBLISH 893h: fPublished
350 // XML_saveExternalLinkValues: BOOKBOOL DAh: fNoSavSupp
351 // XML_showBorderUnselectedTables: BOOKBOOL DAh: fHideBorderUnsels
352 // XML_showInkAnnotation: BOOKEXT 863h: fShowInkAnnotation
353 // XML_showPivotChart: PIVOTCHARTBITS 859h: fGXHide??
354 // XML_updateLinks: BOOKBOOL DAh: grbitUpdateLinks
355 Add( new XclExpXmlEndSingleElementRecord() ); // XML_workbookPr
357 // Formatting: FONT, FORMAT, XF, STYLE, PALETTE
358 aRecList.AppendNewRecord( new XclExpXmlStyleSheet( *this ) );
360 // Change tracking
361 if( rDoc.GetChangeTrack() )
363 rR.pUserBViewList = new XclExpUserBViewList( *rDoc.GetChangeTrack() );
364 Add( rR.pUserBViewList );
367 lcl_AddWorkbookProtection( aRecList, *this );
368 lcl_AddBookviews( aRecList, *this );
370 // Bundlesheet
371 SCTAB nC;
372 SCTAB nScTabCount = rTabInfo.GetScTabCount();
373 aRecList.AppendNewRecord( new XclExpXmlStartElementRecord( XML_sheets ) );
374 for( nC = 0 ; nC < nScTabCount ; nC++ )
375 if( rTabInfo.IsExportTab( nC ) )
377 ExcBoundsheetList::RecordRefType xBoundsheet( new ExcBundlesheet8( rR, nC ) );
378 aRecList.AppendRecord( xBoundsheet );
379 rBoundsheetList.AppendRecord( xBoundsheet );
381 aRecList.AppendNewRecord( new XclExpXmlEndElementRecord( XML_sheets ) );
383 OUString aTmpString;
384 for( SCTAB nAdd = 0; nC < static_cast<SCTAB>(nCodenames) ; nC++, nAdd++ )
386 aTmpString = lcl_GetVbaTabName( nAdd );
387 ExcBoundsheetList::RecordRefType xBoundsheet( new ExcBundlesheet8( aTmpString ) );
388 aRecList.AppendRecord( xBoundsheet );
389 rBoundsheetList.AppendRecord( xBoundsheet );
392 // link table: SUPBOOK, XCT, CRN, EXTERNNAME, EXTERNSHEET, NAME
393 aRecList.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET ) );
394 aRecList.AppendRecord( CreateRecord( EXC_ID_NAME ) );
396 lcl_AddCalcPr( aRecList, *this );
398 // MSODRAWINGGROUP per-document data
399 aRecList.AppendRecord( GetObjectManager().CreateDrawingGroup() );
400 // Shared string table: SST, EXTSST
401 aRecList.AppendRecord( CreateRecord( EXC_ID_SST ) );
404 void ExcTable::FillAsTableBinary( SCTAB nCodeNameIdx )
406 InitializeTable( mnScTab );
408 RootData& rR = GetOldRoot();
409 XclBiff eBiff = GetBiff();
410 ScDocument& rDoc = GetDoc();
412 OSL_ENSURE( (mnScTab >= 0) && (mnScTab <= MAXTAB), "-ExcTable::Table(): mnScTab - no ordinary table!" );
413 OSL_ENSURE( nExcTab <= static_cast<sal_uInt16>(MAXTAB), "-ExcTable::Table(): nExcTab - no ordinary table!" );
415 // create a new OBJ list for this sheet (may be used by notes, autofilter, data validation)
416 if( eBiff == EXC_BIFF8 )
417 GetObjectManager().StartSheet();
419 // cell table: DEFROWHEIGHT, DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
420 mxCellTable.reset( new XclExpCellTable( GetRoot() ) );
422 //export cell notes
423 std::vector<sc::NoteEntry> aNotes;
424 rDoc.GetAllNoteEntries(aNotes);
425 for (const auto& rNote : aNotes)
427 if (rNote.maPos.Tab() != mnScTab)
428 continue;
430 mxNoteList->AppendNewRecord(new XclExpNote(GetRoot(), rNote.maPos, rNote.mpNote, OUString()));
433 // WSBOOL needs data from page settings, create it here, add it later
434 std::shared_ptr< XclExpPageSettings > xPageSett( new XclExpPageSettings( GetRoot() ) );
435 bool bFitToPages = xPageSett->GetPageData().mbFitToPages;
437 if( eBiff <= EXC_BIFF5 )
439 Add( new ExcBof );
440 Add( new ExcDummy_02a );
442 else
444 Add( new ExcBof8 );
445 lcl_AddCalcPr( aRecList, *this );
448 // GUTS (count & size of outline icons)
449 aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_GUTS ) );
450 // DEFROWHEIGHT, created by the cell table
451 aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID2_DEFROWHEIGHT ) );
453 // COUNTRY - in BIFF5/7 in every worksheet
454 if( eBiff <= EXC_BIFF5 )
455 Add( new XclExpCountry( GetRoot() ) );
457 Add( new XclExpWsbool( bFitToPages ) );
459 // page settings (SETUP and various other records)
460 aRecList.AppendRecord( xPageSett );
462 const ScTableProtection* pTabProtect = rDoc.GetTabProtection(mnScTab);
463 if (pTabProtect && pTabProtect->isProtected())
465 Add( new XclExpProtection(true) );
466 Add( new XclExpBoolRecord(oox::xls::BIFF_ID_SCENPROTECT, pTabProtect->isOptionEnabled(ScTableProtection::SCENARIOS)) );
467 if (pTabProtect->isOptionEnabled(ScTableProtection::OBJECTS))
468 Add( new XclExpBoolRecord(oox::xls::BIFF_ID_OBJECTPROTECT, true ));
469 Add( new XclExpPassHash(pTabProtect->getPasswordHash(PASSHASH_XL)) );
472 // local link table: EXTERNCOUNT, EXTERNSHEET
473 if( eBiff <= EXC_BIFF5 )
474 aRecList.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET ) );
476 if ( eBiff == EXC_BIFF8 )
477 lcl_AddScenariosAndFilters( aRecList, GetRoot(), mnScTab );
479 // cell table: DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
480 aRecList.AppendRecord( mxCellTable );
482 // MERGEDCELLS record, generated by the cell table
483 aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_MERGEDCELLS ) );
484 // label ranges
485 if( eBiff == EXC_BIFF8 )
486 Add( new XclExpLabelranges( GetRoot() ) );
487 // data validation (DVAL and list of DV records), generated by the cell table
488 aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_DVAL ) );
490 if( eBiff == EXC_BIFF8 )
492 // all MSODRAWING and OBJ stuff of this sheet goes here
493 aRecList.AppendRecord( GetObjectManager().ProcessDrawing( GetSdrPage( mnScTab ) ) );
494 // pivot tables
495 aRecList.AppendRecord( GetPivotTableManager().CreatePivotTablesRecord( mnScTab ) );
498 // list of NOTE records, generated by the cell table
499 aRecList.AppendRecord( mxNoteList );
501 // sheet view settings: WINDOW2, SCL, PANE, SELECTION
502 aRecList.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab ) );
504 if( eBiff == EXC_BIFF8 )
506 // sheet protection options
507 Add( new XclExpSheetProtectOptions( GetRoot(), mnScTab ) );
509 // enhanced protections if there are
510 if (pTabProtect)
512 const ::std::vector<ScEnhancedProtection>& rProts( pTabProtect->getEnhancedProtection());
513 for (const auto& rProt : rProts)
515 Add( new XclExpSheetEnhancedProtection( GetRoot(), rProt));
519 // web queries
520 Add( new XclExpWebQueryBuffer( GetRoot() ) );
522 // conditional formats
523 Add( new XclExpCondFormatBuffer( GetRoot(), XclExtLstRef() ) );
525 if( HasVbaStorage() )
526 if( nCodeNameIdx < GetExtDocOptions().GetCodeNameCount() )
527 Add( new XclCodename( GetExtDocOptions().GetCodeName( nCodeNameIdx ) ) );
530 // list of HLINK records, generated by the cell table
531 aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_HLINK ) );
533 // change tracking
534 if( rR.pUserBViewList )
536 XclExpUserBViewList::const_iterator iter;
537 for ( iter = rR.pUserBViewList->cbegin(); iter != rR.pUserBViewList->cend(); ++iter)
539 Add( new XclExpUsersViewBegin( (*iter).GetGUID(), nExcTab ) );
540 Add( new XclExpUsersViewEnd );
544 // EOF
545 Add( new ExcEof );
548 void ExcTable::FillAsTableXml()
550 InitializeTable( mnScTab );
552 ScDocument& rDoc = GetDoc();
554 OSL_ENSURE( (mnScTab >= 0) && (mnScTab <= MAXTAB), "-ExcTable::Table(): mnScTab - no ordinary table!" );
555 OSL_ENSURE( nExcTab <= static_cast<sal_uInt16>(MAXTAB), "-ExcTable::Table(): nExcTab - no ordinary table!" );
557 // create a new OBJ list for this sheet (may be used by notes, autofilter, data validation)
558 GetObjectManager().StartSheet();
560 // cell table: DEFROWHEIGHT, DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
561 mxCellTable.reset( new XclExpCellTable( GetRoot() ) );
563 //export cell notes
564 std::vector<sc::NoteEntry> aNotes;
565 rDoc.GetAllNoteEntries(aNotes);
566 for (const auto& rNote : aNotes)
568 if (rNote.maPos.Tab() != mnScTab)
569 continue;
571 mxNoteList->AppendNewRecord(new XclExpNote(GetRoot(), rNote.maPos, rNote.mpNote, OUString()));
574 // WSBOOL needs data from page settings, create it here, add it later
575 std::shared_ptr< XclExpPageSettings > xPageSett( new XclExpPageSettings( GetRoot() ) );
576 XclExtLstRef xExtLst( new XclExtLst( GetRoot() ) );
577 bool bFitToPages = xPageSett->GetPageData().mbFitToPages;
579 Color aTabColor = GetRoot().GetDoc().GetTabBgColor(mnScTab);
580 Add(new XclExpXmlSheetPr(bFitToPages, mnScTab, aTabColor, &GetFilterManager()));
582 // GUTS (count & size of outline icons)
583 aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_GUTS ) );
584 // DEFROWHEIGHT, created by the cell table
585 aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID2_DEFROWHEIGHT ) );
587 aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID3_DIMENSIONS ) );
589 // sheet view settings: WINDOW2, SCL, PANE, SELECTION
590 aRecList.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab ) );
592 // cell table: DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
593 aRecList.AppendRecord( mxCellTable );
595 // list of NOTE records, generated by the cell table
596 // not in the worksheet file
597 if( mxNoteList != nullptr && !mxNoteList->IsEmpty() )
598 aRecList.AppendNewRecord( new XclExpComments( mnScTab, *mxNoteList ) );
600 const ScTableProtection* pTabProtect = rDoc.GetTabProtection(mnScTab);
601 if (pTabProtect && pTabProtect->isProtected())
602 Add( new XclExpSheetProtection(true, mnScTab) );
604 lcl_AddScenariosAndFilters( aRecList, GetRoot(), mnScTab );
606 // MERGEDCELLS record, generated by the cell table
607 aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_MERGEDCELLS ) );
609 // conditional formats
610 Add( new XclExpCondFormatBuffer( GetRoot(), xExtLst ) );
612 // data validation (DVAL and list of DV records), generated by the cell table
613 aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_DVAL ) );
615 // list of HLINK records, generated by the cell table
616 XclExpRecordRef xHyperlinks = mxCellTable->CreateRecord( EXC_ID_HLINK );
617 XclExpHyperlinkList* pHyperlinkList = dynamic_cast<XclExpHyperlinkList*>(xHyperlinks.get());
618 if( pHyperlinkList != nullptr && !pHyperlinkList->IsEmpty() )
620 aRecList.AppendNewRecord( new XclExpXmlStartElementRecord( XML_hyperlinks ) );
621 aRecList.AppendRecord( xHyperlinks );
622 aRecList.AppendNewRecord( new XclExpXmlEndElementRecord( XML_hyperlinks ) );
625 aRecList.AppendRecord( xPageSett );
627 // all MSODRAWING and OBJ stuff of this sheet goes here
628 aRecList.AppendRecord( GetObjectManager().ProcessDrawing( GetSdrPage( mnScTab ) ) );
630 XclExpImgData* pImgData = xPageSett->getGraphicExport();
631 if (pImgData)
632 aRecList.AppendRecord(std::shared_ptr<XclExpRecordBase>(pImgData));
634 // <tableParts> after <drawing> and before <extLst>
635 aRecList.AppendRecord( GetTablesManager().GetTablesBySheet( mnScTab));
637 aRecList.AppendRecord( xExtLst );
640 void ExcTable::FillAsEmptyTable( SCTAB nCodeNameIdx )
642 InitializeTable( mnScTab );
644 if( HasVbaStorage() && (nCodeNameIdx < GetExtDocOptions().GetCodeNameCount()) )
646 if( GetBiff() <= EXC_BIFF5 )
648 Add( new ExcBof );
650 else
652 Add( new ExcBof8 );
653 Add( new XclCodename( GetExtDocOptions().GetCodeName( nCodeNameIdx ) ) );
655 // sheet view settings: WINDOW2, SCL, PANE, SELECTION
656 aRecList.AppendNewRecord( new XclExpTabViewSettings( GetRoot(), mnScTab ) );
657 Add( new ExcEof );
661 void ExcTable::Write( XclExpStream& rStrm )
663 SetCurrScTab( mnScTab );
664 if( mxCellTable.get() )
665 mxCellTable->Finalize(true);
666 aRecList.Save( rStrm );
669 void ExcTable::WriteXml( XclExpXmlStream& rStrm )
671 if (!GetTabInfo().IsExportTab(mnScTab))
673 // header export.
674 SetCurrScTab(mnScTab);
675 if (mxCellTable)
676 mxCellTable->Finalize(false);
677 aRecList.SaveXml(rStrm);
679 return;
682 // worksheet export
683 OUString sSheetName = XclXmlUtils::GetStreamName( "xl/", "worksheets/sheet", mnScTab+1 );
685 sax_fastparser::FSHelperPtr pWorksheet = rStrm.GetStreamForPath( sSheetName );
687 rStrm.PushStream( pWorksheet );
689 pWorksheet->startElement( XML_worksheet,
690 XML_xmlns, rStrm.getNamespaceURL(OOX_NS(xls)).toUtf8(),
691 FSNS(XML_xmlns, XML_r), rStrm.getNamespaceURL(OOX_NS(officeRel)).toUtf8() );
693 SetCurrScTab( mnScTab );
694 if (mxCellTable)
695 mxCellTable->Finalize(false);
696 aRecList.SaveXml( rStrm );
698 XclExpXmlPivotTables* pPT = GetXmlPivotTableManager().GetTablesBySheet(mnScTab);
699 if (pPT)
700 pPT->SaveXml(rStrm);
702 rStrm.GetCurrentStream()->endElement( XML_worksheet );
703 rStrm.PopStream();
706 ExcDocument::ExcDocument( const XclExpRoot& rRoot ) :
707 XclExpRoot( rRoot ),
708 aHeader( rRoot )
712 ExcDocument::~ExcDocument()
714 maTableList.RemoveAllRecords(); // for the following assertion!
717 void ExcDocument::ReadDoc()
719 InitializeConvert();
721 if (GetOutput() == EXC_OUTPUT_BINARY)
722 aHeader.FillAsHeaderBinary(maBoundsheetList);
723 else
725 aHeader.FillAsHeaderXml(maBoundsheetList);
726 GetXmlPivotTableManager().Initialize();
727 GetTablesManager().Initialize(); // Move outside conditions if we wanted to support BIFF.
730 SCTAB nScTab = 0, nScTabCount = GetTabInfo().GetScTabCount();
731 SCTAB nCodeNameIdx = 0, nCodeNameCount = GetExtDocOptions().GetCodeNameCount();
733 for( ; nScTab < nScTabCount; ++nScTab )
735 if( GetTabInfo().IsExportTab( nScTab ) )
737 ExcTableList::RecordRefType xTab( new ExcTable( GetRoot(), nScTab ) );
738 maTableList.AppendRecord( xTab );
739 if (GetOutput() == EXC_OUTPUT_BINARY)
740 xTab->FillAsTableBinary(nCodeNameIdx);
741 else
742 xTab->FillAsTableXml();
744 ++nCodeNameIdx;
747 for( ; nCodeNameIdx < nCodeNameCount; ++nScTab, ++nCodeNameIdx )
749 ExcTableList::RecordRefType xTab( new ExcTable( GetRoot(), nScTab ) );
750 maTableList.AppendRecord( xTab );
751 xTab->FillAsEmptyTable( nCodeNameIdx );
754 if ( GetBiff() == EXC_BIFF8 )
756 // complete temporary Escher stream
757 GetObjectManager().EndDocument();
759 // change tracking
760 if ( GetDoc().GetChangeTrack() )
761 m_xExpChangeTrack.reset(new XclExpChangeTrack( GetRoot() ));
765 void ExcDocument::Write( SvStream& rSvStrm )
767 if( !maTableList.IsEmpty() )
769 InitializeSave();
771 XclExpStream aXclStrm( rSvStrm, GetRoot() );
773 aHeader.Write( aXclStrm );
775 OSL_ENSURE( maTableList.GetSize() == maBoundsheetList.GetSize(),
776 "ExcDocument::Write - different number of sheets and BOUNDSHEET records" );
778 for( size_t nTab = 0, nTabCount = maTableList.GetSize(); nTab < nTabCount; ++nTab )
780 // set current stream position in BOUNDSHEET record
781 ExcBoundsheetRef xBoundsheet = maBoundsheetList.GetRecord( nTab );
782 if( xBoundsheet.get() )
783 xBoundsheet->SetStreamPos( aXclStrm.GetSvStreamPos() );
784 // write the table
785 maTableList.GetRecord( nTab )->Write( aXclStrm );
788 // write the table stream positions into the BOUNDSHEET records
789 for( size_t nBSheet = 0, nBSheetCount = maBoundsheetList.GetSize(); nBSheet < nBSheetCount; ++nBSheet )
790 maBoundsheetList.GetRecord( nBSheet )->UpdateStreamPos( aXclStrm );
792 if( m_xExpChangeTrack )
793 m_xExpChangeTrack->Write();
796 void ExcDocument::WriteXml( XclExpXmlStream& rStrm )
798 SfxObjectShell* pDocShell = GetDocShell();
800 using namespace ::com::sun::star;
801 uno::Reference<document::XDocumentPropertiesSupplier> xDPS( pDocShell->GetModel(), uno::UNO_QUERY_THROW );
802 uno::Reference<document::XDocumentProperties> xDocProps = xDPS->getDocumentProperties();
804 rStrm.exportDocumentProperties(xDocProps, pDocShell->IsSecurityOptOpenReadOnly());
805 rStrm.exportCustomFragments();
807 sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
808 rWorkbook->startElement( XML_workbook,
809 XML_xmlns, rStrm.getNamespaceURL(OOX_NS(xls)).toUtf8(),
810 FSNS(XML_xmlns, XML_r), rStrm.getNamespaceURL(OOX_NS(officeRel)).toUtf8() );
811 rWorkbook->singleElement( XML_fileVersion,
812 XML_appName, "Calc"
813 // OOXTODO: XML_codeName
814 // OOXTODO: XML_lastEdited
815 // OOXTODO: XML_lowestEdited
816 // OOXTODO: XML_rupBuild
819 if( !maTableList.IsEmpty() )
821 InitializeSave();
823 aHeader.WriteXml( rStrm );
825 for( size_t nTab = 0, nTabCount = maTableList.GetSize(); nTab < nTabCount; ++nTab )
827 // write the table
828 maTableList.GetRecord( nTab )->WriteXml( rStrm );
832 if( m_xExpChangeTrack )
833 m_xExpChangeTrack->WriteXml( rStrm );
835 XclExpXmlPivotCaches& rCaches = GetXmlPivotTableManager().GetCaches();
836 if (rCaches.HasCaches())
837 rCaches.SaveXml(rStrm);
839 const ScCalcConfig& rCalcConfig = GetDoc().GetCalcConfig();
840 formula::FormulaGrammar::AddressConvention eConv = rCalcConfig.meStringRefAddressSyntax;
842 // don't save "unspecified" string ref syntax ... query formula grammar
843 // and save that instead
844 if( eConv == formula::FormulaGrammar::CONV_UNSPECIFIED)
846 eConv = GetDoc().GetAddressConvention();
849 // write if it has been read|imported or explicitly changed
850 // or if ref syntax isn't what would be native for our file format
851 // i.e. ExcelA1 in this case
852 if ( rCalcConfig.mbHasStringRefSyntax ||
853 (eConv != formula::FormulaGrammar::CONV_XL_A1) )
855 XclExtLstRef xExtLst( new XclExtLst( GetRoot() ) );
856 xExtLst->AddRecord( XclExpExtRef( new XclExpExtCalcPr( GetRoot(), eConv )) );
857 xExtLst->SaveXml(rStrm);
860 rWorkbook->endElement( XML_workbook );
861 rWorkbook.reset();
864 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */