Browse Source

Don't lost conditionalformatting data when edit an existing file

master
Debao Zhang 11 years ago
parent
commit
9d32599f2d
  1. 4
      examples/xlsx/conditionalformatting/main.cpp
  2. 213
      src/xlsx/xlsxconditionalformatting.cpp
  3. 3
      src/xlsx/xlsxconditionalformatting.h
  4. 6
      src/xlsx/xlsxconditionalformatting_p.h
  5. 2
      src/xlsx/xlsxstyles.cpp
  6. 4
      src/xlsx/xlsxworksheet.cpp

4
examples/xlsx/conditionalformatting/main.cpp

@ -67,8 +67,10 @@ int main()
//![cf5]
//![2]
xlsx.save();
xlsx.saveAs("Book1.xlsx");
//![2]
Document xlsx2("Book1.xlsx");
xlsx2.saveAs("Book2.xlsx");
return 0;
}

213
src/xlsx/xlsxconditionalformatting.cpp

@ -27,6 +27,7 @@
#include "xlsxconditionalformatting_p.h"
#include "xlsxworksheet.h"
#include "xlsxcellrange.h"
#include "xlsxstyles_p.h"
#include <QXmlStreamReader>
#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"));
QString type;
@ -443,11 +444,207 @@ void ConditionalFormatting::addRange(const CellRange &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"));
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
@ -490,16 +687,16 @@ bool ConditionalFormatting::saveToXml(QXmlStreamWriter &writer) const
writer.writeStartElement(QStringLiteral("dataBar"));
if (rule->attrs.contains(XlsxCfRuleData::A_hideData))
writer.writeAttribute(QStringLiteral("showValue"), QStringLiteral("0"));
d->writeCfVo(rule->attrs[XlsxCfRuleData::A_cfvo1].value<XlsxCfVoData>(), writer);
d->writeCfVo(rule->attrs[XlsxCfRuleData::A_cfvo2].value<XlsxCfVoData>(), writer);
d->writeCfVo(writer, rule->attrs[XlsxCfRuleData::A_cfvo1].value<XlsxCfVoData>());
d->writeCfVo(writer, rule->attrs[XlsxCfRuleData::A_cfvo2].value<XlsxCfVoData>());
rule->attrs[XlsxCfRuleData::A_color1].value<XlsxColor>().saveToXml(writer);
writer.writeEndElement();//dataBar
} else if (rule->attrs[XlsxCfRuleData::A_type] == QLatin1String("colorScale")) {
writer.writeStartElement(QStringLiteral("colorScale"));
d->writeCfVo(rule->attrs[XlsxCfRuleData::A_cfvo1].value<XlsxCfVoData>(), writer);
d->writeCfVo(rule->attrs[XlsxCfRuleData::A_cfvo2].value<XlsxCfVoData>(), writer);
d->writeCfVo(writer, rule->attrs[XlsxCfRuleData::A_cfvo1].value<XlsxCfVoData>());
d->writeCfVo(writer, rule->attrs[XlsxCfRuleData::A_cfvo2].value<XlsxCfVoData>());
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_color2].value<XlsxColor>().saveToXml(writer);

3
src/xlsx/xlsxconditionalformatting.h

@ -40,6 +40,7 @@ QT_BEGIN_NAMESPACE_XLSX
class CellRange;
class Format;
class Worksheet;
class Styles;
class ConditionalFormattingPrivate;
class Q_XLSX_EXPORT ConditionalFormatting
@ -125,7 +126,7 @@ private:
friend class Worksheet;
friend class ::ConditionalFormattingTest;
bool saveToXml(QXmlStreamWriter &writer) const;
bool loadFromXml(QXmlStreamReader &reader) const;
bool loadFromXml(QXmlStreamReader &reader, Styles *styles=0);
QSharedDataPointer<ConditionalFormattingPrivate> d;
};

6
src/xlsx/xlsxconditionalformatting_p.h

@ -115,7 +115,11 @@ public:
ConditionalFormattingPrivate(const ConditionalFormattingPrivate &other);
~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<CellRange> ranges;

2
src/xlsx/xlsxstyles.cpp

@ -1266,6 +1266,8 @@ bool Styles::loadFromXmlFile(QIODevice *device)
readCellXfs(reader);
} else if (reader.name() == QLatin1String("cellStyles")) {
} else if (reader.name() == QLatin1String("dxfs")) {
readDxfs(reader);
}
}

4
src/xlsx/xlsxworksheet.cpp

@ -2255,6 +2255,10 @@ bool Worksheet::loadFromXmlFile(QIODevice *device)
d->readMergeCells(reader);
} else if (reader.name() == QLatin1String("dataValidations")) {
d->readDataValidations(reader);
} else if (reader.name() == QLatin1String("conditionalFormatting")) {
ConditionalFormatting cf;
cf.loadFromXml(reader, workbook()->styles());
d->conditionalFormattingList.append(cf);
}
}
}

Loading…
Cancel
Save