Kaydet (Commit) 47f0e839 authored tarafından Mike Kaganski's avatar Mike Kaganski

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/39114Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarMike Kaganski <mike.kaganski@collabora.com>
üst 603a8414
...@@ -235,52 +235,80 @@ void XclExpXmlPivotCaches::SavePivotCacheXml( XclExpXmlStream& rStrm, const Entr ...@@ -235,52 +235,80 @@ void XclExpXmlPivotCaches::SavePivotCacheXml( XclExpXmlStream& rStrm, const Entr
ScDPCache::ScDPItemDataVec::const_iterator it = rFieldItems.begin(), itEnd = rFieldItems.end(); ScDPCache::ScDPItemDataVec::const_iterator it = rFieldItems.begin(), itEnd = rFieldItems.end();
std::set<ScDPItemData::Type> aDPTypes; std::set<ScDPItemData::Type> aDPTypes;
double fMin = std::numeric_limits<double>::infinity(), fMax = -std::numeric_limits<double>::infinity();
for (; it != itEnd; ++it) 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(); auto aDPTypeEnd = aDPTypes.cend();
pDefStrm->startElement(XML_sharedItems, auto pAttList = sax_fastparser::FastSerializerHelper::createAttrList();
XML_count, OString::number(static_cast<long>(rFieldItems.size())).getStr(), // tdf#89139: Only create item list for string-only fields.
XML_containsMixedTypes, XclXmlUtils::ToPsz10(aDPTypes.size() > 1), // Using containsXXX attributes in this case makes Excel think the file is corrupted.
XML_containsSemiMixedTypes, XclXmlUtils::ToPsz10(aDPTypes.size() > 1), // OTOH listing items for e.g. number fields also triggers "corrupted" warning in Excel.
XML_containsString, XclXmlUtils::ToPsz10(aDPTypes.find(ScDPItemData::String) != aDPTypeEnd), bool bListItems = aDPTypes.size() == 1 && aDPTypes.find(ScDPItemData::String) != aDPTypeEnd;
XML_containsNumber, XclXmlUtils::ToPsz10(aDPTypes.find(ScDPItemData::Value) != aDPTypeEnd), if (bListItems)
FSEND); {
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(); pDefStrm->startElement(XML_sharedItems, xAttributeList);
for (; it != itEnd; ++it)
if (bListItems)
{ {
const ScDPItemData& rItem = *it; it = rFieldItems.begin();
switch (rItem.GetType()) for (; it != itEnd; ++it)
{ {
case ScDPItemData::String: const ScDPItemData& rItem = *it;
pDefStrm->singleElement(XML_s, switch (rItem.GetType())
XML_v, XclXmlUtils::ToOString(rItem.GetString()).getStr(), {
FSEND); case ScDPItemData::String:
break; pDefStrm->singleElement(XML_s,
case ScDPItemData::Value: XML_v, XclXmlUtils::ToOString(rItem.GetString()),
pDefStrm->singleElement(XML_n, FSEND);
XML_v, OString::number(rItem.GetValue()).getStr(), break;
FSEND); case ScDPItemData::Value:
break; pDefStrm->singleElement(XML_n,
case ScDPItemData::Empty: XML_v, OString::number(rItem.GetValue()),
pDefStrm->singleElement(XML_m, FSEND); FSEND);
break; break;
case ScDPItemData::Error: case ScDPItemData::Empty:
pDefStrm->singleElement(XML_e, pDefStrm->singleElement(XML_m, FSEND);
XML_v, XclXmlUtils::ToOString(rItem.GetString()).getStr(), break;
FSEND); case ScDPItemData::Error:
break; pDefStrm->singleElement(XML_e,
case ScDPItemData::GroupValue: XML_v, XclXmlUtils::ToOString(rItem.GetString()),
case ScDPItemData::RangeStart: FSEND);
// TODO : What do we do with these types? break;
pDefStrm->singleElement(XML_m, FSEND); case ScDPItemData::GroupValue:
break; case ScDPItemData::RangeStart:
default: // TODO : What do we do with these types?
; pDefStrm->singleElement(XML_m, FSEND);
break;
default:
;
}
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment