Add basic conditional formatting writer support.
This commit is contained in:
@@ -0,0 +1,9 @@
|
|||||||
|
TARGET = hello
|
||||||
|
|
||||||
|
#include(../../../src/xlsx/qtxlsx.pri)
|
||||||
|
QT+=xlsx
|
||||||
|
|
||||||
|
CONFIG += console
|
||||||
|
CONFIG -= app_bundle
|
||||||
|
|
||||||
|
SOURCES += main.cpp
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
/*!
|
||||||
|
\example conditionalformatting
|
||||||
|
\title Conditional Formatting Example
|
||||||
|
\brief This is a conditional formatting example.
|
||||||
|
\ingroup qtxlsx-examples
|
||||||
|
|
||||||
|
This example demonstrates how to create a new
|
||||||
|
.xlsx file containin conditional formatting
|
||||||
|
with Qt Xlsx Library. So lets see how this is achieved.
|
||||||
|
*/
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
#include <QtCore>
|
||||||
|
#include "xlsxdocument.h"
|
||||||
|
#include "xlsxconditionalformatting.h"
|
||||||
|
|
||||||
|
using namespace QXlsx;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
//![0]
|
||||||
|
Document xlsx;
|
||||||
|
Format hFmt;
|
||||||
|
hFmt.setFontBold(true);
|
||||||
|
xlsx.write("B1", "(-inf,40)", hFmt);
|
||||||
|
xlsx.write("D1", "[30,70]", hFmt);
|
||||||
|
|
||||||
|
for (int row=3; row<22; ++row) {
|
||||||
|
for (int col=2; col<22; ++col)
|
||||||
|
xlsx.write(row, col, qrand() % 100);
|
||||||
|
}
|
||||||
|
//![0]
|
||||||
|
|
||||||
|
//![1]
|
||||||
|
ConditionalFormatting cf1;
|
||||||
|
Format fmt1;
|
||||||
|
fmt1.setFontColor(Qt::green);
|
||||||
|
fmt1.setBorderStyle(Format::BorderDashed);
|
||||||
|
cf1.addHighlightCellsRule(ConditionalFormatting::Highlight_LessThan, "40", fmt1);
|
||||||
|
cf1.addRange("B3:B21");
|
||||||
|
xlsx.addConditionalFormatting(cf1);
|
||||||
|
//![1]
|
||||||
|
|
||||||
|
//![cf2]
|
||||||
|
ConditionalFormatting cf2;
|
||||||
|
Format fmt2;
|
||||||
|
fmt2.setBorderStyle(Format::BorderDotted);
|
||||||
|
fmt2.setBorderColor(Qt::blue);
|
||||||
|
cf2.addHighlightCellsRule(ConditionalFormatting::Highlight_Between, "30", "70", fmt2);
|
||||||
|
cf2.addRange("D3:D21");
|
||||||
|
xlsx.addConditionalFormatting(cf2);
|
||||||
|
//![cf2]
|
||||||
|
|
||||||
|
//![cf3]
|
||||||
|
ConditionalFormatting cf3;
|
||||||
|
Format fmt3;
|
||||||
|
fmt3.setFontStrikeOut(true);
|
||||||
|
cf3.addHighlightCellsRule(ConditionalFormatting::Highlight_BeginsWith, "2", fmt3);
|
||||||
|
cf3.addRange("F3:F21");
|
||||||
|
xlsx.addConditionalFormatting(cf3);
|
||||||
|
//![cf3]
|
||||||
|
|
||||||
|
//![2]
|
||||||
|
xlsx.save();
|
||||||
|
//![2]
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -11,5 +11,6 @@ SUBDIRS = hello \
|
|||||||
definename \
|
definename \
|
||||||
formulas \
|
formulas \
|
||||||
richtext \
|
richtext \
|
||||||
|
conditionalformatting \
|
||||||
demo
|
demo
|
||||||
|
|
||||||
|
|||||||
+5
-2
@@ -31,7 +31,9 @@ HEADERS += $$PWD/xlsxdocpropscore_p.h \
|
|||||||
$$PWD/xlsxdatavalidation_p.h \
|
$$PWD/xlsxdatavalidation_p.h \
|
||||||
$$PWD/xlsxcellrange.h \
|
$$PWD/xlsxcellrange.h \
|
||||||
$$PWD/xlsxrichstring_p.h \
|
$$PWD/xlsxrichstring_p.h \
|
||||||
$$PWD/xlsxrichstring.h
|
$$PWD/xlsxrichstring.h \
|
||||||
|
$$PWD/xlsxconditionalformatting.h \
|
||||||
|
$$PWD/xlsxconditionalformatting_p.h
|
||||||
|
|
||||||
SOURCES += $$PWD/xlsxdocpropscore.cpp \
|
SOURCES += $$PWD/xlsxdocpropscore.cpp \
|
||||||
$$PWD/xlsxdocpropsapp.cpp \
|
$$PWD/xlsxdocpropsapp.cpp \
|
||||||
@@ -52,4 +54,5 @@ SOURCES += $$PWD/xlsxdocpropscore.cpp \
|
|||||||
$$PWD/xlsxcell.cpp \
|
$$PWD/xlsxcell.cpp \
|
||||||
$$PWD/xlsxdatavalidation.cpp \
|
$$PWD/xlsxdatavalidation.cpp \
|
||||||
$$PWD/xlsxcellrange.cpp \
|
$$PWD/xlsxcellrange.cpp \
|
||||||
$$PWD/xlsxrichstring.cpp
|
$$PWD/xlsxrichstring.cpp \
|
||||||
|
$$PWD/xlsxconditionalformatting.cpp
|
||||||
|
|||||||
@@ -0,0 +1,392 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
|
||||||
|
** All right reserved.
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
** a copy of this software and associated documentation files (the
|
||||||
|
** "Software"), to deal in the Software without restriction, including
|
||||||
|
** without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
** permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
** the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be
|
||||||
|
** included in all copies or substantial portions of the Software.
|
||||||
|
**
|
||||||
|
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "xlsxconditionalformatting.h"
|
||||||
|
#include "xlsxconditionalformatting_p.h"
|
||||||
|
#include "xlsxworksheet.h"
|
||||||
|
#include "xlsxcellrange.h"
|
||||||
|
|
||||||
|
#include <QXmlStreamReader>
|
||||||
|
#include <QXmlStreamWriter>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE_XLSX
|
||||||
|
|
||||||
|
ConditionalFormattingPrivate::ConditionalFormattingPrivate()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ConditionalFormattingPrivate::ConditionalFormattingPrivate(const ConditionalFormattingPrivate &other)
|
||||||
|
:QSharedData(other)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ConditionalFormattingPrivate::~ConditionalFormattingPrivate()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \class ConditionalFormatting
|
||||||
|
* \brief Conditional formatting for single cell or ranges
|
||||||
|
* \inmodule QtXlsx
|
||||||
|
*
|
||||||
|
* The conditional formatting can be applied to a single cell or ranges of cells.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\enum ConditionalFormatting::HighlightRuleType
|
||||||
|
|
||||||
|
\value Highlight_LessThan
|
||||||
|
\value Highlight_LessThanOrEqual
|
||||||
|
\value Highlight_Equal
|
||||||
|
\value Highlight_NotEqual
|
||||||
|
\value Highlight_GreaterThanOrEqual
|
||||||
|
\value Highlight_GreaterThan
|
||||||
|
\value Highlight_Between
|
||||||
|
\value Highlight_NotBetween
|
||||||
|
|
||||||
|
\value Highlight_ContainsText
|
||||||
|
\value Highlight_NotContainsText
|
||||||
|
\value Highlight_BeginsWith
|
||||||
|
\value Highlight_EndsWith
|
||||||
|
|
||||||
|
\value Highlight_TimePeriod
|
||||||
|
|
||||||
|
\value Highlight_Duplicate
|
||||||
|
\value Highlight_Unique
|
||||||
|
|
||||||
|
\value Highlight_Blanks
|
||||||
|
\value Highlight_NoBlanks
|
||||||
|
\value Highlight_Errors
|
||||||
|
\value Highlight_NoErrors
|
||||||
|
|
||||||
|
\value Highlight_Top
|
||||||
|
\value Highlight_TopPercent
|
||||||
|
\value Highlight_Bottom
|
||||||
|
\value Highlight_BottomPercent
|
||||||
|
|
||||||
|
\value Highlight_AboveAverage
|
||||||
|
\value Highlight_AboveOrEqualAverage
|
||||||
|
\value Highlight_BelowAverage
|
||||||
|
\value Highlight_BelowOrEqualAverage
|
||||||
|
\value Highlight_AboveStdDev1
|
||||||
|
\value Highlight_AboveStdDev2
|
||||||
|
\value Highlight_AboveStdDev3
|
||||||
|
\value Highlight_BelowStdDev1
|
||||||
|
\value Highlight_BelowStdDev2
|
||||||
|
\value Highlight_BelowStdDev3
|
||||||
|
|
||||||
|
\value Highlight_SatisfyFormula
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Construct a conditional formatting object
|
||||||
|
*/
|
||||||
|
ConditionalFormatting::ConditionalFormatting()
|
||||||
|
:d(new ConditionalFormattingPrivate())
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs a copy of \a other.
|
||||||
|
*/
|
||||||
|
ConditionalFormatting::ConditionalFormatting(const ConditionalFormatting &other)
|
||||||
|
:d(other.d)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Assigns \a other to this conditional formatting and returns a reference to
|
||||||
|
this conditional formatting.
|
||||||
|
*/
|
||||||
|
ConditionalFormatting &ConditionalFormatting::operator=(const ConditionalFormatting &other)
|
||||||
|
{
|
||||||
|
this->d = other.d;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Destroy the object.
|
||||||
|
*/
|
||||||
|
ConditionalFormatting::~ConditionalFormatting()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Add a hightlight rule with the given \a type, \a formula1, \a formula2,
|
||||||
|
* \a format and \a stopIfTrue.
|
||||||
|
*/
|
||||||
|
bool ConditionalFormatting::addHighlightCellsRule(HighlightRuleType type, const QString &formula1, const QString &formula2, const Format &format, bool stopIfTrue)
|
||||||
|
{
|
||||||
|
if (format.isEmpty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool skipFormula1 = false;
|
||||||
|
|
||||||
|
QSharedPointer<XlsxCfRuleData> cfRule(new XlsxCfRuleData);
|
||||||
|
if (type >= Highlight_LessThan && type <= Highlight_NotBetween) {
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("cellIs");
|
||||||
|
QString op;
|
||||||
|
switch (type) {
|
||||||
|
case Highlight_Between: op = QStringLiteral("between"); break;
|
||||||
|
case Highlight_Equal: op = QStringLiteral("equal"); break;
|
||||||
|
case Highlight_GreaterThan: op = QStringLiteral("greaterThan"); break;
|
||||||
|
case Highlight_GreaterThanOrEqual: op = QStringLiteral("greaterThanOrEqual"); break;
|
||||||
|
case Highlight_LessThan: op = QStringLiteral("lessThan"); break;
|
||||||
|
case Highlight_LessThanOrEqual: op = QStringLiteral("lessThanOrEqual"); break;
|
||||||
|
case Highlight_NotBetween: op = QStringLiteral("notBetween"); break;
|
||||||
|
case Highlight_NotEqual: op = QStringLiteral("notEqual"); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_operator] = op;
|
||||||
|
} else if (type >= Highlight_ContainsText && type <= Highlight_EndsWith) {
|
||||||
|
if (type == Highlight_ContainsText) {
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("containsText");
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_operator] = QStringLiteral("containsText");
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_formula1_temp] = QStringLiteral("NOT(ISERROR(SEARCH(\"%1\",%2)))").arg(formula1);
|
||||||
|
} else if (type == Highlight_NotContainsText) {
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("notContainsText");
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_operator] = QStringLiteral("notContains");
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_formula1_temp] = QStringLiteral("ISERROR(SEARCH(\"%2\",%1))").arg(formula1);
|
||||||
|
} else if (type == Highlight_BeginsWith) {
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("beginsWith");
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_operator] = QStringLiteral("beginsWith");
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_formula1_temp] = QStringLiteral("LEFT(%2,LEN(\"%1\"))=\"%1\"").arg(formula1);
|
||||||
|
} else {
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("endsWith");
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_operator] = QStringLiteral("endsWith");
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_formula1_temp] = QStringLiteral("RIGHT(%2,LEN(\"%1\"))=\"%1\"").arg(formula1);
|
||||||
|
}
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_text] = formula1;
|
||||||
|
skipFormula1 = true;
|
||||||
|
} else if (type == Highlight_TimePeriod) {
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("timePeriod");
|
||||||
|
//:Todo
|
||||||
|
return false;
|
||||||
|
} else if (type == Highlight_Duplicate) {
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("duplicateValues");
|
||||||
|
} else if (type == Highlight_Unique) {
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("uniqueValues");
|
||||||
|
} else if (type == Highlight_Errors) {
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("containsErrors");
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_formula1_temp] = QStringLiteral("ISERROR(%1)");
|
||||||
|
skipFormula1 = true;
|
||||||
|
} else if (type == Highlight_NoErrors) {
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("notContainsErrors");
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_formula1_temp] = QStringLiteral("NOT(ISERROR(%1))");
|
||||||
|
skipFormula1 = true;
|
||||||
|
} else if (type == Highlight_Blanks) {
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("containsBlanks");
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_formula1_temp] = QStringLiteral("LEN(TRIM(%1))=0");
|
||||||
|
skipFormula1 = true;
|
||||||
|
} else if (type == Highlight_NoBlanks) {
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("notContainsBlanks");
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_formula1_temp] = QStringLiteral("LEN(TRIM(%1))>0");
|
||||||
|
skipFormula1 = true;
|
||||||
|
} else if (type >= Highlight_Top && type <= Highlight_BottomPercent) {
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("top10");
|
||||||
|
if (type == Highlight_Bottom || type == Highlight_BottomPercent)
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_bottom] = QStringLiteral("1");
|
||||||
|
if (type == Highlight_TopPercent || type == Highlight_BottomPercent)
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_percent] = QStringLiteral("1");
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_rank] = !formula1.isEmpty() ? formula1 : QStringLiteral("10");
|
||||||
|
skipFormula1 = true;
|
||||||
|
} else if (type >= Highlight_AboveAverage && type <= Highlight_BelowStdDev3) {
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("aboveAverage");
|
||||||
|
if (type >= Highlight_BelowAverage && type <= Highlight_BelowStdDev3)
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_aboveAverage] = QStringLiteral("0");
|
||||||
|
if (type == Highlight_AboveOrEqualAverage || type == Highlight_BelowOrEqualAverage)
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_equalAverage] = QStringLiteral("1");
|
||||||
|
if (type == Highlight_AboveStdDev1 || type == Highlight_BelowStdDev1)
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_stdDev] = QStringLiteral("1");
|
||||||
|
else if (type == Highlight_AboveStdDev2 || type == Highlight_BelowStdDev2)
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_stdDev] = QStringLiteral("2");
|
||||||
|
else if (type == Highlight_AboveStdDev3 || type == Highlight_BelowStdDev3)
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_stdDev] = QStringLiteral("3");
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cfRule->dxfFormat = format;
|
||||||
|
if (stopIfTrue)
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_stopIfTrue] = true;
|
||||||
|
if (!formula1.isEmpty() && !skipFormula1)
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_formula1] = formula1.startsWith(QLatin1String("=")) ? formula1.mid(1) : formula1;
|
||||||
|
if (!formula2.isEmpty())
|
||||||
|
cfRule->attrs[XlsxCfRuleData::A_formula2] = formula2.startsWith(QLatin1String("=")) ? formula2.mid(1) : formula2;
|
||||||
|
|
||||||
|
d->cfRules.append(cfRule);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \overload
|
||||||
|
*
|
||||||
|
* Add a hightlight rule with the given \a type \a format and \a stopIfTrue.
|
||||||
|
*/
|
||||||
|
bool ConditionalFormatting::addHighlightCellsRule(HighlightRuleType type, const Format &format, bool stopIfTrue)
|
||||||
|
{
|
||||||
|
if ((type >= Highlight_AboveAverage && type <= Highlight_BelowStdDev3)
|
||||||
|
|| (type >= Highlight_Duplicate && type <= Highlight_NoErrors)) {
|
||||||
|
return addHighlightCellsRule(type, QString(), QString(), format, stopIfTrue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \overload
|
||||||
|
*
|
||||||
|
* Add a hightlight rule with the given \a type, \a formula, \a format and \a stopIfTrue.
|
||||||
|
*/
|
||||||
|
bool ConditionalFormatting::addHighlightCellsRule(HighlightRuleType type, const QString &formula, const Format &format, bool stopIfTrue)
|
||||||
|
{
|
||||||
|
if (type == Highlight_Between || type == Highlight_NotBetween)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return addHighlightCellsRule(type, formula, QString(), format, stopIfTrue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the ranges on which the validation will be applied.
|
||||||
|
*/
|
||||||
|
QList<CellRange> ConditionalFormatting::ranges() const
|
||||||
|
{
|
||||||
|
return d->ranges;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Add the \a cell on which the conditional formatting will apply to.
|
||||||
|
*/
|
||||||
|
void ConditionalFormatting::addCell(const QString &cell)
|
||||||
|
{
|
||||||
|
d->ranges.append(CellRange(cell));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\overload
|
||||||
|
Add the cell(\a row, \a col) on which the conditional formatting will apply to.
|
||||||
|
*/
|
||||||
|
void ConditionalFormatting::addCell(int row, int col)
|
||||||
|
{
|
||||||
|
d->ranges.append(CellRange(row, col, row, col));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Add the \a range on which the conditional formatting will apply to.
|
||||||
|
*/
|
||||||
|
void ConditionalFormatting::addRange(const QString &range)
|
||||||
|
{
|
||||||
|
d->ranges.append(CellRange(range));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\overload
|
||||||
|
Add the range(\a firstRow, \a firstCol, \a lastRow, \a lastCol) on
|
||||||
|
which the conditional formatting will apply to.
|
||||||
|
*/
|
||||||
|
void ConditionalFormatting::addRange(int firstRow, int firstCol, int lastRow, int lastCol)
|
||||||
|
{
|
||||||
|
d->ranges.append(CellRange(firstRow, firstCol, lastRow, lastCol));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\overload
|
||||||
|
Add the \a range on which the conditional formatting will apply to.
|
||||||
|
*/
|
||||||
|
void ConditionalFormatting::addRange(const CellRange &range)
|
||||||
|
{
|
||||||
|
d->ranges.append(range);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConditionalFormatting::loadFromXml(QXmlStreamReader &reader) const
|
||||||
|
{
|
||||||
|
Q_ASSERT(reader.name() == QStringLiteral("conditionalFormatting"));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConditionalFormatting::saveToXml(QXmlStreamWriter &writer) const
|
||||||
|
{
|
||||||
|
writer.writeStartElement(QStringLiteral("conditionalFormatting"));
|
||||||
|
QStringList sqref;
|
||||||
|
foreach (CellRange range, ranges())
|
||||||
|
sqref.append(range.toString());
|
||||||
|
writer.writeAttribute(QStringLiteral("sqref"), sqref.join(QLatin1Char(' ')));
|
||||||
|
|
||||||
|
for (int i=0; i<d->cfRules.size(); ++i) {
|
||||||
|
const QSharedPointer<XlsxCfRuleData> &rule = d->cfRules[i];
|
||||||
|
writer.writeStartElement(QStringLiteral("cfRule"));
|
||||||
|
writer.writeAttribute(QStringLiteral("type"), rule->attrs[XlsxCfRuleData::A_type].toString());
|
||||||
|
if (rule->dxfFormat.dxfIndexValid())
|
||||||
|
writer.writeAttribute(QStringLiteral("dxfId"), QString::number(rule->dxfFormat.dxfIndex()));
|
||||||
|
writer.writeAttribute(QStringLiteral("priority"), QString::number(rule->priority));
|
||||||
|
if (rule->attrs.contains(XlsxCfRuleData::A_stopIfTrue))
|
||||||
|
writer.writeAttribute(QStringLiteral("stopIfTrue"), rule->attrs[XlsxCfRuleData::A_stopIfTrue].toString());
|
||||||
|
if (rule->attrs.contains(XlsxCfRuleData::A_aboveAverage))
|
||||||
|
writer.writeAttribute(QStringLiteral("aboveAverage"), rule->attrs[XlsxCfRuleData::A_aboveAverage].toString());
|
||||||
|
if (rule->attrs.contains(XlsxCfRuleData::A_percent))
|
||||||
|
writer.writeAttribute(QStringLiteral("percent"), rule->attrs[XlsxCfRuleData::A_percent].toString());
|
||||||
|
if (rule->attrs.contains(XlsxCfRuleData::A_bottom))
|
||||||
|
writer.writeAttribute(QStringLiteral("bottom"), rule->attrs[XlsxCfRuleData::A_bottom].toString());
|
||||||
|
if (rule->attrs.contains(XlsxCfRuleData::A_operator))
|
||||||
|
writer.writeAttribute(QStringLiteral("operator"), rule->attrs[XlsxCfRuleData::A_operator].toString());
|
||||||
|
if (rule->attrs.contains(XlsxCfRuleData::A_text))
|
||||||
|
writer.writeAttribute(QStringLiteral("text"), rule->attrs[XlsxCfRuleData::A_text].toString());
|
||||||
|
if (rule->attrs.contains(XlsxCfRuleData::A_timePeriod))
|
||||||
|
writer.writeAttribute(QStringLiteral("timePeriod"), rule->attrs[XlsxCfRuleData::A_timePeriod].toString());
|
||||||
|
if (rule->attrs.contains(XlsxCfRuleData::A_rank))
|
||||||
|
writer.writeAttribute(QStringLiteral("rank"), rule->attrs[XlsxCfRuleData::A_rank].toString());
|
||||||
|
if (rule->attrs.contains(XlsxCfRuleData::A_stdDev))
|
||||||
|
writer.writeAttribute(QStringLiteral("stdDev"), rule->attrs[XlsxCfRuleData::A_stdDev].toString());
|
||||||
|
if (rule->attrs.contains(XlsxCfRuleData::A_equalAverage))
|
||||||
|
writer.writeAttribute(QStringLiteral("equalAverage"), rule->attrs[XlsxCfRuleData::A_equalAverage].toString());
|
||||||
|
|
||||||
|
if (rule->attrs.contains(XlsxCfRuleData::A_formula1_temp)) {
|
||||||
|
QString startCell = ranges()[0].toString().split(QLatin1Char(':'))[0];
|
||||||
|
writer.writeTextElement(QStringLiteral("formula"), rule->attrs[XlsxCfRuleData::A_formula1_temp].toString().arg(startCell));
|
||||||
|
} else if (rule->attrs.contains(XlsxCfRuleData::A_formula1)) {
|
||||||
|
writer.writeTextElement(QStringLiteral("formula"), rule->attrs[XlsxCfRuleData::A_formula1].toString());
|
||||||
|
}
|
||||||
|
if (rule->attrs.contains(XlsxCfRuleData::A_formula2))
|
||||||
|
writer.writeTextElement(QStringLiteral("formula"), rule->attrs[XlsxCfRuleData::A_formula2].toString());
|
||||||
|
if (rule->attrs.contains(XlsxCfRuleData::A_formula3))
|
||||||
|
writer.writeTextElement(QStringLiteral("formula"), rule->attrs[XlsxCfRuleData::A_formula3].toString());
|
||||||
|
|
||||||
|
writer.writeEndElement(); //cfRule
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.writeEndElement(); //conditionalFormatting
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_END_NAMESPACE_XLSX
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
|
||||||
|
** All right reserved.
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
** a copy of this software and associated documentation files (the
|
||||||
|
** "Software"), to deal in the Software without restriction, including
|
||||||
|
** without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
** permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
** the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be
|
||||||
|
** included in all copies or substantial portions of the Software.
|
||||||
|
**
|
||||||
|
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef QXLSX_XLSXCONDITIONALFORMATTING_H
|
||||||
|
#define QXLSX_XLSXCONDITIONALFORMATTING_H
|
||||||
|
|
||||||
|
#include "xlsxglobal.h"
|
||||||
|
#include <QSharedDataPointer>
|
||||||
|
#include <QString>
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
|
class QXmlStreamReader;
|
||||||
|
class QXmlStreamWriter;
|
||||||
|
class ConditionalFormattingTest;
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE_XLSX
|
||||||
|
|
||||||
|
class CellRange;
|
||||||
|
class Format;
|
||||||
|
class Worksheet;
|
||||||
|
|
||||||
|
class ConditionalFormattingPrivate;
|
||||||
|
class Q_XLSX_EXPORT ConditionalFormatting
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum HighlightRuleType {
|
||||||
|
Highlight_LessThan,
|
||||||
|
Highlight_LessThanOrEqual,
|
||||||
|
Highlight_Equal,
|
||||||
|
Highlight_NotEqual,
|
||||||
|
Highlight_GreaterThanOrEqual,
|
||||||
|
Highlight_GreaterThan,
|
||||||
|
Highlight_Between,
|
||||||
|
Highlight_NotBetween,
|
||||||
|
|
||||||
|
Highlight_ContainsText,
|
||||||
|
Highlight_NotContainsText,
|
||||||
|
Highlight_BeginsWith,
|
||||||
|
Highlight_EndsWith,
|
||||||
|
|
||||||
|
Highlight_TimePeriod,
|
||||||
|
|
||||||
|
Highlight_Duplicate,
|
||||||
|
Highlight_Unique,
|
||||||
|
Highlight_Blanks,
|
||||||
|
Highlight_NoBlanks,
|
||||||
|
Highlight_Errors,
|
||||||
|
Highlight_NoErrors,
|
||||||
|
|
||||||
|
Highlight_Top,
|
||||||
|
Highlight_TopPercent,
|
||||||
|
Highlight_Bottom,
|
||||||
|
Highlight_BottomPercent,
|
||||||
|
|
||||||
|
Highlight_AboveAverage,
|
||||||
|
Highlight_AboveOrEqualAverage,
|
||||||
|
Highlight_AboveStdDev1,
|
||||||
|
Highlight_AboveStdDev2,
|
||||||
|
Highlight_AboveStdDev3,
|
||||||
|
Highlight_BelowAverage,
|
||||||
|
Highlight_BelowOrEqualAverage,
|
||||||
|
Highlight_BelowStdDev1,
|
||||||
|
Highlight_BelowStdDev2,
|
||||||
|
Highlight_BelowStdDev3,
|
||||||
|
|
||||||
|
Highlight_Expression
|
||||||
|
};
|
||||||
|
|
||||||
|
ConditionalFormatting();
|
||||||
|
ConditionalFormatting(const ConditionalFormatting &other);
|
||||||
|
~ConditionalFormatting();
|
||||||
|
|
||||||
|
bool addHighlightCellsRule(HighlightRuleType type, const Format &format, bool stopIfTrue=false);
|
||||||
|
bool addHighlightCellsRule(HighlightRuleType type, const QString &formula1, const Format &format, bool stopIfTrue=false);
|
||||||
|
bool addHighlightCellsRule(HighlightRuleType type, const QString &formula1, const QString &formula2, const Format &format, bool stopIfTrue=false);
|
||||||
|
|
||||||
|
QList<CellRange> ranges() const;
|
||||||
|
|
||||||
|
void addCell(const QString &cell);
|
||||||
|
void addCell(int row, int col);
|
||||||
|
void addRange(const QString &range);
|
||||||
|
void addRange(int firstRow, int firstCol, int lastRow, int lastCol);
|
||||||
|
void addRange(const CellRange &range);
|
||||||
|
|
||||||
|
//needed by QSharedDataPointer!!
|
||||||
|
ConditionalFormatting &operator=(const ConditionalFormatting &other);
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class Worksheet;
|
||||||
|
friend class ::ConditionalFormattingTest;
|
||||||
|
bool saveToXml(QXmlStreamWriter &writer) const;
|
||||||
|
bool loadFromXml(QXmlStreamReader &reader) const;
|
||||||
|
QSharedDataPointer<ConditionalFormattingPrivate> d;
|
||||||
|
};
|
||||||
|
|
||||||
|
QT_END_NAMESPACE_XLSX
|
||||||
|
|
||||||
|
#endif // QXLSX_XLSXCONDITIONALFORMATTING_H
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
|
||||||
|
** All right reserved.
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
** a copy of this software and associated documentation files (the
|
||||||
|
** "Software"), to deal in the Software without restriction, including
|
||||||
|
** without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
** permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
** the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be
|
||||||
|
** included in all copies or substantial portions of the Software.
|
||||||
|
**
|
||||||
|
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef XLSXCONDITIONALFORMATTING_P_H
|
||||||
|
#define XLSXCONDITIONALFORMATTING_P_H
|
||||||
|
|
||||||
|
//
|
||||||
|
// W A R N I N G
|
||||||
|
// -------------
|
||||||
|
//
|
||||||
|
// This file is not part of the Qt Xlsx API. It exists for the convenience
|
||||||
|
// of the Qt Xlsx. This header file may change from
|
||||||
|
// version to version without notice, or even be removed.
|
||||||
|
//
|
||||||
|
// We mean it.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "xlsxConditionalFormatting.h"
|
||||||
|
#include "xlsxformat.h"
|
||||||
|
#include <QSharedData>
|
||||||
|
#include <QSharedPointer>
|
||||||
|
#include <QMap>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE_XLSX
|
||||||
|
|
||||||
|
class XlsxCfRuleData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Attribute {
|
||||||
|
A_type,
|
||||||
|
A_dxfId,
|
||||||
|
//A_priority,
|
||||||
|
A_stopIfTrue,
|
||||||
|
A_aboveAverage,
|
||||||
|
A_percent,
|
||||||
|
A_bottom,
|
||||||
|
A_operator,
|
||||||
|
A_text,
|
||||||
|
A_timePeriod,
|
||||||
|
A_rank,
|
||||||
|
A_stdDev,
|
||||||
|
A_equalAverage,
|
||||||
|
|
||||||
|
A_dxfFormat,
|
||||||
|
A_formula1,
|
||||||
|
A_formula2,
|
||||||
|
A_formula3,
|
||||||
|
A_formula1_temp
|
||||||
|
};
|
||||||
|
|
||||||
|
XlsxCfRuleData()
|
||||||
|
:priority(1)
|
||||||
|
{}
|
||||||
|
|
||||||
|
int priority;
|
||||||
|
Format dxfFormat;
|
||||||
|
QMap<int, QVariant> attrs;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConditionalFormattingPrivate : public QSharedData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ConditionalFormattingPrivate();
|
||||||
|
ConditionalFormattingPrivate(const ConditionalFormattingPrivate &other);
|
||||||
|
~ConditionalFormattingPrivate();
|
||||||
|
|
||||||
|
QList<QSharedPointer<XlsxCfRuleData> >cfRules;
|
||||||
|
QList<CellRange> ranges;
|
||||||
|
};
|
||||||
|
|
||||||
|
QT_END_NAMESPACE_XLSX
|
||||||
|
#endif // XLSXCONDITIONALFORMATTING_P_H
|
||||||
@@ -249,6 +249,14 @@ bool Document::addDataValidation(const DataValidation &validation)
|
|||||||
return currentWorksheet()->addDataValidation(validation);
|
return currentWorksheet()->addDataValidation(validation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Add a conditional formatting \a cf for current worksheet. Returns true if successful.
|
||||||
|
*/
|
||||||
|
bool Document::addConditionalFormatting(const ConditionalFormatting &cf)
|
||||||
|
{
|
||||||
|
return currentWorksheet()->addConditionalFormatting(cf);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Returns a Cell object based on the given \a pos. 0 will be returned if the cell doesn't exist.
|
* Returns a Cell object based on the given \a pos. 0 will be returned if the cell doesn't exist.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ class Package;
|
|||||||
class Cell;
|
class Cell;
|
||||||
class CellRange;
|
class CellRange;
|
||||||
class DataValidation;
|
class DataValidation;
|
||||||
|
class ConditionalFormatting;
|
||||||
|
|
||||||
class DocumentPrivate;
|
class DocumentPrivate;
|
||||||
class Q_XLSX_EXPORT Document : public QObject
|
class Q_XLSX_EXPORT Document : public QObject
|
||||||
@@ -69,6 +70,7 @@ public:
|
|||||||
bool groupRows(int rowFirst, int rowLast, bool collapsed = true);
|
bool groupRows(int rowFirst, int rowLast, bool collapsed = true);
|
||||||
bool groupColumns(int colFirst, int colLast, bool collapsed = true);
|
bool groupColumns(int colFirst, int colLast, bool collapsed = true);
|
||||||
bool addDataValidation(const DataValidation &validation);
|
bool addDataValidation(const DataValidation &validation);
|
||||||
|
bool addConditionalFormatting(const ConditionalFormatting &cf);
|
||||||
|
|
||||||
Cell *cellAt(const QString &cell) const;
|
Cell *cellAt(const QString &cell) const;
|
||||||
Cell *cellAt(int row, int col) const;
|
Cell *cellAt(int row, int col) const;
|
||||||
|
|||||||
@@ -891,6 +891,9 @@ int Format::borderIndex() const
|
|||||||
return d->border_index;
|
return d->border_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \internal
|
||||||
|
*/
|
||||||
void Format::setBorderIndex(int index)
|
void Format::setBorderIndex(int index)
|
||||||
{
|
{
|
||||||
d->border_index = index;
|
d->border_index = index;
|
||||||
@@ -986,6 +989,9 @@ void Format::setPatternBackgroundColor(const QColor &color)
|
|||||||
setProperty(FormatPrivate::P_Fill_BgColor, color);
|
setProperty(FormatPrivate::P_Fill_BgColor, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \internal
|
||||||
|
*/
|
||||||
bool Format::fillIndexValid() const
|
bool Format::fillIndexValid() const
|
||||||
{
|
{
|
||||||
if (!hasFillData())
|
if (!hasFillData())
|
||||||
@@ -993,6 +999,9 @@ bool Format::fillIndexValid() const
|
|||||||
return d->fill_index_valid;
|
return d->fill_index_valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \internal
|
||||||
|
*/
|
||||||
int Format::fillIndex() const
|
int Format::fillIndex() const
|
||||||
{
|
{
|
||||||
if (!d)
|
if (!d)
|
||||||
@@ -1000,6 +1009,9 @@ int Format::fillIndex() const
|
|||||||
return d->fill_index;
|
return d->fill_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \internal
|
||||||
|
*/
|
||||||
void Format::setFillIndex(int index)
|
void Format::setFillIndex(int index)
|
||||||
{
|
{
|
||||||
d->fill_index = index;
|
d->fill_index = index;
|
||||||
@@ -1133,8 +1145,14 @@ QByteArray Format::formatKey() const
|
|||||||
return d->formatKey;
|
return d->formatKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \internal
|
||||||
|
* Called by QXlsx::Styles or some unittests.
|
||||||
|
*/
|
||||||
void Format::setXfIndex(int index)
|
void Format::setXfIndex(int index)
|
||||||
{
|
{
|
||||||
|
if (!d)
|
||||||
|
d = new FormatPrivate;
|
||||||
d->xf_index = index;
|
d->xf_index = index;
|
||||||
d->xf_indexValid = true;
|
d->xf_indexValid = true;
|
||||||
}
|
}
|
||||||
@@ -1159,8 +1177,14 @@ bool Format::xfIndexValid() const
|
|||||||
return d->xf_indexValid;
|
return d->xf_indexValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \internal
|
||||||
|
* Called by QXlsx::Styles or some unittests.
|
||||||
|
*/
|
||||||
void Format::setDxfIndex(int index)
|
void Format::setDxfIndex(int index)
|
||||||
{
|
{
|
||||||
|
if (!d)
|
||||||
|
d = new FormatPrivate;
|
||||||
d->dxf_index = index;
|
d->dxf_index = index;
|
||||||
d->dxf_indexValid = true;
|
d->dxf_indexValid = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -252,10 +252,6 @@ public:
|
|||||||
int xfIndex() const;
|
int xfIndex() const;
|
||||||
bool dxfIndexValid() const;
|
bool dxfIndexValid() const;
|
||||||
int dxfIndex() const;
|
int dxfIndex() const;
|
||||||
private:
|
|
||||||
friend class Styles;
|
|
||||||
friend class ::FormatTest;
|
|
||||||
friend Q_XLSX_EXPORT QDebug operator<<(QDebug, const Format &f);
|
|
||||||
|
|
||||||
void fixNumberFormat(int id, const QString &format);
|
void fixNumberFormat(int id, const QString &format);
|
||||||
void setFontIndex(int index);
|
void setFontIndex(int index);
|
||||||
@@ -263,6 +259,10 @@ private:
|
|||||||
void setFillIndex(int index);
|
void setFillIndex(int index);
|
||||||
void setXfIndex(int index);
|
void setXfIndex(int index);
|
||||||
void setDxfIndex(int index);
|
void setDxfIndex(int index);
|
||||||
|
private:
|
||||||
|
friend class Styles;
|
||||||
|
friend class ::FormatTest;
|
||||||
|
friend Q_XLSX_EXPORT QDebug operator<<(QDebug, const Format &f);
|
||||||
|
|
||||||
int theme() const;
|
int theme() const;
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include "xlsxcell.h"
|
#include "xlsxcell.h"
|
||||||
#include "xlsxcell_p.h"
|
#include "xlsxcell_p.h"
|
||||||
#include "xlsxcellrange.h"
|
#include "xlsxcellrange.h"
|
||||||
|
#include "xlsxconditionalformatting_p.h"
|
||||||
|
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
@@ -931,6 +932,22 @@ bool Worksheet::addDataValidation(const DataValidation &validation)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Worksheet::addConditionalFormatting(const ConditionalFormatting &cf)
|
||||||
|
{
|
||||||
|
Q_D(Worksheet);
|
||||||
|
if (cf.ranges().isEmpty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (int i=0; i<cf.d->cfRules.size(); ++i) {
|
||||||
|
const QSharedPointer<XlsxCfRuleData> &rule = cf.d->cfRules[i];
|
||||||
|
if (!rule->dxfFormat.isEmpty())
|
||||||
|
d->workbook->styles()->addDxfFormat(rule->dxfFormat);
|
||||||
|
rule->priority = 1;
|
||||||
|
}
|
||||||
|
d->conditionalFormattingList.append(cf);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int Worksheet::insertImage(int row, int column, const QImage &image, const QPointF &offset, double xScale, double yScale)
|
int Worksheet::insertImage(int row, int column, const QImage &image, const QPointF &offset, double xScale, double yScale)
|
||||||
{
|
{
|
||||||
Q_D(Worksheet);
|
Q_D(Worksheet);
|
||||||
@@ -1120,6 +1137,8 @@ void Worksheet::saveToXmlFile(QIODevice *device)
|
|||||||
writer.writeEndElement();//sheetData
|
writer.writeEndElement();//sheetData
|
||||||
|
|
||||||
d->writeMergeCells(writer);
|
d->writeMergeCells(writer);
|
||||||
|
foreach (const ConditionalFormatting cf, d->conditionalFormattingList)
|
||||||
|
cf.saveToXml(writer);
|
||||||
d->writeDataValidation(writer);
|
d->writeDataValidation(writer);
|
||||||
d->writeHyperlinks(writer);
|
d->writeHyperlinks(writer);
|
||||||
d->writeDrawings(writer);
|
d->writeDrawings(writer);
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ class Workbook;
|
|||||||
class Format;
|
class Format;
|
||||||
class Drawing;
|
class Drawing;
|
||||||
class DataValidation;
|
class DataValidation;
|
||||||
|
class ConditionalFormatting;
|
||||||
class CellRange;
|
class CellRange;
|
||||||
struct XlsxImageData;
|
struct XlsxImageData;
|
||||||
class RichString;
|
class RichString;
|
||||||
@@ -80,6 +81,7 @@ public:
|
|||||||
int writeHyperlink(int row, int column, const QUrl &url, const Format &format=Format(), const QString &display=QString(), const QString &tip=QString());
|
int writeHyperlink(int row, int column, const QUrl &url, const Format &format=Format(), const QString &display=QString(), const QString &tip=QString());
|
||||||
|
|
||||||
bool addDataValidation(const DataValidation &validation);
|
bool addDataValidation(const DataValidation &validation);
|
||||||
|
bool addConditionalFormatting(const ConditionalFormatting &cf);
|
||||||
|
|
||||||
Cell *cellAt(const QString &row_column) const;
|
Cell *cellAt(const QString &row_column) const;
|
||||||
Cell *cellAt(int row, int column) const;
|
Cell *cellAt(int row, int column) const;
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
#include "xlsxworksheet.h"
|
#include "xlsxworksheet.h"
|
||||||
#include "xlsxcell.h"
|
#include "xlsxcell.h"
|
||||||
#include "xlsxdatavalidation.h"
|
#include "xlsxdatavalidation.h"
|
||||||
|
#include "xlsxconditionalformatting.h"
|
||||||
|
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QSharedPointer>
|
#include <QSharedPointer>
|
||||||
@@ -215,6 +216,7 @@ public:
|
|||||||
QList<QPair<QString, QString> > drawingLinks;
|
QList<QPair<QString, QString> > drawingLinks;
|
||||||
|
|
||||||
QList<DataValidation> dataValidationsList;
|
QList<DataValidation> dataValidationsList;
|
||||||
|
QList<ConditionalFormatting> conditionalFormattingList;
|
||||||
|
|
||||||
int xls_rowmax;
|
int xls_rowmax;
|
||||||
int xls_colmax;
|
int xls_colmax;
|
||||||
|
|||||||
+2
-1
@@ -10,4 +10,5 @@ SUBDIRS=\
|
|||||||
sharedstrings \
|
sharedstrings \
|
||||||
styles \
|
styles \
|
||||||
format \
|
format \
|
||||||
richstring
|
richstring \
|
||||||
|
xlsxconditionalformatting
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
#include "xlsxconditionalformatting.h"
|
||||||
|
#include "xlsxformat.h"
|
||||||
|
#include "private/xlsxconditionalformatting_p.h"
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <QtTest>
|
||||||
|
#include <QBuffer>
|
||||||
|
#include <QXmlStreamWriter>
|
||||||
|
|
||||||
|
using namespace QXlsx;
|
||||||
|
|
||||||
|
class ConditionalFormattingTest : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
ConditionalFormattingTest();
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void testHighlightRules();
|
||||||
|
void testHighlightRules_data();
|
||||||
|
};
|
||||||
|
|
||||||
|
ConditionalFormattingTest::ConditionalFormattingTest()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConditionalFormattingTest::testHighlightRules_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<int>("type");
|
||||||
|
QTest::addColumn<QString>("formula1");
|
||||||
|
QTest::addColumn<QString>("formula2");
|
||||||
|
QTest::addColumn<QByteArray>("result");
|
||||||
|
|
||||||
|
QTest::newRow("lessThan")<<(int)ConditionalFormatting::Highlight_LessThan
|
||||||
|
<<"100"
|
||||||
|
<<QString()
|
||||||
|
<<QByteArray("<cfRule type=\"cellIs\" dxfId=\"0\" priority=\"1\" operator=\"lessThan\"><formula>100</formula></cfRule>");
|
||||||
|
QTest::newRow("between")<<(int)ConditionalFormatting::Highlight_Between
|
||||||
|
<<"4"
|
||||||
|
<<"20"
|
||||||
|
<<QByteArray("<cfRule type=\"cellIs\" dxfId=\"0\" priority=\"1\" operator=\"between\"><formula>4</formula><formula>20</formula></cfRule>");
|
||||||
|
|
||||||
|
QTest::newRow("containsText")<<(int)ConditionalFormatting::Highlight_ContainsText
|
||||||
|
<<"Qt"
|
||||||
|
<<QString()
|
||||||
|
<<QByteArray("<cfRule type=\"containsText\" dxfId=\"0\" priority=\"1\" operator=\"containsText\" text=\"Qt\">");
|
||||||
|
QTest::newRow("beginsWith")<<(int)ConditionalFormatting::Highlight_BeginsWith
|
||||||
|
<<"Qt"
|
||||||
|
<<QString()
|
||||||
|
<<QByteArray("<cfRule type=\"beginsWith\" dxfId=\"0\" priority=\"1\" operator=\"beginsWith\" text=\"Qt\"><formula>LEFT(C3,LEN"); //(\"Qt\"))=\"Qt\"</formula></cfRule>");
|
||||||
|
QTest::newRow("duplicateValues")<<(int)ConditionalFormatting::Highlight_Duplicate
|
||||||
|
<<QString()
|
||||||
|
<<QString()
|
||||||
|
<<QByteArray("<cfRule type=\"duplicateValues\" dxfId=\"0\" priority=\"1\"/>");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConditionalFormattingTest::testHighlightRules()
|
||||||
|
{
|
||||||
|
QFETCH(int, type);
|
||||||
|
QFETCH(QString, formula1);
|
||||||
|
QFETCH(QString, formula2);
|
||||||
|
QFETCH(QByteArray, result);
|
||||||
|
|
||||||
|
Format fmt;
|
||||||
|
fmt.setFontBold(true);
|
||||||
|
fmt.setDxfIndex(0);
|
||||||
|
|
||||||
|
ConditionalFormatting cf;
|
||||||
|
cf.addHighlightCellsRule((ConditionalFormatting::HighlightRuleType)type, formula1, formula2, fmt);
|
||||||
|
cf.addRange("C3:C10");
|
||||||
|
|
||||||
|
QBuffer buffer;
|
||||||
|
buffer.open(QIODevice::WriteOnly);
|
||||||
|
QXmlStreamWriter writer(&buffer);
|
||||||
|
cf.saveToXml(writer);
|
||||||
|
qDebug()<<buffer.buffer();
|
||||||
|
QVERIFY(buffer.buffer().contains(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
QTEST_APPLESS_MAIN(ConditionalFormattingTest)
|
||||||
|
|
||||||
|
#include "tst_conditionalformattingtest.moc"
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
QT += testlib xlsx xlsx-private
|
||||||
|
CONFIG += testcase
|
||||||
|
DEFINES += XLSX_TEST
|
||||||
|
|
||||||
|
TARGET = tst_conditionalformattingtest
|
||||||
|
CONFIG += console
|
||||||
|
CONFIG -= app_bundle
|
||||||
|
|
||||||
|
TEMPLATE = app
|
||||||
|
|
||||||
|
SOURCES += tst_conditionalformattingtest.cpp
|
||||||
|
DEFINES += SRCDIR=\\\"$$PWD/\\\"
|
||||||
Reference in New Issue
Block a user