include/xmloff/xmltoken.hxx                                 |   26 
 oox/source/core/xmlfilterbase.cxx                           |    2 
 oox/source/token/namespaces-strict.txt                      |    1 
 oox/source/token/namespaces.hxx.tail                        |    1 
 oox/source/token/namespaces.txt                             |    1 
 oox/source/token/tokens.txt                                 |    1 
 sc/CppunitTest_sc_sparkline_test.mk                         |    6 
 sc/Library_sc.mk                                            |    2 
 sc/inc/SparklineGroup.hxx                                   |   10 
 sc/qa/unit/SparklineImportExportTest.cxx                    |   87 ++-
 sc/source/filter/excel/excdoc.cxx                           |    1 
 sc/source/filter/excel/export/SparklineExt.cxx              |    6 
 sc/source/filter/oox/SparklineFragment.cxx                  |    3 
 sc/source/filter/xml/SparklineGroupsExport.cxx              |  222 ++++++++
 sc/source/filter/xml/SparklineGroupsExport.hxx              |   48 +
 sc/source/filter/xml/SparklineGroupsImportContext.cxx       |  332 ++++++++++++
 sc/source/filter/xml/SparklineGroupsImportContext.hxx       |   61 ++
 sc/source/filter/xml/xmlexprt.cxx                           |   15 
 sc/source/filter/xml/xmlexprt.hxx                           |    1 
 sc/source/filter/xml/xmltabi.cxx                            |    5 
 schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng |  165 +++++
 test/source/xmltesttools.cxx                                |    2 
 xmloff/source/core/xmltoken.cxx                             |   28 -
 xmloff/source/token/tokens.txt                              |   26 
 24 files changed, 1044 insertions(+), 8 deletions(-)

New commits:
commit 88214d0f7d55e4b1ccced5f1ec0790d446da8ab6
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Fri Mar 25 14:53:48 2022 +0900
Commit:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
CommitDate: Sat Mar 26 01:37:27 2022 +0900

    sc: sparkline import/export for ODF
    
    Change-Id: I0d8293cdd35cc8c7afab98efac0a28a3613d122b

diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index 4f7cd7e148a4..dc7c930f0e2a 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -449,8 +449,16 @@ namespace xmloff::token {
         XML_CODEBASE,
         XML_COLLAPSE,
         XML_COLOR,
+        XML_COLOR_AXIS,
+        XML_COLOR_FIRST,
+        XML_COLOR_HIGH,
         XML_COLOR_INVERSION,
+        XML_COLOR_LAST,
+        XML_COLOR_LOW,
+        XML_COLOR_MARKERS,
         XML_COLOR_MODE,
+        XML_COLOR_NEGATIVE,
+        XML_COLOR_SERIES,
         XML_COLOR_SCALE,
         XML_COLOR_SCALE_ENTRY,
         XML_COLOR_TABLE,
@@ -593,6 +601,7 @@ namespace xmloff::token {
         XML_DATA_PILOT_TABLE,
         XML_DATA_PILOT_TABLES,
         XML_DATA_POINT,
+        XML_DATA_RANGE,
         XML_DATA_STREAM_SOURCE,
         XML_DATA_STYLE,
         XML_DATA_STYLE_NAME,
@@ -609,6 +618,7 @@ namespace xmloff::token {
         XML_DATABASE_SOURCE_TABLE,
         XML_DATABASE_TABLE_NAME,
         XML_DATE,
+        XML_DATE_AXIS,
         XML_DATE_IS,
         XML_DATE_ADJUST,
         XML_DATE_STYLE,
@@ -668,12 +678,15 @@ namespace xmloff::token {
         XML_DISPLAY_DETAILS,
         XML_DISPLAY_DUPLICATES,
         XML_DISPLAY_EMPTY,
+        XML_DISPLAY_EMPTY_CELLS_AS,
         XML_DISPLAY_FILTER_BUTTONS,
         XML_DISPLAY_FORMULA,
+        XML_DISPLAY_HIDDEN,
         XML_DISPLAY_LABEL,
         XML_DISPLAY_LEVELS,
         XML_DISPLAY_NAME,
         XML_DISPLAY_OUTLINE_LEVEL,
+        XML_DISPLAY_X_AXIS,
         XML_DISSOLVE,
         XML_DISTANCE,
         XML_DISTANCE_AFTER_SEP,
@@ -1180,6 +1193,7 @@ namespace xmloff::token {
         XML_LINE_SKEW,
         XML_LINE_SPACING,
         XML_LINE_STYLE,
+        XML_LINE_WIDTH,
         XML_LINEAR,
         XML_LINEARGRADIENT,
         XML_LINENUMBERING_CONFIGURATION,
@@ -1207,6 +1221,7 @@ namespace xmloff::token {
         XML_LOGARITHMIC,
         XML_LOGBASE,
         XML_LONG,
+        XML_LOW,
         XML_LOWLIMIT,
         XML_LR_TB,
         XML_LT,
@@ -1220,6 +1235,8 @@ namespace xmloff::token {
         XML_MALIGNGROUP,
         XML_MALIGNMARK,
         XML_MANUAL,
+        XML_MANUAL_MIN,
+        XML_MANUAL_MAX,
         XML_MAP,
         XML_MARGIN_BOTTOM,
         XML_MARGIN_LEFT,
@@ -1227,6 +1244,7 @@ namespace xmloff::token {
         XML_MARGIN_TOP,
         XML_MARGINS,
         XML_MARKER,
+        XML_MARKERS,
         XML_MARKER_END,
         XML_MARKER_END_CENTER,
         XML_MARKER_END_WIDTH,
@@ -1245,6 +1263,7 @@ namespace xmloff::token {
         XML_MATRIX_COVERED,
         XML_MATRIXROW,
         XML_MAX,
+        XML_MAX_AXIS_TYPE,
         XML_MAX_EDGE,
         XML_MAX_HEIGHT,
         XML_MAX_LENGTH,
@@ -1270,6 +1289,7 @@ namespace xmloff::token {
         XML_MIDDLE,
         XML_MIME_TYPE,
         XML_MIN,
+        XML_MIN_AXIS_TYPE,
         XML_MIN_DENOMINATOR_DIGITS,
         XML_MIN_EDGE,
         XML_MIN_EXPONENT_DIGITS,
@@ -1344,6 +1364,7 @@ namespace xmloff::token {
         XML_NAMED_RANGE,
         XML_NAVIGATION_MODE,
         XML_NAVY,
+        XML_NEGATIVE,
         XML_NEGATIVE_COLOR,
         XML_NEQ,
         XML_NEW,
@@ -1605,6 +1626,7 @@ namespace xmloff::token {
         XML_RIGHT,
         XML_RIGHT_OUTSIDE,
         XML_RIGHT_TEXT,
+        XML_RIGHT_TO_LEFT,
         XML_RIGHTARC,
         XML_RIGHTCIRCLE,
         XML_RING,
@@ -1759,6 +1781,10 @@ namespace xmloff::token {
         XML_SOURCE_RANGE_ADDRESS,
         XML_SOURCE_SERVICE,
         XML_SPACE_BEFORE,
+        XML_SPARKLINE_GROUPS,
+        XML_SPARKLINE_GROUP,
+        XML_SPARKLINES,
+        XML_SPARKLINE,
         XML_SPAN,
         XML_SPECULAR,
         XML_SPECULAR_COLOR,
diff --git a/sc/CppunitTest_sc_sparkline_test.mk 
b/sc/CppunitTest_sc_sparkline_test.mk
index 499eaaf4ea38..a3e8078a9b83 100644
--- a/sc/CppunitTest_sc_sparkline_test.mk
+++ b/sc/CppunitTest_sc_sparkline_test.mk
@@ -18,6 +18,12 @@ $(eval $(call 
gb_CppunitTest_add_exception_objects,sc_sparkline_test, \
     sc/qa/unit/SparklineTest \
 ))
 
+$(eval $(call gb_CppunitTest_use_externals,sc_sparkline_test, \
+    boost_headers \
+    mdds_headers \
+    libxml2 \
+))
+
 $(eval $(call gb_CppunitTest_use_libraries,sc_sparkline_test, \
     basegfx \
     comphelper \
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index 2c78147abf62..e97f6e04b4c2 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -293,6 +293,8 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
     sc/source/core/tool/webservicelink \
     sc/source/core/tool/zforauto \
     sc/source/filter/xml/datastreamimport \
+    sc/source/filter/xml/SparklineGroupsExport \
+    sc/source/filter/xml/SparklineGroupsImportContext \
     sc/source/filter/xml/XMLCalculationSettingsContext \
     sc/source/filter/xml/XMLCellRangeSourceContext \
     sc/source/filter/xml/XMLChangeTrackingExportHelper \
diff --git a/sc/inc/SparklineGroup.hxx b/sc/inc/SparklineGroup.hxx
index b376ea08bccb..5b2490e08af5 100644
--- a/sc/inc/SparklineGroup.hxx
+++ b/sc/inc/SparklineGroup.hxx
@@ -25,11 +25,16 @@ private:
 
 public:
     SparklineAttributes& getAttributes() { return m_aAttributes; }
+    SparklineAttributes const& getAttributes() const { return m_aAttributes; }
 
     OUString getID() { return m_sUID; }
 
     void setID(OUString const& rID) { m_sUID = rID; }
 
+    OUString const& getID() { return m_sUID; }
+
+    void setID(OUString const& rID) { m_sUID = rID; }
+
     SparklineGroup();
 
     SparklineGroup(SparklineGroup const& pOtherSparkline);
diff --git a/sc/qa/unit/SparklineImportExportTest.cxx 
b/sc/qa/unit/SparklineImportExportTest.cxx
index 599c795c3271..591916e9a932 100644
--- a/sc/qa/unit/SparklineImportExportTest.cxx
+++ b/sc/qa/unit/SparklineImportExportTest.cxx
@@ -8,6 +8,7 @@
  */
 
 #include "helper/qahelper.hxx"
+#include "helper/xpath.hxx"
 
 #include <com/sun/star/lang/XComponent.hpp>
 #include <docsh.hxx>
@@ -16,7 +17,7 @@
 
 using namespace css;
 
-class SparklineImportExportTest : public ScBootstrapFixture
+class SparklineImportExportTest : public ScBootstrapFixture, public 
XmlTestTools
 {
 private:
     uno::Reference<uno::XInterface> m_xCalcComponent;
@@ -44,10 +45,19 @@ public:
         test::BootstrapFixture::tearDown();
     }
 
-    void testSparklines();
+    virtual void registerNamespaces(xmlXPathContextPtr& pXmlXPathContextPtr) 
override
+    {
+        XmlTestTools::registerODFNamespaces(pXmlXPathContextPtr);
+    }
+
+    void testSparklinesRoundtripXLSX();
+    void testSparklinesExportODS();
+    void testSparklinesRoundtripODS();
 
     CPPUNIT_TEST_SUITE(SparklineImportExportTest);
-    CPPUNIT_TEST(testSparklines);
+    CPPUNIT_TEST(testSparklinesRoundtripXLSX);
+    CPPUNIT_TEST(testSparklinesExportODS);
+    CPPUNIT_TEST(testSparklinesRoundtripODS);
     CPPUNIT_TEST_SUITE_END();
 };
 
@@ -74,7 +84,7 @@ void checkSparklines(ScDocument& rDocument)
         CPPUNIT_ASSERT_EQUAL(Color(0x92d050), rAttributes.getColorHigh());
         CPPUNIT_ASSERT_EQUAL(Color(0x00b0f0), rAttributes.getColorLow());
 
-        CPPUNIT_ASSERT_EQUAL(1.0, rAttributes.getLineWeight());
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0, rAttributes.getLineWeight(), 1E-2);
         CPPUNIT_ASSERT_EQUAL(false, rAttributes.isDateAxis());
         CPPUNIT_ASSERT_EQUAL(sc::DisplayEmptyCellsAs::Gap, 
rAttributes.getDisplayEmptyCellsAs());
 
@@ -154,7 +164,7 @@ void checkSparklines(ScDocument& rDocument)
 
 } // end anonymous namespace
 
-void SparklineImportExportTest::testSparklines()
+void SparklineImportExportTest::testSparklinesRoundtripXLSX()
 {
     ScDocShellRef xDocSh = loadDoc(u"Sparklines.", FORMAT_XLSX);
     CPPUNIT_ASSERT(xDocSh);
@@ -168,6 +178,70 @@ void SparklineImportExportTest::testSparklines()
     xDocSh->DoClose();
 }
 
+void SparklineImportExportTest::testSparklinesExportODS()
+{
+    // Load the document containing sparklines
+    ScDocShellRef xDocSh = loadDoc(u"Sparklines.", FORMAT_XLSX);
+    CPPUNIT_ASSERT(xDocSh);
+
+    // Save as ODS and check content.xml with XPath
+    std::shared_ptr<utl::TempFile> pXPathFile = 
ScBootstrapFixture::exportTo(*xDocSh, FORMAT_ODS);
+    xmlDocUniquePtr pXmlDoc = XPathHelper::parseExport(pXPathFile, 
m_xSFactory, "content.xml");
+
+    // We have 3 sparkline groups = 3 tables that contain spakrlines
+    assertXPath(pXmlDoc, "//table:table/calcext:sparkline-groups", 3);
+
+    // Check the number of sparkline groups in table[1]
+    assertXPath(pXmlDoc, 
"//table:table[1]/calcext:sparkline-groups/calcext:sparkline-group", 2);
+    // Check the number of sparkline groups in table[2]
+    assertXPath(pXmlDoc, 
"//table:table[2]/calcext:sparkline-groups/calcext:sparkline-group", 2);
+    // Check the number of sparkline groups in table[3]
+    assertXPath(pXmlDoc, 
"//table:table[3]/calcext:sparkline-groups/calcext:sparkline-group", 3);
+
+    // Check table[1] - sparkline-group[1]
+    OString aSparklineGroupPath
+        = 
"//table:table[1]/calcext:sparkline-groups/calcext:sparkline-group[1]";
+    assertXPath(pXmlDoc, aSparklineGroupPath, "type", "line");
+    assertXPath(pXmlDoc, aSparklineGroupPath, "line-width", "1pt");
+    assertXPath(pXmlDoc, aSparklineGroupPath, "display-empty-cells-as", "gap");
+    assertXPath(pXmlDoc, aSparklineGroupPath, "markers", "true");
+    assertXPath(pXmlDoc, aSparklineGroupPath, "high", "true");
+    assertXPath(pXmlDoc, aSparklineGroupPath, "low", "true");
+    assertXPath(pXmlDoc, aSparklineGroupPath, "first", "true");
+    assertXPath(pXmlDoc, aSparklineGroupPath, "last", "true");
+    assertXPath(pXmlDoc, aSparklineGroupPath, "negative", "true");
+    assertXPath(pXmlDoc, aSparklineGroupPath, "display-x-axis", "true");
+    assertXPath(pXmlDoc, aSparklineGroupPath, "min-axis-type", "individual");
+    assertXPath(pXmlDoc, aSparklineGroupPath, "max-axis-type", "individual");
+    assertXPath(pXmlDoc, aSparklineGroupPath, "color-series", "#376092");
+    assertXPath(pXmlDoc, aSparklineGroupPath, "color-negative", "#00b050");
+    assertXPath(pXmlDoc, aSparklineGroupPath, "color-axis", "#000000");
+    assertXPath(pXmlDoc, aSparklineGroupPath, "color-markers", "#000000");
+    assertXPath(pXmlDoc, aSparklineGroupPath, "color-first", "#7030a0");
+    assertXPath(pXmlDoc, aSparklineGroupPath, "color-last", "#ff0000");
+    assertXPath(pXmlDoc, aSparklineGroupPath, "color-high", "#92d050");
+    assertXPath(pXmlDoc, aSparklineGroupPath, "color-low", "#00b0f0");
+
+    assertXPath(pXmlDoc, aSparklineGroupPath + 
"/calcext:sparklines/calcext:sparkline", 1);
+    assertXPath(pXmlDoc, aSparklineGroupPath + 
"/calcext:sparklines/calcext:sparkline[1]",
+                "cell-address", "Sheet1.A2");
+}
+
+void SparklineImportExportTest::testSparklinesRoundtripODS()
+{
+    ScDocShellRef xDocSh = loadDoc(u"Sparklines.", FORMAT_XLSX);
+    CPPUNIT_ASSERT(xDocSh);
+
+    checkSparklines(xDocSh->GetDocument());
+
+    // Trigger export and import of sparklines
+    xDocSh = saveAndReload(*xDocSh, FORMAT_ODS);
+
+    checkSparklines(xDocSh->GetDocument());
+
+    xDocSh->DoClose();
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SparklineImportExportTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sc/source/filter/xml/SparklineGroupsExport.cxx 
b/sc/source/filter/xml/SparklineGroupsExport.cxx
new file mode 100644
index 000000000000..6be8a616a423
--- /dev/null
+++ b/sc/source/filter/xml/SparklineGroupsExport.cxx
@@ -0,0 +1,222 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#include "SparklineGroupsExport.hxx"
+#include "xmlexprt.hxx"
+#include <rangeutl.hxx>
+
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/namespacemap.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <sax/tools/converter.hxx>
+#include <o3tl/unit_conversion.hxx>
+
+using namespace css;
+using namespace xmloff::token;
+
+namespace sc
+{
+SparklineGroupsExport::SparklineGroupsExport(
+    ScXMLExport& rExport, SCTAB nTable, 
std::vector<std::shared_ptr<Sparkline>> const& rSparklines)
+    : m_rExport(rExport)
+    , m_nTable(nTable)
+{
+    for (auto const& pSparkline : rSparklines)
+    {
+        auto* pGroupPointer = pSparkline->getSparklineGroup().get();
+        auto aIterator = m_aSparklineGroupMap.find(pGroupPointer);
+        if (aIterator == m_aSparklineGroupMap.end())
+        {
+            m_aSparklineGroups.push_back(pGroupPointer);
+            std::vector<std::shared_ptr<sc::Sparkline>> aSparklineVector;
+            aSparklineVector.push_back(pSparkline);
+            m_aSparklineGroupMap.emplace(pGroupPointer, aSparklineVector);
+        }
+        else
+        {
+            aIterator->second.push_back(pSparkline);
+        }
+    }
+}
+
+void SparklineGroupsExport::insertColor(Color aColor, XMLTokenEnum eToken)
+{
+    OUStringBuffer aStringBuffer;
+    if (aColor != COL_TRANSPARENT)
+    {
+        sax::Converter::convertColor(aStringBuffer, aColor);
+        m_rExport.AddAttribute(XML_NAMESPACE_CALC_EXT, eToken, 
aStringBuffer.makeStringAndClear());
+    }
+}
+
+void SparklineGroupsExport::insertBool(bool bValue, XMLTokenEnum eToken)
+{
+    if (bValue)
+        m_rExport.AddAttribute(XML_NAMESPACE_CALC_EXT, eToken, "true");
+}
+
+void SparklineGroupsExport::addSparklineAttributes(Sparkline const& rSparkline)
+{
+    auto const* pDocument = m_rExport.GetDocument();
+
+    {
+        OUString sAddressString;
+        ScAddress aAddress(rSparkline.getColumn(), rSparkline.getRow(), 
m_nTable);
+        ScRangeStringConverter::GetStringFromAddress(sAddressString, aAddress, 
pDocument,
+                                                     
formula::FormulaGrammar::CONV_OOO);
+        m_rExport.AddAttribute(XML_NAMESPACE_CALC_EXT, XML_CELL_ADDRESS, 
sAddressString);
+    }
+
+    {
+        OUString sDataRangeString;
+        ScRangeList const& rRangeList = rSparkline.getInputRange();
+        ScRangeStringConverter::GetStringFromRangeList(sDataRangeString, 
&rRangeList, pDocument,
+                                                       
formula::FormulaGrammar::CONV_OOO);
+        m_rExport.AddAttribute(XML_NAMESPACE_CALC_EXT, XML_DATA_RANGE, 
sDataRangeString);
+    }
+}
+
+namespace
+{
+OUString convertSparklineType(sc::SparklineType eType)
+{
+    switch (eType)
+    {
+        case sc::SparklineType::Line:
+            return u"line";
+        case sc::SparklineType::Column:
+            return u"column";
+        case sc::SparklineType::Stacked:
+            return u"stacked";
+    }
+    return u"";
+}
+
+OUString convertDisplayEmptyCellsAs(sc::DisplayEmptyCellsAs eType)
+{
+    switch (eType)
+    {
+        case sc::DisplayEmptyCellsAs::Zero:
+            return u"zero";
+        case sc::DisplayEmptyCellsAs::Gap:
+            return u"gap";
+        case sc::DisplayEmptyCellsAs::Span:
+            return u"span";
+    }
+    return u"";
+}
+
+OUString convertAxisType(sc::AxisType eType)
+{
+    switch (eType)
+    {
+        case sc::AxisType::Individual:
+            return u"individual";
+        case sc::AxisType::Group:
+            return u"group";
+        case sc::AxisType::Custom:
+            return u"custom";
+    }
+    return u"";
+}
+
+} // end anonymous ns
+
+void SparklineGroupsExport::addSparklineGroupAttributes(SparklineAttributes 
const& rAttributes)
+{
+    OUString sType = convertSparklineType(rAttributes.getType());
+    m_rExport.AddAttribute(XML_NAMESPACE_CALC_EXT, XML_TYPE, sType);
+
+    // Line Weight = Line Width in ODF
+
+    m_rExport.AddAttribute(XML_NAMESPACE_CALC_EXT, XML_LINE_WIDTH,
+                           OUString::number(rAttributes.getLineWeight()) + 
"pt");
+
+    insertBool(rAttributes.isDateAxis(), XML_DATE_AXIS);
+
+    OUString sDisplayEmptyCellsAs
+        = convertDisplayEmptyCellsAs(rAttributes.getDisplayEmptyCellsAs());
+    m_rExport.AddAttribute(XML_NAMESPACE_CALC_EXT, XML_DISPLAY_EMPTY_CELLS_AS,
+                           sDisplayEmptyCellsAs);
+
+    insertBool(rAttributes.isMarkers(), XML_MARKERS);
+    insertBool(rAttributes.isHigh(), XML_HIGH);
+    insertBool(rAttributes.isLow(), XML_LOW);
+    insertBool(rAttributes.isFirst(), XML_FIRST);
+    insertBool(rAttributes.isLast(), XML_LAST);
+    insertBool(rAttributes.isNegative(), XML_NEGATIVE);
+    insertBool(rAttributes.shouldDisplayXAxis(), XML_DISPLAY_X_AXIS);
+    insertBool(rAttributes.shouldDisplayHidden(), XML_DISPLAY_HIDDEN);
+
+    OUString sMinAxisType = convertAxisType(rAttributes.getMinAxisType());
+    m_rExport.AddAttribute(XML_NAMESPACE_CALC_EXT, XML_MIN_AXIS_TYPE, 
sMinAxisType);
+
+    OUString sMaxAxisType = convertAxisType(rAttributes.getMaxAxisType());
+    m_rExport.AddAttribute(XML_NAMESPACE_CALC_EXT, XML_MAX_AXIS_TYPE, 
sMaxAxisType);
+
+    insertBool(rAttributes.isRightToLeft(), XML_RIGHT_TO_LEFT);
+
+    if (rAttributes.getManualMax() && rAttributes.getMaxAxisType() == 
sc::AxisType::Custom)
+        m_rExport.AddAttribute(XML_NAMESPACE_CALC_EXT, XML_MANUAL_MAX,
+                               OUString::number(*rAttributes.getManualMax()));
+
+    if (rAttributes.getManualMin() && rAttributes.getMinAxisType() == 
sc::AxisType::Custom)
+        m_rExport.AddAttribute(XML_NAMESPACE_CALC_EXT, XML_MANUAL_MIN,
+                               OUString::number(*rAttributes.getManualMin()));
+
+    insertColor(rAttributes.getColorSeries(), XML_COLOR_SERIES);
+    insertColor(rAttributes.getColorNegative(), XML_COLOR_NEGATIVE);
+    insertColor(rAttributes.getColorAxis(), XML_COLOR_AXIS);
+    insertColor(rAttributes.getColorMarkers(), XML_COLOR_MARKERS);
+    insertColor(rAttributes.getColorFirst(), XML_COLOR_FIRST);
+    insertColor(rAttributes.getColorLast(), XML_COLOR_LAST);
+    insertColor(rAttributes.getColorHigh(), XML_COLOR_HIGH);
+    insertColor(rAttributes.getColorLow(), XML_COLOR_LOW);
+}
+
+void SparklineGroupsExport::addSparklineGroup(SparklineGroup* pSparklineGroup)
+{
+    auto const& rAttributes = pSparklineGroup->getAttributes();
+
+    OUString sID = pSparklineGroup->getID();
+    if (!sID.isEmpty())
+    {
+        m_rExport.AddAttribute(XML_NAMESPACE_CALC_EXT, XML_ID, sID);
+    }
+
+    addSparklineGroupAttributes(rAttributes);
+
+    SvXMLElementExport aElementSparklineGroup(m_rExport, 
XML_NAMESPACE_CALC_EXT,
+                                              XML_SPARKLINE_GROUP, true, true);
+
+    SvXMLElementExport aElementSparklines(m_rExport, XML_NAMESPACE_CALC_EXT, 
XML_SPARKLINES, true,
+                                          true);
+    for (auto const& rSparkline : m_aSparklineGroupMap[pSparklineGroup])
+    {
+        addSparklineAttributes(*rSparkline);
+        SvXMLElementExport aElementSparkline(m_rExport, 
XML_NAMESPACE_CALC_EXT, XML_SPARKLINE, true,
+                                             true);
+    }
+}
+
+void SparklineGroupsExport::write()
+{
+    SvXMLElementExport aElement(m_rExport, XML_NAMESPACE_CALC_EXT, 
XML_SPARKLINE_GROUPS, true,
+                                true);
+    for (auto* pSparklineGroup : m_aSparklineGroups)
+    {
+        addSparklineGroup(pSparklineGroup);
+    }
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/SparklineGroupsExport.hxx 
b/sc/source/filter/xml/SparklineGroupsExport.hxx
new file mode 100644
index 000000000000..4e49f585dbc7
--- /dev/null
+++ b/sc/source/filter/xml/SparklineGroupsExport.hxx
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#pragma once
+
+#include <memory>
+#include <unordered_map>
+#include <tools/color.hxx>
+#include <xmloff/xmltoken.hxx>
+
+#include <Sparkline.hxx>
+#include <SparklineGroup.hxx>
+
+class ScXMLExport;
+
+namespace sc
+{
+class SparklineGroupsExport
+{
+    ScXMLExport& m_rExport;
+    std::vector<SparklineGroup*> m_aSparklineGroups;
+    std::unordered_map<SparklineGroup*, 
std::vector<std::shared_ptr<Sparkline>>>
+        m_aSparklineGroupMap;
+    SCTAB m_nTable;
+
+    void addSparklineGroupAttributes(sc::SparklineAttributes const& 
rAttributes);
+    void addSparklineGroup(SparklineGroup* pSparklineGroup);
+    void addSparklineAttributes(Sparkline const& rSparkline);
+
+    void insertColor(Color aColor, xmloff::token::XMLTokenEnum eToken);
+    void insertBool(bool bValue, xmloff::token::XMLTokenEnum eToken);
+
+public:
+    SparklineGroupsExport(ScXMLExport& rExport, SCTAB nTable,
+                          std::vector<std::shared_ptr<Sparkline>> const& 
rSparklines);
+
+    void write();
+};
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/SparklineGroupsImportContext.cxx 
b/sc/source/filter/xml/SparklineGroupsImportContext.cxx
new file mode 100644
index 000000000000..33d831d08608
--- /dev/null
+++ b/sc/source/filter/xml/SparklineGroupsImportContext.cxx
@@ -0,0 +1,332 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "SparklineGroupsImportContext.hxx"
+
+#include <sax/tools/converter.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmluconv.hxx>
+
+#include <document.hxx>
+#include <rangeutl.hxx>
+#include <Sparkline.hxx>
+#include <SparklineGroup.hxx>
+#include <SparklineAttributes.hxx>
+
+using namespace xmloff::token;
+using namespace css;
+
+namespace sc
+{
+SparklineGroupsImportContext::SparklineGroupsImportContext(ScXMLImport& 
rImport)
+    : ScXMLImportContext(rImport)
+{
+}
+
+namespace
+{
+sc::SparklineType parseSparklineType(OUString const& rString)
+{
+    if (rString == "column")
+        return sc::SparklineType::Column;
+    else if (rString == "stacked")
+        return sc::SparklineType::Stacked;
+    return sc::SparklineType::Line;
+}
+
+sc::DisplayEmptyCellsAs parseDisplayEmptyCellsAs(OUString const& rString)
+{
+    if (rString == "span")
+        return sc::DisplayEmptyCellsAs::Span;
+    else if (rString == "gap")
+        return sc::DisplayEmptyCellsAs::Gap;
+    return sc::DisplayEmptyCellsAs::Zero;
+}
+
+sc::AxisType parseAxisType(OUString const& rString)
+{
+    if (rString == "group")
+        return sc::AxisType::Group;
+    else if (rString == "custom")
+        return sc::AxisType::Custom;
+    return sc::AxisType::Individual;
+}
+
+} // end anonymous namespace
+
+void SparklineGroupsImportContext::fillSparklineGroupID(
+    uno::Reference<xml::sax::XFastAttributeList> const& xAttrList)
+{
+    for (auto& rIter : sax_fastparser::castToFastAttributeList(xAttrList))
+    {
+        switch (rIter.getToken())
+        {
+            case XML_ELEMENT(CALC_EXT, XML_ID):
+            {
+                m_pCurrentSparklineGroup->setID(rIter.toString());
+                break;
+            }
+        }
+    }
+}
+
+void SparklineGroupsImportContext::fillSparklineGroupAttributes(
+    uno::Reference<xml::sax::XFastAttributeList> const& xAttrList)
+{
+    sc::SparklineAttributes& rAttributes = 
m_pCurrentSparklineGroup->getAttributes();
+
+    for (auto& rIter : sax_fastparser::castToFastAttributeList(xAttrList))
+    {
+        switch (rIter.getToken())
+        {
+            case XML_ELEMENT(CALC_EXT, XML_TYPE):
+            {
+                rAttributes.setType(parseSparklineType(rIter.toString()));
+                break;
+            }
+            case XML_ELEMENT(CALC_EXT, XML_LINE_WIDTH):
+            {
+                OUString sLineWidth = rIter.toString();
+                double fLineWidth;
+                sal_Int16 const eSrcUnit
+                    = ::sax::Converter::GetUnitFromString(sLineWidth, 
util::MeasureUnit::POINT);
+                ::sax::Converter::convertDouble(fLineWidth, sLineWidth, 
eSrcUnit,
+                                                util::MeasureUnit::POINT);
+                rAttributes.setLineWeight(fLineWidth);
+                break;
+            }
+            case XML_ELEMENT(CALC_EXT, XML_DATE_AXIS):
+            {
+                rAttributes.setDateAxis(rIter.toBoolean());
+                break;
+            }
+            case XML_ELEMENT(CALC_EXT, XML_DISPLAY_EMPTY_CELLS_AS):
+            {
+                auto eDisplayEmptyCellsAs = 
parseDisplayEmptyCellsAs(rIter.toString());
+                rAttributes.setDisplayEmptyCellsAs(eDisplayEmptyCellsAs);
+                break;
+            }
+            case XML_ELEMENT(CALC_EXT, XML_MARKERS):
+            {
+                rAttributes.setMarkers(rIter.toBoolean());
+                break;
+            }
+            case XML_ELEMENT(CALC_EXT, XML_HIGH):
+            {
+                rAttributes.setHigh(rIter.toBoolean());
+                break;
+            }
+            case XML_ELEMENT(CALC_EXT, XML_LOW):
+            {
+                rAttributes.setLow(rIter.toBoolean());
+                break;
+            }
+            case XML_ELEMENT(CALC_EXT, XML_FIRST):
+            {
+                rAttributes.setFirst(rIter.toBoolean());
+                break;
+            }
+            case XML_ELEMENT(CALC_EXT, XML_LAST):
+            {
+                rAttributes.setLast(rIter.toBoolean());
+                break;
+            }
+            case XML_ELEMENT(CALC_EXT, XML_NEGATIVE):
+            {
+                rAttributes.setNegative(rIter.toBoolean());
+                break;
+            }
+            case XML_ELEMENT(CALC_EXT, XML_DISPLAY_X_AXIS):
+            {
+                rAttributes.setDisplayXAxis(rIter.toBoolean());
+                break;
+            }
+            case XML_ELEMENT(CALC_EXT, XML_DISPLAY_HIDDEN):
+            {
+                rAttributes.setDisplayHidden(rIter.toBoolean());
+                break;
+            }
+            case XML_ELEMENT(CALC_EXT, XML_MIN_AXIS_TYPE):
+            {
+                rAttributes.setMinAxisType(parseAxisType(rIter.toString()));
+                break;
+            }
+            case XML_ELEMENT(CALC_EXT, XML_MAX_AXIS_TYPE):
+            {
+                rAttributes.setMaxAxisType(parseAxisType(rIter.toString()));
+                break;
+            }
+            case XML_ELEMENT(CALC_EXT, XML_RIGHT_TO_LEFT):
+            {
+                rAttributes.setRightToLeft(rIter.toBoolean());
+                break;
+            }
+            case XML_ELEMENT(CALC_EXT, XML_MANUAL_MAX):
+            {
+                rAttributes.setManualMax(rIter.toDouble());
+                break;
+            }
+            case XML_ELEMENT(CALC_EXT, XML_MANUAL_MIN):
+            {
+                rAttributes.setManualMin(rIter.toDouble());
+                break;
+            }
+            case XML_ELEMENT(CALC_EXT, XML_COLOR_SERIES):
+            {
+                Color aColor;
+                sax::Converter::convertColor(aColor, rIter.toString());
+                rAttributes.setColorSeries(aColor);
+                break;
+            }
+            case XML_ELEMENT(CALC_EXT, XML_COLOR_NEGATIVE):
+            {
+                Color aColor;
+                sax::Converter::convertColor(aColor, rIter.toString());
+                rAttributes.setColorNegative(aColor);
+                break;
+            }
+            case XML_ELEMENT(CALC_EXT, XML_COLOR_AXIS):
+            {
+                Color aColor;
+                sax::Converter::convertColor(aColor, rIter.toString());
+                rAttributes.setColorAxis(aColor);
+                break;
+            }
+            case XML_ELEMENT(CALC_EXT, XML_COLOR_MARKERS):
+            {
+                Color aColor;
+                sax::Converter::convertColor(aColor, rIter.toString());
+                rAttributes.setColorMarkers(aColor);
+                break;
+            }
+            case XML_ELEMENT(CALC_EXT, XML_COLOR_FIRST):
+            {
+                Color aColor;
+                sax::Converter::convertColor(aColor, rIter.toString());
+                rAttributes.setColorFirst(aColor);
+                break;
+            }
+            case XML_ELEMENT(CALC_EXT, XML_COLOR_LAST):
+            {
+                Color aColor;
+                sax::Converter::convertColor(aColor, rIter.toString());
+                rAttributes.setColorLast(aColor);
+                break;
+            }
+            case XML_ELEMENT(CALC_EXT, XML_COLOR_HIGH):
+            {
+                Color aColor;
+                sax::Converter::convertColor(aColor, rIter.toString());
+                rAttributes.setColorHigh(aColor);
+                break;
+            }
+            case XML_ELEMENT(CALC_EXT, XML_COLOR_LOW):
+            {
+                Color aColor;
+                sax::Converter::convertColor(aColor, rIter.toString());
+                rAttributes.setColorLow(aColor);
+                break;
+            }
+            default:
+                break;
+        }
+    }
+}
+
+void SparklineGroupsImportContext::fillSparklineAttributes(
+    SparklineImportData& rImportData, 
uno::Reference<xml::sax::XFastAttributeList> const& xAttrList)
+{
+    ScDocument* pDocument = GetScImport().GetDocument();
+
+    for (auto& rIter : sax_fastparser::castToFastAttributeList(xAttrList))
+    {
+        switch (rIter.getToken())
+        {
+            case XML_ELEMENT(CALC_EXT, XML_CELL_ADDRESS):
+            {
+                sal_Int32 nOffset = 0;
+                ScRangeStringConverter::GetAddressFromString(
+                    rImportData.m_aAddress, rIter.toString(), *pDocument,
+                    formula::FormulaGrammar::CONV_OOO, nOffset);
+                break;
+            }
+            case XML_ELEMENT(CALC_EXT, XML_DATA_RANGE):
+            {
+                
ScRangeStringConverter::GetRangeListFromString(rImportData.m_aDataRangeList,
+                                                               
rIter.toString(), *pDocument,
+                                                               
formula::FormulaGrammar::CONV_OOO);
+                break;
+            }
+            default:
+                break;
+        }
+    }
+}
+
+uno::Reference<xml::sax::XFastContextHandler>
+    SAL_CALL SparklineGroupsImportContext::createFastChildContext(
+        sal_Int32 nElement, uno::Reference<xml::sax::XFastAttributeList> 
const& xAttrList)
+{
+    SvXMLImportContext* pContext = nullptr;
+    switch (nElement)
+    {
+        case XML_ELEMENT(CALC_EXT, XML_SPARKLINE_GROUP):
+        {
+            m_pCurrentSparklineGroup = std::make_shared<sc::SparklineGroup>();
+            fillSparklineGroupID(xAttrList);
+            fillSparklineGroupAttributes(xAttrList);
+            pContext = this;
+            break;
+        }
+        case XML_ELEMENT(CALC_EXT, XML_SPARKLINES):
+        {
+            pContext = this;
+            break;
+        }
+        case XML_ELEMENT(CALC_EXT, XML_SPARKLINE):
+        {
+            SparklineImportData& rImportData = 
m_aCurrentSparklineDataList.emplace_back();
+            fillSparklineAttributes(rImportData, xAttrList);
+            pContext = this;
+            break;
+        }
+    }
+
+    return pContext;
+}
+
+void SparklineGroupsImportContext::insertSparklines()
+{
+    ScDocument* pDocument = GetScImport().GetDocument();
+    for (auto const& rSparklineImportData : m_aCurrentSparklineDataList)
+    {
+        auto* pSparkline
+            = pDocument->CreateSparkline(rSparklineImportData.m_aAddress, 
m_pCurrentSparklineGroup);
+        pSparkline->setInputRange(rSparklineImportData.m_aDataRangeList);
+    }
+}
+
+void SAL_CALL SparklineGroupsImportContext::endFastElement(sal_Int32 nElement)
+{
+    switch (nElement)
+    {
+        case XML_ELEMENT(CALC_EXT, XML_SPARKLINE_GROUP):
+        {
+            insertSparklines();
+            m_pCurrentSparklineGroup.reset();
+            m_aCurrentSparklineDataList.clear();
+            break;
+        }
+    }
+}
+
+} // end sc
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/SparklineGroupsImportContext.hxx 
b/sc/source/filter/xml/SparklineGroupsImportContext.hxx
new file mode 100644
index 000000000000..f643c1c054f7
--- /dev/null
+++ b/sc/source/filter/xml/SparklineGroupsImportContext.hxx
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <memory>
+#include "importcontext.hxx"
+#include "xmlimprt.hxx"
+#include <address.hxx>
+#include <rangelst.hxx>
+
+namespace sax_fastparser
+{
+class FastAttributeList;
+}
+
+namespace sc
+{
+class SparklineGroup;
+
+struct SparklineImportData
+{
+    ScAddress m_aAddress;
+    ScRangeList m_aDataRangeList;
+};
+
+class SparklineGroupsImportContext : public ScXMLImportContext
+{
+private:
+    std::shared_ptr<sc::SparklineGroup> m_pCurrentSparklineGroup;
+    std::vector<SparklineImportData> m_aCurrentSparklineDataList;
+
+    void
+    
fillSparklineGroupID(css::uno::Reference<css::xml::sax::XFastAttributeList> 
const& xAttrList);
+    void fillSparklineGroupAttributes(
+        css::uno::Reference<css::xml::sax::XFastAttributeList> const& 
xAttrList);
+    void fillSparklineAttributes(
+        SparklineImportData& rImportData,
+        css::uno::Reference<css::xml::sax::XFastAttributeList> const& 
xAttrList);
+
+    void insertSparklines();
+
+public:
+    SparklineGroupsImportContext(ScXMLImport& rImport);
+
+    css::uno::Reference<css::xml::sax::XFastContextHandler> SAL_CALL 
createFastChildContext(
+        sal_Int32 nElement,
+        css::uno::Reference<css::xml::sax::XFastAttributeList> const& 
xAttrList) override;
+
+    void SAL_CALL endFastElement(sal_Int32 nElement) override;
+};
+
+} // end sc
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlexprt.cxx 
b/sc/source/filter/xml/xmlexprt.cxx
index ab1ba651823d..1b273a7b53d5 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -67,6 +67,7 @@
 #include <cellform.hxx>
 #include <datamapper.hxx>
 #include <datatransformation.hxx>
+#include "SparklineGroupsExport.hxx"
 
 #include <xmloff/xmltoken.hxx>
 #include <xmloff/xmlnamespace.hxx>
@@ -2984,6 +2985,7 @@ void ScXMLExport::WriteTable(sal_Int32 nTable, const 
uno::Reference<sheet::XSpre
     {
         //export new conditional format information
         ExportConditionalFormat(nTable);
+        exportSparklineGroups(nTable);
     }
 }
 
@@ -4512,6 +4514,19 @@ void ScXMLExport::WriteNamedRange(ScRangeName* 
pRangeName)
     }
 }
 
+void ScXMLExport::exportSparklineGroups(SCTAB nTable)
+{
+    if (sc::SparklineList* pSparklineList = pDoc->GetSparklineList(nTable))
+    {
+        auto pSparklines = pSparklineList->getSparklines();
+        if (!pSparklines.empty())
+        {
+            sc::SparklineGroupsExport aSparklineGroupExport(*this, nTable, 
pSparklines);
+            aSparklineGroupExport.write();
+        }
+    }
+}
+
 namespace {
 
 OUString getCondFormatEntryType(const ScColorScaleEntry& rEntry, bool bFirst = 
true)
diff --git a/sc/source/filter/xml/xmlexprt.hxx 
b/sc/source/filter/xml/xmlexprt.hxx
index e4a165ab0511..8ab8901d4671 100644
--- a/sc/source/filter/xml/xmlexprt.hxx
+++ b/sc/source/filter/xml/xmlexprt.hxx
@@ -198,6 +198,7 @@ class ScXMLExport : public SvXMLExport
     void WriteExternalDataTransformations(const 
std::vector<std::shared_ptr<sc::DataTransformation>>& aDataTransformations);
     void WriteDataStream();
     void WriteNamedRange(ScRangeName* pRangeName);
+    void exportSparklineGroups(SCTAB nTab);
     void ExportConditionalFormat(SCTAB nTab);
     void WriteExternalRefCaches();
     void WriteConsolidation();  // core implementation
diff --git a/sc/source/filter/xml/xmltabi.cxx b/sc/source/filter/xml/xmltabi.cxx
index dd1baf299d86..835474537401 100644
--- a/sc/source/filter/xml/xmltabi.cxx
+++ b/sc/source/filter/xml/xmltabi.cxx
@@ -34,6 +34,7 @@
 #include <externalrefmgr.hxx>
 #include <sheetdata.hxx>
 #include "xmlcondformat.hxx"
+#include "SparklineGroupsImportContext.hxx"
 
 #include <xmloff/xmltoken.hxx>
 #include <xmloff/xmlnamespace.hxx>
@@ -298,6 +299,9 @@ uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
     case XML_ELEMENT( CALC_EXT, XML_CONDITIONAL_FORMATS ):
         pContext = new ScXMLConditionalFormatsContext( GetScImport() );
         break;
+     case XML_ELEMENT(CALC_EXT, XML_SPARKLINE_GROUPS):
+        pContext = new sc::SparklineGroupsImportContext(GetScImport());
+        break;
     case XML_ELEMENT(OFFICE, XML_EVENT_LISTENERS):
     case XML_ELEMENT(OFFICE_EXT, XML_EVENT_LISTENERS):
         {
@@ -315,6 +319,7 @@ uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
         break;
     default:
         XMLOFF_WARN_UNKNOWN_ELEMENT("sc", nElement);
+        break;
     }
 
     return pContext;
diff --git a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng 
b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
index 9698c0448bdf..2c35d54c1d8a 100644
--- a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
+++ b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
@@ -1535,6 +1535,171 @@ 
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.
             </rng:oneOrMore>
           </rng:element>
         </rng:optional>
+        <!-- Sparklines-->
+        <rng:optional>
+          <rng:element name="calcext:sparkline-groups">
+            <rng:oneOrMore>
+              <rng:element name="calcext:sparkline-group">
+                <rng:attribute name="calcext:id">
+                  <rng:ref name="string"/>
+                </rng:attribute>
+                <rng:optional>
+                  <rng:attribute name="calcext:type">
+                    <rng:choice>
+                      <rng:value>line</rng:value>
+                      <rng:value>column</rng:value>
+                      <rng:value>stacked</rng:value>
+                    </rng:choice>
+                  </rng:attribute>
+                </rng:optional>
+                <rng:optional>
+                  <rng:attribute name="calcext:line-width">
+                    <rng:ref name="length"/>
+                  </rng:attribute>
+                </rng:optional>
+                <rng:optional>
+                  <rng:attribute name="calcext:date-axis">
+                    <rng:ref name="boolean"/>
+                  </rng:attribute>
+                </rng:optional>
+                <rng:optional>
+                  <rng:attribute name="calcext:display-empty-cells-as">
+                    <rng:choice>
+                      <rng:value>zero</rng:value>
+                      <rng:value>gap</rng:value>
+                      <rng:value>span</rng:value>
+                    </rng:choice>
+                  </rng:attribute>
+                </rng:optional>
+                <rng:optional>
+                  <rng:attribute name="calcext:markers">
+                    <rng:ref name="boolean"/>
+                  </rng:attribute>
+                </rng:optional>
+                <rng:optional>
+                  <rng:attribute name="calcext:high">
+                    <rng:ref name="boolean"/>
+                  </rng:attribute>
+                </rng:optional>
+                <rng:optional>
+                  <rng:attribute name="calcext:low">
+                    <rng:ref name="boolean"/>
+                  </rng:attribute>
+                </rng:optional>
+                <rng:optional>
+                  <rng:attribute name="calcext:first">
+                    <rng:ref name="boolean"/>
+                  </rng:attribute>
+                </rng:optional>
+                <rng:optional>
+                  <rng:attribute name="calcext:last">
+                    <rng:ref name="boolean"/>
+                  </rng:attribute>
+                </rng:optional>
+                <rng:optional>
+                  <rng:attribute name="calcext:negative">
+                    <rng:ref name="boolean"/>
+                  </rng:attribute>
+                </rng:optional>
+                <rng:optional>
+                  <rng:attribute name="calcext:display-x-axis">
+                    <rng:ref name="boolean"/>
+                  </rng:attribute>
+                </rng:optional>
+                <rng:optional>
+                  <rng:attribute name="calcext:display-hidden">
+                    <rng:ref name="boolean"/>
+                  </rng:attribute>
+                </rng:optional>
+                <rng:optional>
+                  <rng:attribute name="calcext:min-axis-type">
+                    <rng:choice>
+                      <rng:value>individual</rng:value>
+                      <rng:value>group</rng:value>
+                      <rng:value>custom</rng:value>
+                    </rng:choice>
+                  </rng:attribute>
+                </rng:optional>
+                <rng:optional>
+                  <rng:attribute name="calcext:max-axis-type">
+                    <rng:choice>
+                      <rng:value>individual</rng:value>
+                      <rng:value>group</rng:value>
+                      <rng:value>custom</rng:value>
+                    </rng:choice>
+                  </rng:attribute>
+                </rng:optional>
+                <rng:optional>
+                  <rng:attribute name="calcext:right-to-left">
+                    <rng:ref name="boolean"/>
+                  </rng:attribute>
+                </rng:optional>
+                <rng:optional>
+                  <rng:attribute name="calcext:manual-max">
+                    <rng:ref name="double"/>
+                  </rng:attribute>
+                </rng:optional>
+                <rng:optional>
+                  <rng:attribute name="calcext:manual-min">
+                    <rng:ref name="double"/>
+                  </rng:attribute>
+                </rng:optional>
+                <rng:optional>
+                  <rng:attribute name="calcext:color-series">
+                    <rng:ref name="color"/>
+                  </rng:attribute>
+                </rng:optional>
+                <rng:optional>
+                  <rng:attribute name="calcext:color-negative">
+                    <rng:ref name="color"/>
+                  </rng:attribute>
+                </rng:optional>
+                <rng:optional>
+                  <rng:attribute name="calcext:color-axis">
+                    <rng:ref name="color"/>
+                  </rng:attribute>
+                </rng:optional>
+                <rng:optional>
+                  <rng:attribute name="calcext:color-markers">
+                    <rng:ref name="color"/>
+                  </rng:attribute>
+                </rng:optional>
+                <rng:optional>
+                  <rng:attribute name="calcext:color-first">
+                    <rng:ref name="color"/>
+                  </rng:attribute>
+                </rng:optional>
+                <rng:optional>
+                  <rng:attribute name="calcext:color-last">
+                    <rng:ref name="color"/>
+                  </rng:attribute>
+                </rng:optional>
+                <rng:optional>
+                  <rng:attribute name="calcext:color-high">
+                    <rng:ref name="color"/>
+                  </rng:attribute>
+                </rng:optional>
+                <rng:optional>
+                  <rng:attribute name="calcext:color-low">
+                    <rng:ref name="color"/>
+                  </rng:attribute>
+                </rng:optional>
+                <rng:element name="calcext:sparklines">
+                  <rng:oneOrMore>
+                    <rng:element name="calcext:sparkline">
+                      <rng:attribute name="calcext:cell-address">
+                        <rng:ref name="cellAddress"/>
+                      </rng:attribute>
+                      <rng:attribute name="calcext:data-range">
+                        <rng:ref name="cellRangeAddressList"/>
+                      </rng:attribute>
+                    </rng:element>
+                  </rng:oneOrMore>
+                </rng:element>
+              </rng:element>
+            </rng:oneOrMore>
+          </rng:element>
+        </rng:optional>
       </rng:element>
     </rng:define>
 
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index c7db64b00174..ef1655bfbbfe 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -461,8 +461,16 @@ namespace xmloff::token {
         TOKEN( "codebase",                        XML_CODEBASE ),
         TOKEN( "collapse",                        XML_COLLAPSE ),
         TOKEN( "color",                           XML_COLOR ),
+        TOKEN( "color-axis",                      XML_COLOR_AXIS ),
+        TOKEN( "color-first",                     XML_COLOR_FIRST ),
+        TOKEN( "color-high",                      XML_COLOR_HIGH ),
         TOKEN( "color-inversion",                 XML_COLOR_INVERSION ),
+        TOKEN( "color-last",                      XML_COLOR_LAST ),
+        TOKEN( "color-low",                       XML_COLOR_LOW ),
+        TOKEN( "color-markers",                   XML_COLOR_MARKERS ),
         TOKEN( "color-mode",                      XML_COLOR_MODE ),
+        TOKEN( "color-negative",                  XML_COLOR_NEGATIVE ),
+        TOKEN( "color-series",                    XML_COLOR_SERIES ),
         TOKEN( "color-scale",                     XML_COLOR_SCALE ),
         TOKEN( "color-scale-entry",               XML_COLOR_SCALE_ENTRY ),
         TOKEN( "color-table",                     XML_COLOR_TABLE ),
@@ -605,6 +613,7 @@ namespace xmloff::token {
         TOKEN( "data-pilot-table",                XML_DATA_PILOT_TABLE ),
         TOKEN( "data-pilot-tables",               XML_DATA_PILOT_TABLES ),
         TOKEN( "data-point",                      XML_DATA_POINT ),
+        TOKEN( "data-range",                      XML_DATA_RANGE ),
         TOKEN( "data-stream-source",              XML_DATA_STREAM_SOURCE ),
         TOKEN( "data-style",                      XML_DATA_STYLE ),
         TOKEN( "data-style-name",                 XML_DATA_STYLE_NAME ),
@@ -621,6 +630,7 @@ namespace xmloff::token {
         TOKEN( "database-source-table",           XML_DATABASE_SOURCE_TABLE ),
         TOKEN( "database-table-name",             XML_DATABASE_TABLE_NAME ),
         TOKEN( "date",                            XML_DATE ),
+        TOKEN( "date-axis",                       XML_DATE_AXIS ),
         TOKEN( "date-is",                         XML_DATE_IS ),
         TOKEN( "date-adjust",                     XML_DATE_ADJUST ),
         TOKEN( "date-style",                      XML_DATE_STYLE ),
@@ -680,12 +690,15 @@ namespace xmloff::token {
         TOKEN( "display-details",                 XML_DISPLAY_DETAILS ),
         TOKEN( "display-duplicates",              XML_DISPLAY_DUPLICATES ),
         TOKEN( "display-empty",                   XML_DISPLAY_EMPTY ),
+        TOKEN( "display-empty-cells-as",          XML_DISPLAY_EMPTY_CELLS_AS ),
         TOKEN( "display-filter-buttons",          XML_DISPLAY_FILTER_BUTTONS ),
         TOKEN( "display-formula",                 XML_DISPLAY_FORMULA ),
+        TOKEN( "display-hidden",                  XML_DISPLAY_HIDDEN ),
         TOKEN( "display-label",                   XML_DISPLAY_LABEL ),
         TOKEN( "display-levels",                  XML_DISPLAY_LEVELS ),
         TOKEN( "display-name",                    XML_DISPLAY_NAME ),
         TOKEN( "display-outline-level",           XML_DISPLAY_OUTLINE_LEVEL ),
+        TOKEN( "display-x-axis",                  XML_DISPLAY_X_AXIS ),
         TOKEN( "dissolve",                        XML_DISSOLVE ),
         TOKEN( "distance",                        XML_DISTANCE ),
         TOKEN( "distance-after-sep",              XML_DISTANCE_AFTER_SEP ),
@@ -1193,6 +1206,7 @@ namespace xmloff::token {
         TOKEN( "line-skew",                       XML_LINE_SKEW ),
         TOKEN( "line-spacing",                    XML_LINE_SPACING ),
         TOKEN( "line-style",                      XML_LINE_STYLE ),
+        TOKEN( "line-width",                      XML_LINE_WIDTH ),
         TOKEN( "linear",                          XML_LINEAR ),
         TOKEN( "linearGradient",                  XML_LINEARGRADIENT ),
         TOKEN( "linenumbering-configuration",     
XML_LINENUMBERING_CONFIGURATION ),
@@ -1220,6 +1234,7 @@ namespace xmloff::token {
         TOKEN( "logarithmic",                     XML_LOGARITHMIC ),
         TOKEN( "logbase",                         XML_LOGBASE ),
         TOKEN( "long",                            XML_LONG ),
+        TOKEN( "low",                             XML_LOW ),
         TOKEN( "lowlimit",                        XML_LOWLIMIT ),
         TOKEN( "lr-tb",                           XML_LR_TB ),
         TOKEN( "lt",                              XML_LT ),
@@ -1233,6 +1248,8 @@ namespace xmloff::token {
         TOKEN( "maligngroup",                     XML_MALIGNGROUP ),
         TOKEN( "malignmark",                      XML_MALIGNMARK ),
         TOKEN( "manual",                          XML_MANUAL ),
+        TOKEN( "manual-min",                      XML_MANUAL_MIN ),
+        TOKEN( "manual-max",                      XML_MANUAL_MAX ),
         TOKEN( "map",                             XML_MAP ),
         TOKEN( "margin-bottom",                   XML_MARGIN_BOTTOM ),
         TOKEN( "margin-left",                     XML_MARGIN_LEFT ),
@@ -1240,6 +1257,7 @@ namespace xmloff::token {
         TOKEN( "margin-top",                      XML_MARGIN_TOP ),
         TOKEN( "margins",                         XML_MARGINS ),
         TOKEN( "marker",                          XML_MARKER ),
+        TOKEN( "markers",                         XML_MARKERS ),
         TOKEN( "marker-end",                      XML_MARKER_END ),
         TOKEN( "marker-end-center",               XML_MARKER_END_CENTER ),
         TOKEN( "marker-end-width",                XML_MARKER_END_WIDTH ),
@@ -1258,6 +1276,7 @@ namespace xmloff::token {
         TOKEN( "matrix-covered",                  XML_MATRIX_COVERED ),
         TOKEN( "matrixrow",                       XML_MATRIXROW ),
         TOKEN( "max",                             XML_MAX ),
+        TOKEN( "max-axis-type",                   XML_MAX_AXIS_TYPE ),
         TOKEN( "max-edge",                        XML_MAX_EDGE ),
         TOKEN( "max-height",                      XML_MAX_HEIGHT ),
         TOKEN( "max-length",                      XML_MAX_LENGTH ),
@@ -1283,6 +1302,7 @@ namespace xmloff::token {
         TOKEN( "middle",                          XML_MIDDLE ),
         TOKEN( "mime-type",                       XML_MIME_TYPE ),
         TOKEN( "min",                             XML_MIN ),
+        TOKEN( "min-axis-type",                   XML_MIN_AXIS_TYPE ),
         TOKEN( "min-denominator-digits",          XML_MIN_DENOMINATOR_DIGITS ),
         TOKEN( "min-edge",                        XML_MIN_EDGE ),
         TOKEN( "min-exponent-digits",             XML_MIN_EXPONENT_DIGITS ),
@@ -1357,7 +1377,8 @@ namespace xmloff::token {
         TOKEN( "named-range",                     XML_NAMED_RANGE ),
         TOKEN( "navigation-mode",                 XML_NAVIGATION_MODE ),
         TOKEN( "navy",                            XML_NAVY ),
-        TOKEN( "negative-color",                   XML_NEGATIVE_COLOR ),
+        TOKEN( "negative",                        XML_NEGATIVE ),
+        TOKEN( "negative-color",                  XML_NEGATIVE_COLOR ),
         TOKEN( "neq",                             XML_NEQ ),
         TOKEN( "new",                             XML_NEW ),
         TOKEN( "next",                            XML_NEXT ),
@@ -1618,6 +1639,7 @@ namespace xmloff::token {
         TOKEN( "right",                           XML_RIGHT ),
         TOKEN( "right-outside",                   XML_RIGHT_OUTSIDE ),
         TOKEN( "right-text",                      XML_RIGHT_TEXT ),
+        TOKEN( "right-to-left",                   XML_RIGHT_TO_LEFT ),
         TOKEN( "right-arc",                       XML_RIGHTARC ),
         TOKEN( "right-circle",                    XML_RIGHTCIRCLE ),
         TOKEN( "ring",                            XML_RING ),
@@ -1772,6 +1794,10 @@ namespace xmloff::token {
         TOKEN( "source-range-address",            XML_SOURCE_RANGE_ADDRESS ),
         TOKEN( "source-service",                  XML_SOURCE_SERVICE ),
         TOKEN( "space-before",                    XML_SPACE_BEFORE ),
+        TOKEN( "sparkline-groups",                XML_SPARKLINE_GROUPS ),
+        TOKEN( "sparkline-group",                 XML_SPARKLINE_GROUP ),
+        TOKEN( "sparklines",                      XML_SPARKLINES ),
+        TOKEN( "sparkline",                       XML_SPARKLINE ),
         TOKEN( "span",                            XML_SPAN ),
         TOKEN( "specular",                        XML_SPECULAR ),
         TOKEN( "specular-color",                  XML_SPECULAR_COLOR ),
diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt
index ec591c072789..17e73ed5a952 100644
--- a/xmloff/source/token/tokens.txt
+++ b/xmloff/source/token/tokens.txt
@@ -366,8 +366,16 @@ code
 codebase
 collapse
 color
+color-axis
+color-first
+color-high
 color-inversion
+color-last
+color-low
+color-markers
 color-mode
+color-negative
+color-series
 color-scale
 color-scale-entry
 color-table
@@ -510,6 +518,7 @@ data-pilot-subtotals
 data-pilot-table
 data-pilot-tables
 data-point
+data-range
 data-stream-source
 data-style
 data-style-name
@@ -526,6 +535,7 @@ database-source-sql
 database-source-table
 database-table-name
 date
+date-axis
 date-is
 date-adjust
 date-style
@@ -585,12 +595,15 @@ display-border
 display-details
 display-duplicates
 display-empty
+display-empty-cells-as
 display-filter-buttons
 display-formula
+display-hidden
 display-label
 display-levels
 display-name
 display-outline-level
+display-x-axis
 dissolve
 distance
 distance-after-sep
@@ -1093,6 +1106,7 @@ line-number
 line-skew
 line-spacing
 line-style
+line-width
 linear
 linearGradient
 linenumbering-configuration
@@ -1120,6 +1134,7 @@ log
 logarithmic
 logbase
 long
+low
 lowlimit
 lr-tb
 lt
@@ -1133,6 +1148,8 @@ major-origin
 maligngroup
 malignmark
 manual
+manual-min
+manual-max
 map
 margin-bottom
 margin-left
@@ -1140,6 +1157,7 @@ margin-right
 margin-top
 margins
 marker
+markers
 marker-end
 marker-end-center
 marker-end-width
@@ -1158,6 +1176,7 @@ matrix
 matrix-covered
 matrixrow
 max
+max-axis-type
 max-edge
 max-height
 max-length
@@ -1183,6 +1202,7 @@ mi
 middle
 mime-type
 min
+min-axis-type
 min-denominator-digits
 min-edge
 min-exponent-digits
@@ -1257,6 +1277,7 @@ named-expressions
 named-range
 navigation-mode
 navy
+negative
 negative-color
 neq
 new
@@ -1518,6 +1539,7 @@ ridge
 right
 right-outside
 right-text
+right-to-left
 right-arc
 right-circle
 ring
@@ -1672,6 +1694,10 @@ source-name
 source-range-address
 source-service
 space-before
+sparkline-groups
+sparkline-group
+sparklines
+sparkline
 span
 specular
 specular-color
commit da07b9618432fdaef748f19902c0d9afd421bd15
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Sat Mar 26 01:33:29 2022 +0900
Commit:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
CommitDate: Sat Mar 26 01:36:48 2022 +0900

    sc: add support for xr2 namespace and read uid of sparkline group
    
    Change-Id: I470819a89338f4fb1d9b2486ffb4d93f8eb42844

diff --git a/oox/source/core/xmlfilterbase.cxx 
b/oox/source/core/xmlfilterbase.cxx
index fa9811f4e7fa..852cda990e2d 100644
--- a/oox/source/core/xmlfilterbase.cxx
+++ b/oox/source/core/xmlfilterbase.cxx
@@ -146,6 +146,8 @@ const Sequence< beans::Pair< OUString, sal_Int32 > >& 
NamespaceIds()
              NMSP_x12ac},
             {"http://schemas.microsoft.com/office/drawing/2012/chart";,
              NMSP_c15},
+            
{"http://schemas.microsoft.com/office/spreadsheetml/2015/revision2";,
+             NMSP_xr2},
         };
     return SINGLETON;
 };
diff --git a/oox/source/token/namespaces-strict.txt 
b/oox/source/token/namespaces-strict.txt
index 5024249bfacc..7449dca99a33 100644
--- a/oox/source/token/namespaces-strict.txt
+++ b/oox/source/token/namespaces-strict.txt
@@ -88,6 +88,7 @@ w15                     
http://schemas.microsoft.com/office/word/2012/wordml
 p15                     
http://schemas.microsoft.com/office/powerpoint/2012/main
 x12ac                   
http://schemas.microsoft.com/office/spreadsheetml/2011/1/ac
 c15                     http://schemas.microsoft.com/office/drawing/2012/chart
+xr2                     
http://schemas.microsoft.com/office/spreadsheetml/2015/revision2
 
 # extlst namespaces
 
diff --git a/oox/source/token/namespaces.hxx.tail 
b/oox/source/token/namespaces.hxx.tail
index fdea5b96f1b4..382955683d7d 100644
--- a/oox/source/token/namespaces.hxx.tail
+++ b/oox/source/token/namespaces.hxx.tail
@@ -62,6 +62,7 @@ inline sal_Int32 getNamespace( sal_Int32 nToken ) { return 
nToken & NMSP_MASK; }
 #define W_TOKEN( token )        OOX_TOKEN( doc, token )
 #define LOEXT_TOKEN( token )    OOX_TOKEN( loext, token )
 #define M_TOKEN(token)          OOX_TOKEN(officeMath, token)
+#define XR2_TOKEN(token)        OOX_TOKEN(xr2, token)
 
 
 
diff --git a/oox/source/token/namespaces.txt b/oox/source/token/namespaces.txt
index f18e0833f31d..849caa547695 100644
--- a/oox/source/token/namespaces.txt
+++ b/oox/source/token/namespaces.txt
@@ -88,6 +88,7 @@ w15                     
http://schemas.microsoft.com/office/word/2012/wordml
 p15                     
http://schemas.microsoft.com/office/powerpoint/2012/main
 x12ac                   
http://schemas.microsoft.com/office/spreadsheetml/2011/1/ac
 c15                     http://schemas.microsoft.com/office/drawing/2012/chart
+xr2                     
http://schemas.microsoft.com/office/spreadsheetml/2015/revision2
 
 # extlst namespaces
 
diff --git a/oox/source/token/tokens.txt b/oox/source/token/tokens.txt
index 593ef0b23a5d..d1a40140add9 100644
--- a/oox/source/token/tokens.txt
+++ b/oox/source/token/tokens.txt
@@ -5848,6 +5848,7 @@ xmlDataType
 xmlPr
 xmlns
 xpath
+xr2
 xrange
 xsc
 xscale
diff --git a/sc/inc/SparklineGroup.hxx b/sc/inc/SparklineGroup.hxx
index 8cddafd68e70..b376ea08bccb 100644
--- a/sc/inc/SparklineGroup.hxx
+++ b/sc/inc/SparklineGroup.hxx
@@ -21,11 +21,14 @@ class SC_DLLPUBLIC SparklineGroup
 {
 private:
     SparklineAttributes m_aAttributes;
+    OUString m_sUID;
 
 public:
     SparklineAttributes& getAttributes() { return m_aAttributes; }
 
-    OUString m_sUID;
+    OUString getID() { return m_sUID; }
+
+    void setID(OUString const& rID) { m_sUID = rID; }
 
     SparklineGroup();
 
diff --git a/sc/qa/unit/SparklineImportExportTest.cxx 
b/sc/qa/unit/SparklineImportExportTest.cxx
index 2aaeb333f82e..599c795c3271 100644
--- a/sc/qa/unit/SparklineImportExportTest.cxx
+++ b/sc/qa/unit/SparklineImportExportTest.cxx
@@ -59,6 +59,9 @@ void checkSparklines(ScDocument& rDocument)
     {
         auto pSparkline = rDocument.GetSparkline(ScAddress(0, 1, 0)); // A2
         CPPUNIT_ASSERT(pSparkline);
+        
CPPUNIT_ASSERT_EQUAL(OUString("{1C5C5DE0-3C09-4CB3-A3EC-9E763301EC82}"),
+                             pSparkline->getSparklineGroup()->getID());
+
         auto& rAttributes = pSparkline->getSparklineGroup()->getAttributes();
         CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Line, rAttributes.getType());
 
diff --git a/sc/source/filter/excel/excdoc.cxx 
b/sc/source/filter/excel/excdoc.cxx
index 529e76971cbc..c01dde32981c 100644
--- a/sc/source/filter/excel/excdoc.cxx
+++ b/sc/source/filter/excel/excdoc.cxx
@@ -696,6 +696,7 @@ void ExcTable::WriteXml( XclExpXmlStream& rStrm )
         FSNS(XML_xmlns, XML_r), 
rStrm.getNamespaceURL(OOX_NS(officeRel)).toUtf8(),
         FSNS(XML_xmlns, XML_xdr), 
"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing";, // 
rStrm.getNamespaceURL(OOX_NS(xm)).toUtf8() -> 
"http://schemas.microsoft.com/office/excel/2006/main";,
         FSNS(XML_xmlns, XML_x14), 
rStrm.getNamespaceURL(OOX_NS(xls14Lst)).toUtf8(),
+        FSNS(XML_xmlns, XML_xr2), rStrm.getNamespaceURL(OOX_NS(xr2)).toUtf8(),
         FSNS(XML_xmlns, XML_mc), rStrm.getNamespaceURL(OOX_NS(mce)).toUtf8());
 
     SetCurrScTab( mnScTab );
diff --git a/sc/source/filter/excel/export/SparklineExt.cxx 
b/sc/source/filter/excel/export/SparklineExt.cxx
index 565ac51a1e0b..c36d78d0750b 100644
--- a/sc/source/filter/excel/export/SparklineExt.cxx
+++ b/sc/source/filter/excel/export/SparklineExt.cxx
@@ -187,6 +187,12 @@ void SparklineExt::addSparklineGroup(XclExpXmlStream& 
rStream, sc::SparklineGrou
 
     // Sparkline Group Attributes
     auto pAttrList = sax_fastparser::FastSerializerHelper::createAttrList();
+
+    // Write ID
+    OString sUID = OUStringToOString(rSparklineGroup.getID(), 
RTL_TEXTENCODING_UTF8);
+    pAttrList->addNS(XML_xr2, XML_uid, sUID);
+
+    // Write attributes
     addSparklineGroupAttributes(pAttrList, rSparklineGroup.getAttributes());
 
     rWorksheet->startElementNS(XML_x14, XML_sparklineGroup, pAttrList);
diff --git a/sc/source/filter/oox/SparklineFragment.cxx 
b/sc/source/filter/oox/SparklineFragment.cxx
index eda633bb3df3..f9475ebf014b 100644
--- a/sc/source/filter/oox/SparklineFragment.cxx
+++ b/sc/source/filter/oox/SparklineFragment.cxx
@@ -173,7 +173,8 @@ ContextHandlerRef 
SparklineGroupsContext::onCreateContext(sal_Int32 nElement,
             auto& rLastGroup = m_aSparklineGroups.emplace_back();
             auto& rSparklineAttributes = 
rLastGroup.getSparklineGroup()->getAttributes();
             addAttributesToSparklineAttributes(rSparklineAttributes, rAttribs);
-            rLastGroup.getSparklineGroup()->m_sUID = 
rAttribs.getString(XML_uid, OUString());
+            OUString sUID = rAttribs.getString(XR2_TOKEN(uid), OUString());
+            rLastGroup.getSparklineGroup()->setID(sUID);
             return this;
         }
         case XLS14_TOKEN(colorSeries):
diff --git a/test/source/xmltesttools.cxx b/test/source/xmltesttools.cxx
index f92c380d9bf8..ab9e5dcff8b8 100644
--- a/test/source/xmltesttools.cxx
+++ b/test/source/xmltesttools.cxx
@@ -440,6 +440,8 @@ void 
XmlTestTools::registerOOXMLNamespaces(xmlXPathContextPtr& pXmlXpathCtx)
                        
BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/diagram";));
     xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("c15"),
                        
BAD_CAST("http://schemas.microsoft.com/office/drawing/2012/chart";));
+    xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("xr2"),
+                       
BAD_CAST("http://schemas.microsoft.com/office/spreadsheetml/2015/revision2";));
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Reply via email to