Don't lost conditionalformatting data when edit an existing file
This commit is contained in:
@@ -67,8 +67,10 @@ int main()
|
|||||||
//![cf5]
|
//![cf5]
|
||||||
|
|
||||||
//![2]
|
//![2]
|
||||||
xlsx.save();
|
xlsx.saveAs("Book1.xlsx");
|
||||||
//![2]
|
//![2]
|
||||||
|
|
||||||
|
Document xlsx2("Book1.xlsx");
|
||||||
|
xlsx2.saveAs("Book2.xlsx");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include "xlsxconditionalformatting_p.h"
|
#include "xlsxconditionalformatting_p.h"
|
||||||
#include "xlsxworksheet.h"
|
#include "xlsxworksheet.h"
|
||||||
#include "xlsxcellrange.h"
|
#include "xlsxcellrange.h"
|
||||||
|
#include "xlsxstyles_p.h"
|
||||||
|
|
||||||
#include <QXmlStreamReader>
|
#include <QXmlStreamReader>
|
||||||
#include <QXmlStreamWriter>
|
#include <QXmlStreamWriter>
|
||||||
@@ -50,7 +51,7 @@ ConditionalFormattingPrivate::~ConditionalFormattingPrivate()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConditionalFormattingPrivate::writeCfVo(const XlsxCfVoData &cfvo, QXmlStreamWriter &writer) const
|
void ConditionalFormattingPrivate::writeCfVo(QXmlStreamWriter &writer, const XlsxCfVoData &cfvo) const
|
||||||
{
|
{
|
||||||
writer.writeEmptyElement(QStringLiteral("cfvo"));
|
writer.writeEmptyElement(QStringLiteral("cfvo"));
|
||||||
QString type;
|
QString type;
|
||||||
@@ -443,11 +444,207 @@ void ConditionalFormatting::addRange(const CellRange &range)
|
|||||||
d->ranges.append(range);
|
d->ranges.append(range);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConditionalFormatting::loadFromXml(QXmlStreamReader &reader) const
|
bool ConditionalFormattingPrivate::readCfRule(QXmlStreamReader &reader, XlsxCfRuleData *rule, Styles *styles)
|
||||||
|
{
|
||||||
|
Q_ASSERT(reader.name() == QLatin1String("cfRule"));
|
||||||
|
QXmlStreamAttributes attrs = reader.attributes();
|
||||||
|
if (attrs.hasAttribute(QLatin1String("type")))
|
||||||
|
rule->attrs[XlsxCfRuleData::A_type] = attrs.value(QLatin1String("type")).toString();
|
||||||
|
if (attrs.hasAttribute(QLatin1String("dxfId"))) {
|
||||||
|
int id = attrs.value(QLatin1String("dxfId")).toString().toInt();
|
||||||
|
if (styles)
|
||||||
|
rule->dxfFormat = styles->dxfFormat(id);
|
||||||
|
else
|
||||||
|
rule->dxfFormat.setDxfIndex(id);
|
||||||
|
}
|
||||||
|
rule->priority = attrs.value(QLatin1String("priority")).toString().toInt();
|
||||||
|
if (attrs.value(QLatin1String("stopIfTrue")) == QLatin1String("1")) {
|
||||||
|
//default is false
|
||||||
|
rule->attrs[XlsxCfRuleData::A_stopIfTrue] = QLatin1String("1");
|
||||||
|
}
|
||||||
|
if (attrs.value(QLatin1String("aboveAverage")) == QLatin1String("0")) {
|
||||||
|
//default is true
|
||||||
|
rule->attrs[XlsxCfRuleData::A_aboveAverage] = QLatin1String("0");
|
||||||
|
}
|
||||||
|
if (attrs.value(QLatin1String("percent")) == QLatin1String("1")) {
|
||||||
|
//default is false
|
||||||
|
rule->attrs[XlsxCfRuleData::A_percent] = QLatin1String("1");
|
||||||
|
}
|
||||||
|
if (attrs.value(QLatin1String("bottom")) == QLatin1String("1")) {
|
||||||
|
//default is false
|
||||||
|
rule->attrs[XlsxCfRuleData::A_bottom] = QLatin1String("1");
|
||||||
|
}
|
||||||
|
if (attrs.hasAttribute(QLatin1String("operator")))
|
||||||
|
rule->attrs[XlsxCfRuleData::A_operator] = attrs.value(QLatin1String("operator")).toString();
|
||||||
|
|
||||||
|
if (attrs.hasAttribute(QLatin1String("text")))
|
||||||
|
rule->attrs[XlsxCfRuleData::A_text] = attrs.value(QLatin1String("text")).toString();
|
||||||
|
|
||||||
|
if (attrs.hasAttribute(QLatin1String("timePeriod")))
|
||||||
|
rule->attrs[XlsxCfRuleData::A_timePeriod] = attrs.value(QLatin1String("timePeriod")).toString();
|
||||||
|
|
||||||
|
if (attrs.hasAttribute(QLatin1String("rank")))
|
||||||
|
rule->attrs[XlsxCfRuleData::A_rank] = attrs.value(QLatin1String("rank")).toString();
|
||||||
|
|
||||||
|
if (attrs.hasAttribute(QLatin1String("stdDev")))
|
||||||
|
rule->attrs[XlsxCfRuleData::A_stdDev] = attrs.value(QLatin1String("stdDev")).toString();
|
||||||
|
|
||||||
|
if (attrs.value(QLatin1String("equalAverage")) == QLatin1String("1")) {
|
||||||
|
//default is false
|
||||||
|
rule->attrs[XlsxCfRuleData::A_equalAverage] = QLatin1String("1");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!reader.atEnd()) {
|
||||||
|
reader.readNextStartElement();
|
||||||
|
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||||
|
if (reader.name() == QLatin1String("formula")) {
|
||||||
|
QString f = reader.readElementText();
|
||||||
|
if (!rule->attrs.contains(XlsxCfRuleData::A_formula1))
|
||||||
|
rule->attrs[XlsxCfRuleData::A_formula1] = f;
|
||||||
|
else if (!rule->attrs.contains(XlsxCfRuleData::A_formula2))
|
||||||
|
rule->attrs[XlsxCfRuleData::A_formula2] = f;
|
||||||
|
else if (!rule->attrs.contains(XlsxCfRuleData::A_formula3))
|
||||||
|
rule->attrs[XlsxCfRuleData::A_formula3] = f;
|
||||||
|
} else if (reader.name() == QLatin1String("dataBar")) {
|
||||||
|
readCfDataBar(reader, rule, styles);
|
||||||
|
} else if (reader.name() == QLatin1String("colorScale")) {
|
||||||
|
readCfColorScale(reader, rule, styles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (reader.tokenType() == QXmlStreamReader::EndElement
|
||||||
|
&& reader.name() == QStringLiteral("conditionalFormatting")) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConditionalFormattingPrivate::readCfDataBar(QXmlStreamReader &reader, XlsxCfRuleData *rule, Styles *styles)
|
||||||
|
{
|
||||||
|
Q_ASSERT(reader.name() == QLatin1String("dataBar"));
|
||||||
|
QXmlStreamAttributes attrs = reader.attributes();
|
||||||
|
if (attrs.value(QLatin1String("showValue")) == QLatin1String("0"))
|
||||||
|
rule->attrs[XlsxCfRuleData::A_hideData] = QStringLiteral("1");
|
||||||
|
|
||||||
|
while (!reader.atEnd()) {
|
||||||
|
reader.readNextStartElement();
|
||||||
|
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||||
|
if (reader.name() == QLatin1String("cfvo")) {
|
||||||
|
XlsxCfVoData data;
|
||||||
|
readCfVo(reader, data);
|
||||||
|
if (!rule->attrs.contains(XlsxCfRuleData::A_cfvo1))
|
||||||
|
rule->attrs[XlsxCfRuleData::A_cfvo1] = QVariant::fromValue(data);
|
||||||
|
else
|
||||||
|
rule->attrs[XlsxCfRuleData::A_cfvo2] = QVariant::fromValue(data);
|
||||||
|
} else if (reader.name() == QLatin1String("color")) {
|
||||||
|
XlsxColor color;
|
||||||
|
color.loadFromXml(reader, styles);
|
||||||
|
rule->attrs[XlsxCfRuleData::A_color1] = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (reader.tokenType() == QXmlStreamReader::EndElement
|
||||||
|
&& reader.name() == QStringLiteral("dataBar")) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConditionalFormattingPrivate::readCfColorScale(QXmlStreamReader &reader, XlsxCfRuleData *rule, Styles *styles)
|
||||||
|
{
|
||||||
|
Q_ASSERT(reader.name() == QLatin1String("colorScale"));
|
||||||
|
|
||||||
|
while (!reader.atEnd()) {
|
||||||
|
reader.readNextStartElement();
|
||||||
|
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||||
|
if (reader.name() == QLatin1String("cfvo")) {
|
||||||
|
XlsxCfVoData data;
|
||||||
|
readCfVo(reader, data);
|
||||||
|
if (!rule->attrs.contains(XlsxCfRuleData::A_cfvo1))
|
||||||
|
rule->attrs[XlsxCfRuleData::A_cfvo1] = QVariant::fromValue(data);
|
||||||
|
else if (!rule->attrs.contains(XlsxCfRuleData::A_cfvo2))
|
||||||
|
rule->attrs[XlsxCfRuleData::A_cfvo2] = QVariant::fromValue(data);
|
||||||
|
else
|
||||||
|
rule->attrs[XlsxCfRuleData::A_cfvo2] = QVariant::fromValue(data);
|
||||||
|
} else if (reader.name() == QLatin1String("color")) {
|
||||||
|
XlsxColor color;
|
||||||
|
color.loadFromXml(reader, styles);
|
||||||
|
if (!rule->attrs.contains(XlsxCfRuleData::A_color1))
|
||||||
|
rule->attrs[XlsxCfRuleData::A_color1] = color;
|
||||||
|
else if (!rule->attrs.contains(XlsxCfRuleData::A_color2))
|
||||||
|
rule->attrs[XlsxCfRuleData::A_color2] = color;
|
||||||
|
else
|
||||||
|
rule->attrs[XlsxCfRuleData::A_color3] = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (reader.tokenType() == QXmlStreamReader::EndElement
|
||||||
|
&& reader.name() == QStringLiteral("colorScale")) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConditionalFormattingPrivate::readCfVo(QXmlStreamReader &reader, XlsxCfVoData &cfvo)
|
||||||
|
{
|
||||||
|
Q_ASSERT(reader.name() == QStringLiteral("cfvo"));
|
||||||
|
|
||||||
|
QXmlStreamAttributes attrs = reader.attributes();
|
||||||
|
|
||||||
|
QString type = attrs.value(QLatin1String("type")).toString();
|
||||||
|
ConditionalFormatting::ValueObjectType t;
|
||||||
|
if (type == QLatin1String("formula"))
|
||||||
|
t = ConditionalFormatting::VOT_Formula;
|
||||||
|
else if (type == QLatin1String("max"))
|
||||||
|
t = ConditionalFormatting::VOT_Max;
|
||||||
|
else if (type == QLatin1String("min"))
|
||||||
|
t = ConditionalFormatting::VOT_Min;
|
||||||
|
else if (type == QLatin1String("num"))
|
||||||
|
t = ConditionalFormatting::VOT_Num;
|
||||||
|
else if (type == QLatin1String("percent"))
|
||||||
|
t = ConditionalFormatting::VOT_Percent;
|
||||||
|
else if (type == QLatin1String("percentile"))
|
||||||
|
t = ConditionalFormatting::VOT_Percentile;
|
||||||
|
|
||||||
|
cfvo.type = t;
|
||||||
|
cfvo.value = attrs.value(QLatin1String("val")).toString();
|
||||||
|
if (attrs.value(QLatin1String("gte")) == QLatin1String("0")) {
|
||||||
|
//default is true
|
||||||
|
cfvo.gte = false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConditionalFormatting::loadFromXml(QXmlStreamReader &reader, Styles *styles)
|
||||||
{
|
{
|
||||||
Q_ASSERT(reader.name() == QStringLiteral("conditionalFormatting"));
|
Q_ASSERT(reader.name() == QStringLiteral("conditionalFormatting"));
|
||||||
|
|
||||||
return false;
|
d->ranges.clear();
|
||||||
|
d->cfRules.clear();
|
||||||
|
QXmlStreamAttributes attrs = reader.attributes();
|
||||||
|
QString sqref = attrs.value(QLatin1String("sqref")).toString();
|
||||||
|
foreach (QString range, sqref.split(QLatin1Char(' ')))
|
||||||
|
this->addRange(range);
|
||||||
|
|
||||||
|
while (!reader.atEnd()) {
|
||||||
|
reader.readNextStartElement();
|
||||||
|
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||||
|
if (reader.name() == QLatin1String("cfRule")) {
|
||||||
|
QSharedPointer<XlsxCfRuleData> cfRule(new XlsxCfRuleData);
|
||||||
|
d->readCfRule(reader, cfRule.data(), styles);
|
||||||
|
d->cfRules.append(cfRule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (reader.tokenType() == QXmlStreamReader::EndElement
|
||||||
|
&& reader.name() == QStringLiteral("conditionalFormatting")) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConditionalFormatting::saveToXml(QXmlStreamWriter &writer) const
|
bool ConditionalFormatting::saveToXml(QXmlStreamWriter &writer) const
|
||||||
@@ -490,16 +687,16 @@ bool ConditionalFormatting::saveToXml(QXmlStreamWriter &writer) const
|
|||||||
writer.writeStartElement(QStringLiteral("dataBar"));
|
writer.writeStartElement(QStringLiteral("dataBar"));
|
||||||
if (rule->attrs.contains(XlsxCfRuleData::A_hideData))
|
if (rule->attrs.contains(XlsxCfRuleData::A_hideData))
|
||||||
writer.writeAttribute(QStringLiteral("showValue"), QStringLiteral("0"));
|
writer.writeAttribute(QStringLiteral("showValue"), QStringLiteral("0"));
|
||||||
d->writeCfVo(rule->attrs[XlsxCfRuleData::A_cfvo1].value<XlsxCfVoData>(), writer);
|
d->writeCfVo(writer, rule->attrs[XlsxCfRuleData::A_cfvo1].value<XlsxCfVoData>());
|
||||||
d->writeCfVo(rule->attrs[XlsxCfRuleData::A_cfvo2].value<XlsxCfVoData>(), writer);
|
d->writeCfVo(writer, rule->attrs[XlsxCfRuleData::A_cfvo2].value<XlsxCfVoData>());
|
||||||
rule->attrs[XlsxCfRuleData::A_color1].value<XlsxColor>().saveToXml(writer);
|
rule->attrs[XlsxCfRuleData::A_color1].value<XlsxColor>().saveToXml(writer);
|
||||||
writer.writeEndElement();//dataBar
|
writer.writeEndElement();//dataBar
|
||||||
} else if (rule->attrs[XlsxCfRuleData::A_type] == QLatin1String("colorScale")) {
|
} else if (rule->attrs[XlsxCfRuleData::A_type] == QLatin1String("colorScale")) {
|
||||||
writer.writeStartElement(QStringLiteral("colorScale"));
|
writer.writeStartElement(QStringLiteral("colorScale"));
|
||||||
d->writeCfVo(rule->attrs[XlsxCfRuleData::A_cfvo1].value<XlsxCfVoData>(), writer);
|
d->writeCfVo(writer, rule->attrs[XlsxCfRuleData::A_cfvo1].value<XlsxCfVoData>());
|
||||||
d->writeCfVo(rule->attrs[XlsxCfRuleData::A_cfvo2].value<XlsxCfVoData>(), writer);
|
d->writeCfVo(writer, rule->attrs[XlsxCfRuleData::A_cfvo2].value<XlsxCfVoData>());
|
||||||
if (rule->attrs.contains(XlsxCfRuleData::A_cfvo3))
|
if (rule->attrs.contains(XlsxCfRuleData::A_cfvo3))
|
||||||
d->writeCfVo(rule->attrs[XlsxCfRuleData::A_cfvo3].value<XlsxCfVoData>(), writer);
|
d->writeCfVo(writer, rule->attrs[XlsxCfRuleData::A_cfvo3].value<XlsxCfVoData>());
|
||||||
|
|
||||||
rule->attrs[XlsxCfRuleData::A_color1].value<XlsxColor>().saveToXml(writer);
|
rule->attrs[XlsxCfRuleData::A_color1].value<XlsxColor>().saveToXml(writer);
|
||||||
rule->attrs[XlsxCfRuleData::A_color2].value<XlsxColor>().saveToXml(writer);
|
rule->attrs[XlsxCfRuleData::A_color2].value<XlsxColor>().saveToXml(writer);
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ QT_BEGIN_NAMESPACE_XLSX
|
|||||||
class CellRange;
|
class CellRange;
|
||||||
class Format;
|
class Format;
|
||||||
class Worksheet;
|
class Worksheet;
|
||||||
|
class Styles;
|
||||||
|
|
||||||
class ConditionalFormattingPrivate;
|
class ConditionalFormattingPrivate;
|
||||||
class Q_XLSX_EXPORT ConditionalFormatting
|
class Q_XLSX_EXPORT ConditionalFormatting
|
||||||
@@ -125,7 +126,7 @@ private:
|
|||||||
friend class Worksheet;
|
friend class Worksheet;
|
||||||
friend class ::ConditionalFormattingTest;
|
friend class ::ConditionalFormattingTest;
|
||||||
bool saveToXml(QXmlStreamWriter &writer) const;
|
bool saveToXml(QXmlStreamWriter &writer) const;
|
||||||
bool loadFromXml(QXmlStreamReader &reader) const;
|
bool loadFromXml(QXmlStreamReader &reader, Styles *styles=0);
|
||||||
QSharedDataPointer<ConditionalFormattingPrivate> d;
|
QSharedDataPointer<ConditionalFormattingPrivate> d;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -115,7 +115,11 @@ public:
|
|||||||
ConditionalFormattingPrivate(const ConditionalFormattingPrivate &other);
|
ConditionalFormattingPrivate(const ConditionalFormattingPrivate &other);
|
||||||
~ConditionalFormattingPrivate();
|
~ConditionalFormattingPrivate();
|
||||||
|
|
||||||
void writeCfVo(const XlsxCfVoData& cfvo, QXmlStreamWriter &writer) const;
|
void writeCfVo(QXmlStreamWriter &writer, const XlsxCfVoData& cfvo) const;
|
||||||
|
bool readCfVo(QXmlStreamReader &reader, XlsxCfVoData& cfvo);
|
||||||
|
bool readCfRule(QXmlStreamReader &reader, XlsxCfRuleData *cfRule, Styles *styles);
|
||||||
|
bool readCfDataBar(QXmlStreamReader &reader, XlsxCfRuleData *cfRule, Styles *styles);
|
||||||
|
bool readCfColorScale(QXmlStreamReader &reader, XlsxCfRuleData *cfRule, Styles *styles);
|
||||||
|
|
||||||
QList<QSharedPointer<XlsxCfRuleData> >cfRules;
|
QList<QSharedPointer<XlsxCfRuleData> >cfRules;
|
||||||
QList<CellRange> ranges;
|
QList<CellRange> ranges;
|
||||||
|
|||||||
@@ -1266,6 +1266,8 @@ bool Styles::loadFromXmlFile(QIODevice *device)
|
|||||||
readCellXfs(reader);
|
readCellXfs(reader);
|
||||||
} else if (reader.name() == QLatin1String("cellStyles")) {
|
} else if (reader.name() == QLatin1String("cellStyles")) {
|
||||||
|
|
||||||
|
} else if (reader.name() == QLatin1String("dxfs")) {
|
||||||
|
readDxfs(reader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2255,6 +2255,10 @@ bool Worksheet::loadFromXmlFile(QIODevice *device)
|
|||||||
d->readMergeCells(reader);
|
d->readMergeCells(reader);
|
||||||
} else if (reader.name() == QLatin1String("dataValidations")) {
|
} else if (reader.name() == QLatin1String("dataValidations")) {
|
||||||
d->readDataValidations(reader);
|
d->readDataValidations(reader);
|
||||||
|
} else if (reader.name() == QLatin1String("conditionalFormatting")) {
|
||||||
|
ConditionalFormatting cf;
|
||||||
|
cf.loadFromXml(reader, workbook()->styles());
|
||||||
|
d->conditionalFormattingList.append(cf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user