diff options
Diffstat (limited to 'sc/source/filter/excel/xepivot.cxx')
-rw-r--r-- | sc/source/filter/excel/xepivot.cxx | 141 |
1 files changed, 136 insertions, 5 deletions
diff --git a/sc/source/filter/excel/xepivot.cxx b/sc/source/filter/excel/xepivot.cxx index bc694d01725e..8680623dc29b 100644 --- a/sc/source/filter/excel/xepivot.cxx +++ b/sc/source/filter/excel/xepivot.cxx @@ -67,6 +67,7 @@ using ::com::sun::star::sheet::DataPilotFieldSortInfo; using ::com::sun::star::sheet::DataPilotFieldAutoShowInfo; using ::com::sun::star::sheet::DataPilotFieldLayoutInfo; using ::com::sun::star::sheet::DataPilotFieldReference; +using ::rtl::OUString; using ::rtl::OString; using ::rtl::OUString; @@ -975,6 +976,11 @@ void XclExpPTItem::SetPropertiesFromMember( const ScDPSaveMember& rSaveMem ) { ::set_flag( maItemInfo.mnFlags, EXC_SXVI_HIDDEN, !rSaveMem.GetIsVisible() ); ::set_flag( maItemInfo.mnFlags, EXC_SXVI_HIDEDETAIL, !rSaveMem.GetShowDetails() ); + + // visible name + const OUString* pVisName = rSaveMem.GetLayoutName(); + if (pVisName && !pVisName->equals(GetItemName())) + maItemInfo.SetVisName(*pVisName); } void XclExpPTItem::WriteBody( XclExpStream& rStrm ) @@ -1032,6 +1038,31 @@ sal_uInt16 XclExpPTField::GetItemIndex( const String& rName, sal_uInt16 nDefault // fill data -------------------------------------------------------------- +/** + * Calc's subtotal names are escaped with backslashes ('\'), while Excel's + * are not escaped at all. + */ +static OUString lcl_convertCalcSubtotalName(const OUString& rName) +{ + OUStringBuffer aBuf; + const sal_Unicode* p = rName.getStr(); + sal_Int32 n = rName.getLength(); + bool bEscaped = false; + for (sal_Int32 i = 0; i < n; ++i) + { + const sal_Unicode c = p[i]; + if (!bEscaped && c == sal_Unicode('\\')) + { + bEscaped = true; + continue; + } + + aBuf.append(c); + bEscaped = false; + } + return aBuf.makeStringAndClear(); +} + void XclExpPTField::SetPropertiesFromDim( const ScDPSaveDimension& rSaveDim ) { // orientation @@ -1043,8 +1074,16 @@ void XclExpPTField::SetPropertiesFromDim( const ScDPSaveDimension& rSaveDim ) ::set_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_SHOWALL, rSaveDim.GetShowEmpty() ); // visible name - if( rSaveDim.HasLayoutName() && (rSaveDim.GetLayoutName() != GetFieldName()) ) - maFieldInfo.SetVisName( rSaveDim.GetLayoutName() ); + const OUString* pLayoutName = rSaveDim.GetLayoutName(); + if (pLayoutName && !pLayoutName->equals(GetFieldName())) + maFieldInfo.SetVisName(*pLayoutName); + + const rtl::OUString* pSubtotalName = rSaveDim.GetSubtotalName(); + if (pSubtotalName) + { + OUString aSubName = lcl_convertCalcSubtotalName(*pSubtotalName); + maFieldExtInfo.mpFieldTotalName.reset(new rtl::OUString(aSubName)); + } // subtotals XclPTSubtotalVec aSubtotals; @@ -1111,7 +1150,11 @@ void XclExpPTField::SetDataPropertiesFromDim( const ScDPSaveDimension& rSaveDim rDataInfo.SetApiAggFunc( eFunc ); // visible name - rDataInfo.SetVisName( lclGetDataFieldCaption( GetFieldName(), eFunc ) ); + const rtl::OUString* pVisName = rSaveDim.GetLayoutName(); + if (pVisName) + rDataInfo.SetVisName(*pVisName); + else + rDataInfo.SetVisName( lclGetDataFieldCaption( GetFieldName(), eFunc ) ); // result field reference if( const DataPilotFieldReference* pFieldRef = rSaveDim.GetReferenceValue() ) @@ -1220,9 +1263,10 @@ XclExpPivotTable::XclExpPivotTable( const XclExpRoot& rRoot, const ScDPObject& r // pivot table properties from DP object mnOutScTab = rOutScRange.aStart.Tab(); maPTInfo.maTableName = rDPObj.GetName(); - maPTInfo.maDataName = ScGlobal::GetRscString( STR_PIVOT_DATA ); maPTInfo.mnCacheIdx = mrPCache.GetCacheIndex(); + maPTViewEx9Info.Init( rDPObj ); + if( const ScDPSaveData* pSaveData = rDPObj.GetSaveData() ) { // additional properties from ScDPSaveData @@ -1302,6 +1346,10 @@ void XclExpPivotTable::Save( XclExpStream& rStrm ) WriteSxli( rStrm, maPTInfo.mnDataCols, maPTInfo.mnColFields ); // SXEX WriteSxex( rStrm ); + // QSISXTAG + WriteQsiSxTag( rStrm ); + // SXVIEWEX9 + WriteSxViewEx9( rStrm ); } } @@ -1335,6 +1383,15 @@ void XclExpPivotTable::SetPropertiesFromDP( const ScDPSaveData& rSaveData ) ::set_flag( maPTInfo.mnFlags, EXC_SXVIEW_COLGRAND, rSaveData.GetColumnGrand() ); ::set_flag( maPTExtInfo.mnFlags, EXC_SXEX_DRILLDOWN, rSaveData.GetDrillDown() ); mbFilterBtn = rSaveData.GetFilterButton(); + const ScDPSaveDimension* pDim = rSaveData.GetExistingDataLayoutDimension(); + if (!pDim) + return; + + const rtl::OUString* pLayoutName = pDim->GetLayoutName(); + if (pLayoutName) + maPTInfo.maDataName = *pLayoutName; + else + maPTInfo.maDataName = ScGlobal::GetRscString(STR_PIVOT_DATA); } void XclExpPivotTable::SetFieldPropertiesFromDim( const ScDPSaveDimension& rSaveDim ) @@ -1442,13 +1499,21 @@ void XclExpPivotTable::Finalize() rnDataXclRow = rnXclRow1 + maPTInfo.mnColFields + 1; if( maDataFields.empty() ) ++rnDataXclRow; + + bool bExtraHeaderRow = (0 == maPTViewEx9Info.mnGridLayout && maPTInfo.mnColFields == 0); + if (bExtraHeaderRow) + // Insert an extra row only when there is no column field. + ++rnDataXclRow; + rnXclCol2 = ::std::max( rnXclCol2, rnDataXclCol ); rnXclRow2 = ::std::max( rnXclRow2, rnDataXclRow ); maPTInfo.mnDataCols = rnXclCol2 - rnDataXclCol + 1; maPTInfo.mnDataRows = rnXclRow2 - rnDataXclRow + 1; // first heading - maPTInfo.mnFirstHeadRow = rnXclRow1 + 1; + maPTInfo.mnFirstHeadRow = rnXclRow1; + if (bExtraHeaderRow) + maPTInfo.mnFirstHeadRow += 2; } // records ---------------------------------------------------------------- @@ -1528,6 +1593,72 @@ void XclExpPivotTable::WriteSxex( XclExpStream& rStrm ) const rStrm.EndRecord(); } +void XclExpPivotTable::WriteQsiSxTag( XclExpStream& rStrm ) const +{ + rStrm.StartRecord( 0x0802, 32 ); + + sal_uInt16 nRecordType = 0x0802; + sal_uInt16 nDummyFlags = 0x0000; + sal_uInt16 nTableType = 1; // 0 = query table : 1 = pivot table + + rStrm << nRecordType << nDummyFlags << nTableType; + + // General flags + bool bEnableRefresh = true; + bool bPCacheInvalid = false; + bool bOlapPTReport = false; + + sal_uInt16 nFlags = 0x0000; + if (bEnableRefresh) nFlags |= 0x0001; + if (bPCacheInvalid) nFlags |= 0x0002; + if (bOlapPTReport) nFlags |= 0x0004; + rStrm << nFlags; + + // Feature-specific options. The value differs depending on the table + // type, but we assume the table type is always pivot table. + sal_uInt32 nOptions = 0x00000000; + bool bNoStencil = false; + bool bHideTotal = false; + bool bEmptyRows = false; + bool bEmptyCols = false; + if (bNoStencil) nOptions |= 0x00000001; + if (bHideTotal) nOptions |= 0x00000002; + if (bEmptyRows) nOptions |= 0x00000008; + if (bEmptyCols) nOptions |= 0x00000010; + rStrm << nOptions; + + enum ExcelVersion + { + Excel2000 = 0, + ExcelXP = 1, + Excel2003 = 2, + Excel2007 = 3 + }; + ExcelVersion eXclVer = Excel2000; + sal_uInt8 nOffsetBytes = 16; + rStrm << static_cast<sal_uInt8>(eXclVer) // version table last refreshed + << static_cast<sal_uInt8>(eXclVer) // minimum version to refresh + << nOffsetBytes + << static_cast<sal_uInt8>(eXclVer); // first version created + + rStrm << XclExpString(maPTInfo.maTableName); + rStrm << static_cast<sal_uInt16>(0x0001); // no idea what this is for. + + rStrm.EndRecord(); +} + +void XclExpPivotTable::WriteSxViewEx9( XclExpStream& rStrm ) const +{ + // Until we sync the autoformat ids only export if using grid header layout + // That could only have been set via xls import so far. + if ( 0 == maPTViewEx9Info.mnGridLayout ) + { + rStrm.StartRecord( EXC_ID_SXVIEWEX9, 17 ); + rStrm << maPTViewEx9Info; + rStrm.EndRecord(); + } +} + // ============================================================================ namespace { |