summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2017-06-22 18:10:14 +0300
committerMike Kaganski <mike.kaganski@collabora.com>2017-06-26 16:45:57 +0200
commit845a70d23a20e222205a9fbc8d5c9bda04043a5a (patch)
tree06b5b97545c67330b52e57659c01cf586465980e
parentf2b846a1fefa0cd7a091204ed3f8aa00515b34fd (diff)
tdf#89139: pivotCache: output sharedItems children only for string fields
... to avoid "corrupted" warning from Excel. In case of string fields, Excel expects the item list to be present, and containsXXX attributes of sharedItems to be absent, otherwise it shows a warning about file corruption. For numeric fields, it doesn't expect item list, othervise it also warns about file corruption. Change-Id: I5ded5b836587bed3177eb0a6b6c418e459e6be8b Reviewed-on: https://gerrit.libreoffice.org/39114 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com> (cherry picked from commit 47f0e83989c4c03d9690229b6433a5541032a3eb) Reviewed-on: https://gerrit.libreoffice.org/39257 Tested-by: Mike Kaganski <mike.kaganski@collabora.com>
-rw-r--r--sc/source/filter/excel/xepivotxml.cxx102
1 files changed, 65 insertions, 37 deletions
diff --git a/sc/source/filter/excel/xepivotxml.cxx b/sc/source/filter/excel/xepivotxml.cxx
index d03403aa230b..37b94168e193 100644
--- a/sc/source/filter/excel/xepivotxml.cxx
+++ b/sc/source/filter/excel/xepivotxml.cxx
@@ -233,52 +233,80 @@ void XclExpXmlPivotCaches::SavePivotCacheXml( XclExpXmlStream& rStrm, const Entr
ScDPCache::ScDPItemDataVec::const_iterator it = rFieldItems.begin(), itEnd = rFieldItems.end();
std::set<ScDPItemData::Type> aDPTypes;
+ double fMin = std::numeric_limits<double>::infinity(), fMax = -std::numeric_limits<double>::infinity();
for (; it != itEnd; ++it)
{
- aDPTypes.insert(it->GetType());
+ ScDPItemData::Type eType = it->GetType();
+ aDPTypes.insert(eType);
+ if (eType == ScDPItemData::Value)
+ {
+ double fVal = it->GetValue();
+ fMin = std::min(fMin, fVal);
+ fMax = std::max(fMax, fVal);
+ }
}
auto aDPTypeEnd = aDPTypes.cend();
- pDefStrm->startElement(XML_sharedItems,
- XML_count, OString::number(static_cast<long>(rFieldItems.size())).getStr(),
- XML_containsMixedTypes, XclXmlUtils::ToPsz10(aDPTypes.size() > 1),
- XML_containsSemiMixedTypes, XclXmlUtils::ToPsz10(aDPTypes.size() > 1),
- XML_containsString, XclXmlUtils::ToPsz10(aDPTypes.find(ScDPItemData::String) != aDPTypeEnd),
- XML_containsNumber, XclXmlUtils::ToPsz10(aDPTypes.find(ScDPItemData::Value) != aDPTypeEnd),
- FSEND);
+ auto pAttList = sax_fastparser::FastSerializerHelper::createAttrList();
+ // tdf#89139: Only create item list for string-only fields.
+ // Using containsXXX attributes in this case makes Excel think the file is corrupted.
+ // OTOH listing items for e.g. number fields also triggers "corrupted" warning in Excel.
+ bool bListItems = aDPTypes.size() == 1 && aDPTypes.find(ScDPItemData::String) != aDPTypeEnd;
+ if (bListItems)
+ {
+ pAttList->add(XML_count, OString::number(static_cast<long>(rFieldItems.size())));
+ }
+ else
+ {
+ pAttList->add(XML_containsMixedTypes, XclXmlUtils::ToPsz10(aDPTypes.size() > 1));
+ pAttList->add(XML_containsSemiMixedTypes, XclXmlUtils::ToPsz10(aDPTypes.size() > 1));
+ pAttList->add(XML_containsString, XclXmlUtils::ToPsz10(aDPTypes.find(ScDPItemData::String) != aDPTypeEnd));
+ if (aDPTypes.find(ScDPItemData::Value) != aDPTypeEnd)
+ {
+ pAttList->add(XML_containsNumber, XclXmlUtils::ToPsz10(true));
+ pAttList->add(XML_minValue, OString::number(fMin));
+ pAttList->add(XML_maxValue, OString::number(fMax));
+ }
+ }
+ sax_fastparser::XFastAttributeListRef xAttributeList(pAttList);
- it = rFieldItems.begin();
- for (; it != itEnd; ++it)
+ pDefStrm->startElement(XML_sharedItems, xAttributeList);
+
+ if (bListItems)
{
- const ScDPItemData& rItem = *it;
- switch (rItem.GetType())
+ it = rFieldItems.begin();
+ for (; it != itEnd; ++it)
{
- case ScDPItemData::String:
- pDefStrm->singleElement(XML_s,
- XML_v, XclXmlUtils::ToOString(rItem.GetString()).getStr(),
- FSEND);
- break;
- case ScDPItemData::Value:
- pDefStrm->singleElement(XML_n,
- XML_v, OString::number(rItem.GetValue()).getStr(),
- FSEND);
- break;
- case ScDPItemData::Empty:
- pDefStrm->singleElement(XML_m, FSEND);
- break;
- case ScDPItemData::Error:
- pDefStrm->singleElement(XML_e,
- XML_v, XclXmlUtils::ToOString(rItem.GetString()).getStr(),
- FSEND);
- break;
- case ScDPItemData::GroupValue:
- case ScDPItemData::RangeStart:
- // TODO : What do we do with these types?
- pDefStrm->singleElement(XML_m, FSEND);
- break;
- default:
- ;
+ const ScDPItemData& rItem = *it;
+ switch (rItem.GetType())
+ {
+ case ScDPItemData::String:
+ pDefStrm->singleElement(XML_s,
+ XML_v, XclXmlUtils::ToOString(rItem.GetString()),
+ FSEND);
+ break;
+ case ScDPItemData::Value:
+ pDefStrm->singleElement(XML_n,
+ XML_v, OString::number(rItem.GetValue()),
+ FSEND);
+ break;
+ case ScDPItemData::Empty:
+ pDefStrm->singleElement(XML_m, FSEND);
+ break;
+ case ScDPItemData::Error:
+ pDefStrm->singleElement(XML_e,
+ XML_v, XclXmlUtils::ToOString(rItem.GetString()),
+ FSEND);
+ break;
+ case ScDPItemData::GroupValue:
+ case ScDPItemData::RangeStart:
+ // TODO : What do we do with these types?
+ pDefStrm->singleElement(XML_m, FSEND);
+ break;
+ default:
+ ;
+ }
}
}