summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sc/inc/pivot/PivotTableFormats.hxx14
-rw-r--r--sc/qa/unit/PivotTableFormatsImportExport.cxx14
-rw-r--r--sc/source/filter/excel/xepivotxml.cxx65
-rw-r--r--sc/source/filter/excel/xestyle.cxx115
-rw-r--r--sc/source/filter/inc/PivotTableFormat.hxx5
-rw-r--r--sc/source/filter/inc/xepivotxml.hxx1
-rw-r--r--sc/source/filter/inc/xestyle.hxx8
-rw-r--r--sc/source/filter/oox/PivotTableFormat.cxx15
8 files changed, 184 insertions, 53 deletions
diff --git a/sc/inc/pivot/PivotTableFormats.hxx b/sc/inc/pivot/PivotTableFormats.hxx
index 2665c088625c..3a4d12e16479 100644
--- a/sc/inc/pivot/PivotTableFormats.hxx
+++ b/sc/inc/pivot/PivotTableFormats.hxx
@@ -28,6 +28,7 @@ enum class FormatType
/** Information to make a selection in the pivot table. */
struct Selection
{
+ bool bSelected = false;
sal_Int32 nField = 0;
sal_uInt32 nDataIndex = 0;
};
@@ -38,8 +39,17 @@ struct Selection
struct PivotTableFormat
{
FormatType eType = FormatType::None;
+
+ bool bDataOnly = true;
+ bool bLabelOnly = false;
+ bool bSelected = false;
+ bool bOutline = false;
+ std::optional<sal_uInt32> oFieldPosition = std::nullopt;
+
std::vector<Selection> aSelections;
std::shared_ptr<ScPatternAttr> pPattern;
+
+ std::vector<Selection> const& getSelections() const { return aSelections; }
};
/** A holder for a collection of PivotTableFormat */
@@ -50,9 +60,9 @@ class PivotTableFormats
public:
void add(PivotTableFormat const& rPivotTableFormat) { maFormats.push_back(rPivotTableFormat); }
- size_t size() { return maFormats.size(); }
+ size_t size() const { return maFormats.size(); }
- std::vector<PivotTableFormat> const& getVector() { return maFormats; }
+ std::vector<PivotTableFormat> const& getVector() const { return maFormats; }
};
}
diff --git a/sc/qa/unit/PivotTableFormatsImportExport.cxx b/sc/qa/unit/PivotTableFormatsImportExport.cxx
index 3cffe8cbc510..401e190b34f5 100644
--- a/sc/qa/unit/PivotTableFormatsImportExport.cxx
+++ b/sc/qa/unit/PivotTableFormatsImportExport.cxx
@@ -73,6 +73,8 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport,
createScDoc("xlsx/pivot-table/PivotTableCellFormatsTest_1_DataFieldInRow_RowLabelColor.xlsx");
assertDocument(*getScDoc());
+ saveAndReload("Calc Office Open XML");
+ assertDocument(*getScDoc());
}
CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport,
@@ -85,6 +87,8 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport,
createScDoc(
"xlsx/pivot-table/PivotTableCellFormatsTest_2_DataFieldInRow_ColumnLabelColor.xlsx");
assertDocument(*getScDoc());
+ saveAndReload("Calc Office Open XML");
+ assertDocument(*getScDoc());
}
CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport,
@@ -98,6 +102,8 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport,
createScDoc(
"xlsx/pivot-table/PivotTableCellFormatsTest_3_DataFieldInColumn_ColumnLabelColor.xlsx");
assertDocument(*getScDoc());
+ saveAndReload("Calc Office Open XML");
+ assertDocument(*getScDoc());
}
CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport,
@@ -110,6 +116,8 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport,
createScDoc("xlsx/pivot-table/PivotTableCellFormatsTest_4_DataFieldInColumn_DataColor.xlsx");
assertDocument(*getScDoc());
+ saveAndReload("Calc Office Open XML");
+ assertDocument(*getScDoc());
}
CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport,
@@ -124,6 +132,8 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport,
createScDoc("xlsx/pivot-table//"
"PivotTableCellFormatsTest_5_DataFieldInColumnAndTwoRowFields_DataColor.xlsx");
assertDocument(*getScDoc());
+ saveAndReload("Calc Office Open XML");
+ assertDocument(*getScDoc());
}
CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport,
@@ -137,6 +147,8 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport,
createScDoc(
"xlsx/pivot-table//PivotTableCellFormatsTest_6_SingleDataFieldInColumn_DataColor.xlsx");
assertDocument(*getScDoc());
+ saveAndReload("Calc Office Open XML");
+ assertDocument(*getScDoc());
}
CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport,
@@ -154,6 +166,8 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport,
createScDoc(
"xlsx/pivot-table//PivotTableCellFormatsTest_7_TwoRowTwoColumnFields_DataColor.xlsx");
assertDocument(*getScDoc());
+ saveAndReload("Calc Office Open XML");
+ assertDocument(*getScDoc());
}
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sc/source/filter/excel/xepivotxml.cxx b/sc/source/filter/excel/xepivotxml.cxx
index 633499eadb5e..81f1c71f30a6 100644
--- a/sc/source/filter/excel/xepivotxml.cxx
+++ b/sc/source/filter/excel/xepivotxml.cxx
@@ -9,6 +9,7 @@
#include <xepivotxml.hxx>
#include <dpcache.hxx>
+#include <pivot/PivotTableFormats.hxx>
#include <dpdimsave.hxx>
#include <dpitemdata.hxx>
#include <dpobject.hxx>
@@ -27,6 +28,7 @@
#include <sal/log.hxx>
#include <sax/tools/converter.hxx>
#include <sax/fastattribs.hxx>
+#include <sax/fshelper.hxx>
#include <svl/numformat.hxx>
#include <com/sun/star/beans/XPropertySet.hpp>
@@ -1181,6 +1183,9 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP
pPivotStrm->endElement(XML_dataFields);
}
+ // <formats>
+ savePivotTableFormats(rStrm, rDPObj);
+
// Now add style info (use grab bag, or just a set which is default on Excel 2007 through 2016)
if (const auto [bHas, aVal] = rDPObj.GetInteropGrabBagValue("pivotTableStyleInfo"); bHas)
WriteGrabBagItemToStream(rStrm, XML_pivotTableStyleInfo, aVal);
@@ -1202,6 +1207,66 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP
pPivotStrm->endElement(XML_pivotTableDefinition);
}
+void XclExpXmlPivotTables::savePivotTableFormats(XclExpXmlStream& rStream, ScDPObject const& rDPObject)
+{
+ sax_fastparser::FSHelperPtr& pPivotStream = rStream.GetCurrentStream();
+
+ ScDPSaveData* pSaveData = rDPObject.GetSaveData();
+ if (pSaveData && pSaveData->hasFormats())
+ {
+ sc::PivotTableFormats const& rFormats = pSaveData->getFormats();
+ if (rFormats.size() > 0)
+ {
+ pPivotStream->startElement(XML_formats, XML_count, OString::number(rFormats.size()));
+
+ for (auto const& rFormat : rFormats.getVector())
+ {
+ if (!rFormat.pPattern)
+ continue;
+
+ sal_Int32 nDxf = GetDxfs().GetDxfIdForPattern(rFormat.pPattern.get());
+ if (nDxf == -1)
+ continue;
+
+ pPivotStream->startElement(XML_format, XML_dxfId, OString::number(nDxf));
+ {
+ auto pAttributeList = sax_fastparser::FastSerializerHelper::createAttrList();
+ if (!rFormat.bDataOnly) // default is true
+ pAttributeList->add(XML_dataOnly, "0");
+ if (rFormat.bLabelOnly) // default is false
+ pAttributeList->add(XML_labelOnly, "1");
+ if (!rFormat.bOutline) // default is true
+ pAttributeList->add(XML_outline, "0");
+ if (rFormat.oFieldPosition)
+ pAttributeList->add(XML_fieldPosition, OString::number(*rFormat.oFieldPosition));
+ pPivotStream->startElement(XML_pivotArea, pAttributeList);
+ }
+ pPivotStream->startElement(XML_references, XML_count, OString::number(rFormat.aSelections.size()));
+ for (sc::Selection const& rSelection : rFormat.getSelections())
+ {
+ {
+ auto pRefAttributeList = sax_fastparser::FastSerializerHelper::createAttrList();
+ pRefAttributeList->add(XML_field, OString::number(sal_uInt32(rSelection.nField)));
+ pRefAttributeList->add(XML_count, "1");
+ if (!rSelection.bSelected) // default is true
+ pRefAttributeList->add(XML_selected, "0");
+ pPivotStream->startElement(XML_reference, pRefAttributeList);
+ }
+
+ pPivotStream->singleElement(XML_x, XML_v, OString::number(rSelection.nDataIndex));
+
+ pPivotStream->endElement(XML_reference);
+ }
+ pPivotStream->endElement(XML_references);
+ pPivotStream->endElement(XML_pivotArea);
+
+ pPivotStream->endElement(XML_format);
+ }
+ pPivotStream->endElement(XML_formats);
+ }
+ }
+}
+
void XclExpXmlPivotTables::AppendTable( const ScDPObject* pTable, sal_Int32 nCacheId, sal_Int32 nPivotId )
{
maTables.emplace_back(pTable, nCacheId, nPivotId);
diff --git a/sc/source/filter/excel/xestyle.cxx b/sc/source/filter/excel/xestyle.cxx
index 6ee407c369f9..057bee7b30f4 100644
--- a/sc/source/filter/excel/xestyle.cxx
+++ b/sc/source/filter/excel/xestyle.cxx
@@ -50,6 +50,9 @@
#include <dbdata.hxx>
#include <filterentries.hxx>
#include <export/ExportTools.hxx>
+#include <dpobject.hxx>
+#include <dpsave.hxx>
+#include <pivot/PivotTableFormats.hxx>
#include <o3tl/safeint.hxx>
#include <oox/export/utils.hxx>
@@ -3070,7 +3073,6 @@ XclExpDxfs::XclExpDxfs( const XclExpRoot& rRoot )
xFormatter->FillKeywordTableForExcel( *mpKeywordTable );
SCTAB nTables = rRoot.GetDoc().GetTableCount();
- sal_Int32 nDxfId = 0;
for(SCTAB nTab = 0; nTab < nTables; ++nTab)
{
// Color filters
@@ -3089,21 +3091,21 @@ XclExpDxfs::XclExpDxfs( const XclExpRoot& rRoot )
// Does not matter it is text color or cell background color
for (auto& rColor : aFilterEntries.getBackgroundColors())
{
- if (!maColorToDxfId.emplace(rColor, nDxfId).second)
+ if (!maColorToDxfId.emplace(rColor, mnDxfId).second)
continue;
std::unique_ptr<XclExpCellArea> pExpCellArea(new XclExpCellArea(rColor, 0));
maDxf.push_back(std::make_unique<XclExpDxf>(rRoot, std::move(pExpCellArea)));
- nDxfId++;
+ mnDxfId++;
}
for (auto& rColor : aFilterEntries.getTextColors())
{
- if (!maColorToDxfId.emplace(rColor, nDxfId).second)
+ if (!maColorToDxfId.emplace(rColor, mnDxfId).second)
continue;
std::unique_ptr<XclExpCellArea> pExpCellArea(new XclExpCellArea(rColor, 0));
maDxf.push_back(std::make_unique<XclExpDxf>(rRoot, std::move(pExpCellArea)));
- nDxfId++;
+ mnDxfId++;
}
}
}
@@ -3137,57 +3139,74 @@ XclExpDxfs::XclExpDxfs( const XclExpRoot& rRoot )
aStyleName = pEntry->GetStyleName();
}
- if (maStyleNameToDxfId.emplace(aStyleName, nDxfId).second)
+ if (maStyleNameToDxfId.emplace(aStyleName, mnDxfId).second)
{
SfxStyleSheetBase* pStyle = rRoot.GetDoc().GetStyleSheetPool()->Find(aStyleName, SfxStyleFamily::Para);
if(!pStyle)
continue;
SfxItemSet& rSet = pStyle->GetItemSet();
-
- std::unique_ptr<XclExpCellBorder> pBorder(new XclExpCellBorder);
- if (!pBorder->FillFromItemSet( rSet, GetPalette(), GetBiff()) )
- {
- pBorder.reset();
- }
-
- std::unique_ptr<XclExpCellAlign> pAlign(new XclExpCellAlign);
- if (!pAlign->FillFromItemSet(rRoot, rSet, false, GetBiff()))
- {
- pAlign.reset();
- }
-
- std::unique_ptr<XclExpCellProt> pCellProt(new XclExpCellProt);
- if (!pCellProt->FillFromItemSet( rSet ))
- {
- pCellProt.reset();
- }
-
- std::unique_ptr<XclExpColor> pColor(new XclExpColor);
- if(!pColor->FillFromItemSet( rSet ))
- {
- pColor.reset();
- }
-
- std::unique_ptr<XclExpDxfFont> pFont(new XclExpDxfFont(rRoot, rSet));
-
- std::unique_ptr<XclExpNumFmt> pNumFormat;
- if( const SfxUInt32Item *pPoolItem = rSet.GetItemIfSet( ATTR_VALUE_FORMAT ) )
- {
- sal_uInt32 nScNumFmt = pPoolItem->GetValue();
- sal_Int32 nXclNumFmt = GetRoot().GetNumFmtBuffer().Insert(nScNumFmt);
- pNumFormat.reset(new XclExpNumFmt( nScNumFmt, nXclNumFmt, GetNumberFormatCode( *this, nScNumFmt, xFormatter.get(), mpKeywordTable.get() )));
- }
-
- maDxf.push_back(std::make_unique<XclExpDxf>( rRoot, std::move(pAlign), std::move(pBorder),
- std::move(pFont), std::move(pNumFormat), std::move(pCellProt), std::move(pColor) ));
- ++nDxfId;
+ fillDxfFrom(rSet, xFormatter);
+ mnDxfId++;
}
}
}
}
}
+
+ ScDPCollection* pCollection = rRoot.GetDoc().GetDPCollection();
+ for (size_t nIndex = 0; nIndex < pCollection->GetCount(); nIndex++)
+ {
+ const ScDPObject& rObject = (*pCollection)[nIndex];
+ ScDPSaveData* pSaveData = rObject.GetSaveData();
+ if (pSaveData && pSaveData->hasFormats())
+ {
+ sc::PivotTableFormats const& rFormats = pSaveData->getFormats();
+ for (sc::PivotTableFormat const& rFormat : rFormats.getVector())
+ {
+ if (!rFormat.pPattern)
+ continue;
+
+ SfxItemSet& rItemSet = rFormat.pPattern->GetItemSet();
+ fillDxfFrom(rItemSet, xFormatter);
+ maPatternToDxfId.emplace(rFormat.pPattern.get(), mnDxfId);
+ mnDxfId++;
+ }
+ }
+ }
+}
+
+void XclExpDxfs::fillDxfFrom(SfxItemSet& rItemSet, SvNumberFormatterPtr& xFormatter)
+{
+ std::unique_ptr<XclExpCellBorder> pBorder(new XclExpCellBorder);
+ if (!pBorder->FillFromItemSet(rItemSet, GetPalette(), GetBiff()))
+ pBorder.reset();
+
+ std::unique_ptr<XclExpCellAlign> pAlign(new XclExpCellAlign);
+ if (!pAlign->FillFromItemSet(GetRoot(), rItemSet, false, GetBiff()))
+ pAlign.reset();
+
+ std::unique_ptr<XclExpCellProt> pCellProtection(new XclExpCellProt);
+ if (!pCellProtection->FillFromItemSet(rItemSet))
+ pCellProtection.reset();
+
+ std::unique_ptr<XclExpColor> pColor(new XclExpColor);
+ if (!pColor->FillFromItemSet(rItemSet))
+ pColor.reset();
+
+ std::unique_ptr<XclExpDxfFont> pFont(new XclExpDxfFont(GetRoot(), rItemSet));
+
+ std::unique_ptr<XclExpNumFmt> pNumberFormat;
+ if (const SfxUInt32Item* pPoolItem = rItemSet.GetItemIfSet(ATTR_VALUE_FORMAT))
+ {
+ sal_uInt32 nScNumberFormat = pPoolItem->GetValue();
+ sal_Int32 nXclNumberFormat = GetRoot().GetNumFmtBuffer().Insert(nScNumberFormat);
+ pNumberFormat.reset(new XclExpNumFmt(nScNumberFormat, nXclNumberFormat, GetNumberFormatCode(*this, nScNumberFormat, xFormatter.get(), mpKeywordTable.get())));
+ }
+
+ maDxf.push_back(std::make_unique<XclExpDxf>(GetRoot(), std::move(pAlign), std::move(pBorder),
+ std::move(pFont), std::move(pNumberFormat), std::move(pCellProtection), std::move(pColor)));
}
sal_Int32 XclExpDxfs::GetDxfId( const OUString& rStyleName ) const
@@ -3206,6 +3225,14 @@ sal_Int32 XclExpDxfs::GetDxfByColor(Color aColor) const
return -1;
}
+sal_Int32 XclExpDxfs::GetDxfIdForPattern(ScPatternAttr* pPattern) const
+{
+ auto iterator = maPatternToDxfId.find(pPattern);
+ if (iterator != maPatternToDxfId.end())
+ return iterator->second;
+ return -1;
+}
+
void XclExpDxfs::addColor(Color aColor)
{
maColorToDxfId.emplace(aColor, maDxf.size());
diff --git a/sc/source/filter/inc/PivotTableFormat.hxx b/sc/source/filter/inc/PivotTableFormat.hxx
index 204dea566def..3a7b56cf423b 100644
--- a/sc/source/filter/inc/PivotTableFormat.hxx
+++ b/sc/source/filter/inc/PivotTableFormat.hxx
@@ -43,16 +43,17 @@ private:
// PivotArea
std::optional<sal_Int32> mnField;
PivotAreaType meType = PivotAreaType::Normal;
+ std::optional<sal_uInt32> moField = std::nullopt;
bool mbDataOnly = true;
bool mbLabelOnly = false;
bool mbGrandRow = false;
bool mbGrandCol = false;
bool mbCacheIndex = false;
bool mbOutline = true;
- std::optional<OUString> msOffset;
+ std::optional<OUString> moOffset = std::nullopt;
bool mbCollapsedLevelsAreSubtotals = false;
// TODO Axis
- std::optional<sal_uInt32> mnFieldPosition;
+ std::optional<sal_uInt32> moFieldPosition = std::nullopt;
std::vector<std::shared_ptr<PivotTableReference>> maReferences;
diff --git a/sc/source/filter/inc/xepivotxml.hxx b/sc/source/filter/inc/xepivotxml.hxx
index 30fb25a30f48..5e02ba214b78 100644
--- a/sc/source/filter/inc/xepivotxml.hxx
+++ b/sc/source/filter/inc/xepivotxml.hxx
@@ -66,6 +66,7 @@ public:
private:
void SavePivotTableXml(XclExpXmlStream& rStrm, const ScDPObject& rObj, sal_Int32 nCacheId);
+ void savePivotTableFormats(XclExpXmlStream& rStrm, ScDPObject const& rDPObject);
};
class XclExpXmlPivotTableManager : protected XclExpRoot
diff --git a/sc/source/filter/inc/xestyle.hxx b/sc/source/filter/inc/xestyle.hxx
index dd290af06825..740c892dcb68 100644
--- a/sc/source/filter/inc/xestyle.hxx
+++ b/sc/source/filter/inc/xestyle.hxx
@@ -758,9 +758,10 @@ private:
class XclExpDxfs : public XclExpRecordBase, protected XclExpRoot
{
public:
- XclExpDxfs( const XclExpRoot& rRoot );
+ XclExpDxfs(const XclExpRoot& rRoot);
sal_Int32 GetDxfId(const OUString& rName) const;
+ sal_Int32 GetDxfIdForPattern(ScPatternAttr* pPattern) const;
sal_Int32 GetDxfByColor(Color aColor) const;
void addColor(Color aColor);
@@ -769,10 +770,15 @@ public:
private:
typedef std::vector< std::unique_ptr<XclExpDxf> > DxfContainer;
+ sal_Int32 mnDxfId = 0;
std::map<OUString, sal_Int32> maStyleNameToDxfId;
std::map<Color, sal_Int32> maColorToDxfId;
+ std::map<ScPatternAttr*, sal_Int32> maPatternToDxfId;
DxfContainer maDxf;
std::unique_ptr<NfKeywordTable> mpKeywordTable; /// Replacement table.
+
+ void fillDxfFrom(SfxItemSet& rItemSet, SvNumberFormatterPtr& xFormatter);
+
};
class XclExpXmlStyleSheet : public XclExpRecordBase, protected XclExpRoot
diff --git a/sc/source/filter/oox/PivotTableFormat.cxx b/sc/source/filter/oox/PivotTableFormat.cxx
index 9b16087400d2..156fe9983a6e 100644
--- a/sc/source/filter/oox/PivotTableFormat.cxx
+++ b/sc/source/filter/oox/PivotTableFormat.cxx
@@ -62,15 +62,16 @@ void PivotTableFormat::importPivotArea(const oox::AttributeList& rAttribs)
}
}
+ moField = rAttribs.getUnsigned(XML_field);
mbDataOnly = rAttribs.getBool(XML_dataOnly, true);
mbLabelOnly = rAttribs.getBool(XML_labelOnly, false);
mbGrandRow = rAttribs.getBool(XML_grandRow, false);
mbGrandCol = rAttribs.getBool(XML_grandCol, false);
mbCacheIndex = rAttribs.getBool(XML_cacheIndex, false);
- mbOutline = rAttribs.getBool(XML_cacheIndex, true);
- msOffset = rAttribs.getXString(XML_offset);
+ mbOutline = rAttribs.getBool(XML_outline, true);
+ moOffset = rAttribs.getXString(XML_offset);
mbCollapsedLevelsAreSubtotals = rAttribs.getBool(XML_collapsedLevelsAreSubtotals, false);
- mnFieldPosition = rAttribs.getUnsigned(XML_field);
+ moFieldPosition = rAttribs.getUnsigned(XML_fieldPosition);
}
void PivotTableFormat::finalizeImport()
@@ -95,13 +96,19 @@ void PivotTableFormat::finalizeImport()
else if (mbLabelOnly)
aFormat.eType = sc::FormatType::Label;
+ aFormat.bDataOnly = mbDataOnly;
+ aFormat.bLabelOnly = mbLabelOnly;
+ aFormat.bOutline = mbOutline;
+ aFormat.oFieldPosition = moFieldPosition;
+
aFormat.pPattern = pPattern;
for (auto& rReference : maReferences)
{
if (rReference->mnField)
{
aFormat.aSelections.push_back(
- sc::Selection{ .nField = sal_Int32(*rReference->mnField),
+ sc::Selection{ .bSelected = rReference->mbSelected,
+ .nField = sal_Int32(*rReference->mnField),
.nDataIndex = rReference->maFieldItemsIndices[0] });
}
}