Code refactoring: Introduce new class CellFormula
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#include "xlsxdocument.h"
|
||||
#include "xlsxformat.h"
|
||||
#include "xlsxworksheet.h"
|
||||
#include "xlsxcellformula.h"
|
||||
|
||||
QTXLSX_USE_NAMESPACE
|
||||
|
||||
@@ -58,8 +59,8 @@ int main()
|
||||
sheet->write(row, 3, QString(row%5+1, 'X')); //C2:C19
|
||||
sheet->write(row, 5, 100.0 - row); //E2:E19
|
||||
}
|
||||
sheet->writeArrayFormula("C20", "{=SUM(IF((C2:C19=\"X\")*(B2:B19=\"X\"),1,0))}");
|
||||
sheet->writeArrayFormula("F2:F19", "{=E2:E19*10}");
|
||||
sheet->writeFormula("C20", CellFormula("SUM(IF((C2:C19=\"X\")*(B2:B19=\"X\"),1,0))", "C20", CellFormula::ArrayType));
|
||||
sheet->writeFormula("F2", CellFormula("E2:E19*10", "F2:F19", CellFormula::ArrayType));
|
||||
//![2]
|
||||
|
||||
//![3]
|
||||
|
||||
+5
-2
@@ -46,7 +46,9 @@ HEADERS += $$PWD/xlsxdocpropscore_p.h \
|
||||
$$PWD/xlsxabstractooxmlfile_p.h \
|
||||
$$PWD/xlsxchart.h \
|
||||
$$PWD/xlsxchart_p.h \
|
||||
$$PWD/xlsxsimpleooxmlfile_p.h
|
||||
$$PWD/xlsxsimpleooxmlfile_p.h \
|
||||
$$PWD/xlsxcellformula.h \
|
||||
$$PWD/xlsxcellformula_p.h
|
||||
|
||||
SOURCES += $$PWD/xlsxdocpropscore.cpp \
|
||||
$$PWD/xlsxdocpropsapp.cpp \
|
||||
@@ -77,5 +79,6 @@ SOURCES += $$PWD/xlsxdocpropscore.cpp \
|
||||
$$PWD/xlsxmediafile.cpp \
|
||||
$$PWD/xlsxabstractooxmlfile.cpp \
|
||||
$$PWD/xlsxchart.cpp \
|
||||
$$PWD/xlsxsimpleooxmlfile.cpp
|
||||
$$PWD/xlsxsimpleooxmlfile.cpp \
|
||||
$$PWD/xlsxcellformula.cpp
|
||||
|
||||
|
||||
+26
-20
@@ -40,9 +40,8 @@ CellPrivate::CellPrivate(Cell *p) :
|
||||
}
|
||||
|
||||
CellPrivate::CellPrivate(const CellPrivate * const cp)
|
||||
: value(cp->value), formula(cp->formula), dataType(cp->dataType)
|
||||
, format(cp->format), range(cp->range), richString(cp->richString)
|
||||
, parent(cp->parent)
|
||||
: value(cp->value), formula(cp->formula), cellType(cp->cellType)
|
||||
, format(cp->format), richString(cp->richString), parent(cp->parent)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -55,27 +54,24 @@ CellPrivate::CellPrivate(const CellPrivate * const cp)
|
||||
*/
|
||||
|
||||
/*!
|
||||
\enum Cell::DataType
|
||||
|
||||
\value Blank,
|
||||
\value String,
|
||||
\value Numeric,
|
||||
\value Formula,
|
||||
\value Boolean,
|
||||
\value Error,
|
||||
\value InlineString,
|
||||
\value ArrayFormula
|
||||
\enum Cell::CellType
|
||||
\value BooleanType Boolean type
|
||||
\value NumberType Number type, can be blank or used with forumula
|
||||
\value ErrorType Error type
|
||||
\value SharedStringType Shared string type
|
||||
\value StringType String type, can be used with forumula
|
||||
\value InlineStringType Inline string type
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* Created by Worksheet only.
|
||||
*/
|
||||
Cell::Cell(const QVariant &data, DataType type, const Format &format, Worksheet *parent) :
|
||||
Cell::Cell(const QVariant &data, CellType type, const Format &format, Worksheet *parent) :
|
||||
d_ptr(new CellPrivate(this))
|
||||
{
|
||||
d_ptr->value = data;
|
||||
d_ptr->dataType = type;
|
||||
d_ptr->cellType = type;
|
||||
d_ptr->format = format;
|
||||
d_ptr->parent = parent;
|
||||
}
|
||||
@@ -100,10 +96,10 @@ Cell::~Cell()
|
||||
/*!
|
||||
* Return the dataType of this Cell
|
||||
*/
|
||||
Cell::DataType Cell::dataType() const
|
||||
Cell::CellType Cell::cellType() const
|
||||
{
|
||||
Q_D(const Cell);
|
||||
return d->dataType;
|
||||
return d->cellType;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -124,10 +120,19 @@ Format Cell::format() const
|
||||
return d->format;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns true if the cell has one formula.
|
||||
*/
|
||||
bool Cell::hasFormula() const
|
||||
{
|
||||
Q_D(const Cell);
|
||||
return d->formula.isValid();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Return the formula contents if the dataType is Formula
|
||||
*/
|
||||
QString Cell::formula() const
|
||||
CellFormula Cell::formula() const
|
||||
{
|
||||
Q_D(const Cell);
|
||||
return d->formula;
|
||||
@@ -139,7 +144,7 @@ QString Cell::formula() const
|
||||
bool Cell::isDateTime() const
|
||||
{
|
||||
Q_D(const Cell);
|
||||
if (d->dataType == Numeric && d->value.toDouble() >=0
|
||||
if (d->cellType == NumberType && d->value.toDouble() >=0
|
||||
&& d->format.isValid() && d->format.isDateTimeFormat()) {
|
||||
return true;
|
||||
}
|
||||
@@ -163,7 +168,8 @@ QDateTime Cell::dateTime() const
|
||||
bool Cell::isRichString() const
|
||||
{
|
||||
Q_D(const Cell);
|
||||
if (d->dataType != String && d->dataType != InlineString)
|
||||
if (d->cellType != SharedStringType && d->cellType != InlineStringType
|
||||
&& d->cellType != StringType)
|
||||
return false;
|
||||
|
||||
return d->richString.isRichString();
|
||||
|
||||
+13
-12
@@ -33,6 +33,7 @@ QT_BEGIN_NAMESPACE_XLSX
|
||||
|
||||
class Worksheet;
|
||||
class Format;
|
||||
class CellFormula;
|
||||
class CellPrivate;
|
||||
class WorksheetPrivate;
|
||||
|
||||
@@ -40,21 +41,21 @@ class Q_XLSX_EXPORT Cell
|
||||
{
|
||||
Q_DECLARE_PRIVATE(Cell)
|
||||
public:
|
||||
enum DataType {
|
||||
Blank,
|
||||
String,
|
||||
Numeric,
|
||||
Formula,
|
||||
Boolean,
|
||||
Error,
|
||||
InlineString,
|
||||
ArrayFormula
|
||||
enum CellType {
|
||||
BooleanType, //t="b"
|
||||
NumberType, //t="n" (default)
|
||||
ErrorType, //t="e"
|
||||
SharedStringType, //t="s"
|
||||
StringType, //t="str"
|
||||
InlineStringType //t="inlineStr"
|
||||
};
|
||||
|
||||
DataType dataType() const;
|
||||
CellType cellType() const;
|
||||
QVariant value() const;
|
||||
Format format() const;
|
||||
QString formula() const;
|
||||
|
||||
bool hasFormula() const;
|
||||
CellFormula formula() const;
|
||||
|
||||
bool isDateTime() const;
|
||||
QDateTime dateTime() const;
|
||||
@@ -66,7 +67,7 @@ private:
|
||||
friend class Worksheet;
|
||||
friend class WorksheetPrivate;
|
||||
|
||||
Cell(const QVariant &data=QVariant(), DataType type=Blank, const Format &format=Format(), Worksheet *parent=0);
|
||||
Cell(const QVariant &data=QVariant(), CellType type=NumberType, const Format &format=Format(), Worksheet *parent=0);
|
||||
Cell(const Cell * const cell);
|
||||
CellPrivate * const d_ptr;
|
||||
};
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "xlsxcell.h"
|
||||
#include "xlsxcellrange.h"
|
||||
#include "xlsxrichstring.h"
|
||||
#include "xlsxcellformula.h"
|
||||
#include <QList>
|
||||
#include <QSharedPointer>
|
||||
|
||||
@@ -53,10 +54,9 @@ public:
|
||||
CellPrivate(const CellPrivate * const cp);
|
||||
|
||||
QVariant value;
|
||||
QString formula;
|
||||
Cell::DataType dataType;
|
||||
CellFormula formula;
|
||||
Cell::CellType cellType;
|
||||
Format format;
|
||||
CellRange range; //used for arrayFormula
|
||||
|
||||
RichString richString;
|
||||
|
||||
|
||||
@@ -0,0 +1,249 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 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 "xlsxcellformula.h"
|
||||
#include "xlsxcellformula_p.h"
|
||||
|
||||
#include <QXmlStreamReader>
|
||||
#include <QXmlStreamWriter>
|
||||
|
||||
QT_BEGIN_NAMESPACE_XLSX
|
||||
|
||||
CellFormulaPrivate::CellFormulaPrivate(const QString &formula_, const CellRange &ref_, CellFormula::FormulaType type_)
|
||||
:formula(formula_), type(type_), reference(ref_), si(0)
|
||||
{
|
||||
//Remove the formula '=' sign if exists
|
||||
if (formula.startsWith(QLatin1String("=")))
|
||||
formula.remove(0,1);
|
||||
else if (formula.startsWith(QLatin1String("{=")) && formula.endsWith(QLatin1String("}")))
|
||||
formula = formula.mid(2, formula.length()-3);
|
||||
}
|
||||
|
||||
CellFormulaPrivate::CellFormulaPrivate(const CellFormulaPrivate &other)
|
||||
: QSharedData(other)
|
||||
, formula(other.formula), type(other.type), reference(other.reference), si(other.si)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CellFormulaPrivate::~CellFormulaPrivate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
\class CellFormula
|
||||
\inmodule QtXlsx
|
||||
\brief The CellFormula class provides a API that is used to handle the cell formula.
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\enum CellFormula::FormulaType
|
||||
\value NormalType
|
||||
\value ArrayType
|
||||
\value DataTableType
|
||||
\value SharedType
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Creates a new formula.
|
||||
*/
|
||||
CellFormula::CellFormula()
|
||||
{
|
||||
//The d pointer is initialized with a null pointer
|
||||
}
|
||||
|
||||
/*!
|
||||
* Creates a new formula with the given \a formula and \a type.
|
||||
*/
|
||||
CellFormula::CellFormula(const char *formula, FormulaType type)
|
||||
:d(new CellFormulaPrivate(QString::fromLatin1(formula), CellRange(), type))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
* Creates a new formula with the given \a formula and \a type.
|
||||
*/
|
||||
CellFormula::CellFormula(const QString &formula, FormulaType type)
|
||||
:d(new CellFormulaPrivate(formula, CellRange(), type))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
* Creates a new formula with the given \a formula, \a ref and \a type.
|
||||
*/
|
||||
CellFormula::CellFormula(const QString &formula, const CellRange &ref, FormulaType type)
|
||||
:d(new CellFormulaPrivate(formula, ref, type))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
Creates a new formula with the same attributes as the \a other formula.
|
||||
*/
|
||||
CellFormula::CellFormula(const CellFormula &other)
|
||||
:d(other.d)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Assigns the \a other formula to this formula, and returns a
|
||||
reference to this formula.
|
||||
*/
|
||||
CellFormula &CellFormula::operator =(const CellFormula &other)
|
||||
{
|
||||
d = other.d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Destroys this formula.
|
||||
*/
|
||||
CellFormula::~CellFormula()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the type of the formula.
|
||||
*/
|
||||
CellFormula::FormulaType CellFormula::formulaType() const
|
||||
{
|
||||
return d ? d->type : NormalType;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the contents of the formula.
|
||||
*/
|
||||
QString CellFormula::formulaContent() const
|
||||
{
|
||||
return d ? d->formula : QString();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the reference cells of the formula. For normal formula,
|
||||
* this will return an invalid CellRange object.
|
||||
*/
|
||||
CellRange CellFormula::reference() const
|
||||
{
|
||||
return d ? d->reference : CellRange();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns whether the formula is valid.
|
||||
*/
|
||||
bool CellFormula::isValid() const
|
||||
{
|
||||
return d;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the shared index for shared formula.
|
||||
*/
|
||||
int CellFormula::sharedIndex() const
|
||||
{
|
||||
return d && d->type == SharedType ? d->si : -1;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
bool CellFormula::saveToXml(QXmlStreamWriter &writer) const
|
||||
{
|
||||
writer.writeStartElement(QStringLiteral("f"));
|
||||
QString t;
|
||||
switch (d->type) {
|
||||
case CellFormula::ArrayType:
|
||||
t = QStringLiteral("array");
|
||||
break;
|
||||
case CellFormula::SharedType:
|
||||
t = QStringLiteral("shared");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!t.isEmpty())
|
||||
writer.writeAttribute(QStringLiteral("t"), t);
|
||||
if (d->reference.isValid())
|
||||
writer.writeAttribute(QStringLiteral("ref"), d->reference.toString());
|
||||
if (d->type == CellFormula::SharedType)
|
||||
writer.writeAttribute(QStringLiteral("si"), QString::number(d->si));
|
||||
|
||||
writer.writeCharacters(d->formula);
|
||||
writer.writeEndElement(); //f
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
bool CellFormula::loadFromXml(QXmlStreamReader &reader)
|
||||
{
|
||||
Q_ASSERT(reader.name() == QLatin1String("f"));
|
||||
if (!d)
|
||||
d = new CellFormulaPrivate(QString(), CellRange(), NormalType);
|
||||
|
||||
QXmlStreamAttributes attributes = reader.attributes();
|
||||
QString typeString = attributes.value(QLatin1String("t")).toString();
|
||||
if (typeString == QLatin1String("array"))
|
||||
d->type = ArrayType;
|
||||
else if (typeString == QLatin1String("shared"))
|
||||
d->type = SharedType;
|
||||
else
|
||||
d->type = NormalType;
|
||||
|
||||
if (attributes.hasAttribute(QLatin1String("ref"))) {
|
||||
QString refString = attributes.value(QLatin1String("ref")).toString();
|
||||
d->reference = CellRange(refString);
|
||||
} else if (attributes.hasAttribute(QLatin1String("si"))) {
|
||||
d->si = attributes.value(QLatin1String("si")).toString().toInt();
|
||||
}
|
||||
|
||||
d->formula = reader.readElementText();
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
bool CellFormula::operator ==(const CellFormula &formula) const
|
||||
{
|
||||
return d->formula == formula.d->formula && d->type == formula.d->type
|
||||
&& d->si ==formula.d->si;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
bool CellFormula::operator !=(const CellFormula &formula) const
|
||||
{
|
||||
return d->formula != formula.d->formula || d->type != formula.d->type
|
||||
|| d->si !=formula.d->si;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE_XLSX
|
||||
@@ -0,0 +1,74 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 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_XLSXCELLFORMULA_H
|
||||
#define QXLSX_XLSXCELLFORMULA_H
|
||||
|
||||
#include "xlsxglobal.h"
|
||||
#include <QExplicitlySharedDataPointer>
|
||||
|
||||
class QXmlStreamWriter;
|
||||
class QXmlStreamReader;
|
||||
|
||||
QT_BEGIN_NAMESPACE_XLSX
|
||||
|
||||
class CellFormulaPrivate;
|
||||
class CellRange;
|
||||
|
||||
class Q_XLSX_EXPORT CellFormula
|
||||
{
|
||||
public:
|
||||
enum FormulaType {
|
||||
NormalType,
|
||||
ArrayType,
|
||||
DataTableType,
|
||||
SharedType
|
||||
};
|
||||
|
||||
CellFormula();
|
||||
CellFormula(const char *formula, FormulaType type=NormalType);
|
||||
CellFormula(const QString &formula, FormulaType type=NormalType);
|
||||
CellFormula(const QString &formula, const CellRange &ref, FormulaType type);
|
||||
CellFormula(const CellFormula &other);
|
||||
~CellFormula();
|
||||
CellFormula &operator =(const CellFormula &other);
|
||||
bool isValid() const;
|
||||
|
||||
FormulaType formulaType() const;
|
||||
QString formulaContent() const;
|
||||
CellRange reference() const;
|
||||
int sharedIndex() const;
|
||||
|
||||
bool operator == (const CellFormula &formula) const;
|
||||
bool operator != (const CellFormula &formula) const;
|
||||
|
||||
bool saveToXml(QXmlStreamWriter &writer) const;
|
||||
bool loadFromXml(QXmlStreamReader &reader);
|
||||
private:
|
||||
QExplicitlySharedDataPointer<CellFormulaPrivate> d;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE_XLSX
|
||||
|
||||
#endif // QXLSX_XLSXCELLFORMULA_H
|
||||
@@ -0,0 +1,63 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2013-2014 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 XLSXCELLFORMULA_P_H
|
||||
#define XLSXCELLFORMULA_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 "xlsxglobal.h"
|
||||
#include "xlsxcellformula.h"
|
||||
#include "xlsxcellrange.h"
|
||||
|
||||
#include <QSharedData>
|
||||
#include <QString>
|
||||
|
||||
QT_BEGIN_NAMESPACE_XLSX
|
||||
|
||||
class CellFormulaPrivate : public QSharedData
|
||||
{
|
||||
public:
|
||||
CellFormulaPrivate(const QString &formula, const CellRange &reference, CellFormula::FormulaType type);
|
||||
CellFormulaPrivate(const CellFormulaPrivate &other);
|
||||
~CellFormulaPrivate();
|
||||
|
||||
QString formula; //formula contents
|
||||
CellFormula::FormulaType type;
|
||||
CellRange reference;
|
||||
int si;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE_XLSX
|
||||
|
||||
#endif // XLSXCELLFORMULA_P_H
|
||||
+73
-177
@@ -39,6 +39,8 @@
|
||||
#include "xlsxconditionalformatting_p.h"
|
||||
#include "xlsxdrawinganchor_p.h"
|
||||
#include "xlsxchart.h"
|
||||
#include "xlsxcellformula.h"
|
||||
#include "xlsxcellformula_p.h"
|
||||
|
||||
#include <QVariant>
|
||||
#include <QDateTime>
|
||||
@@ -208,7 +210,7 @@ Worksheet *Worksheet::copy(const QString &distName, int distId) const
|
||||
QSharedPointer<Cell> cell(new Cell(it2.value().data()));
|
||||
cell->d_ptr->parent = sheet;
|
||||
|
||||
if (cell->dataType() == Cell::String)
|
||||
if (cell->cellType() == Cell::SharedStringType)
|
||||
d->workbook->sharedStrings()->addSharedString(cell->d_ptr->richString);
|
||||
|
||||
sheet_d->cellTable[row][col] = cell;
|
||||
@@ -437,10 +439,7 @@ bool Worksheet::write(int row, int column, const QVariant &value, const Format &
|
||||
|
||||
if (token.startsWith(QLatin1String("="))) {
|
||||
//convert to formula
|
||||
ret = writeFormula(row, column, token, format);
|
||||
} else if (token.startsWith(QLatin1String("{=")) && token.endsWith(QLatin1Char('}'))) {
|
||||
//convert to array formula
|
||||
ret = writeArrayFormula(CellRange(row, column, row, column), token, format);
|
||||
ret = writeFormula(row, column, CellFormula(token), format);
|
||||
} else if (d->workbook->isStringsToHyperlinksEnabled() && token.contains(d->urlPattern)) {
|
||||
//convert to url
|
||||
ret = writeHyperlink(row, column, QUrl(token));
|
||||
@@ -513,8 +512,8 @@ QVariant Worksheet::read(int row, int column) const
|
||||
Cell *cell = cellAt(row, column);
|
||||
if (!cell)
|
||||
return QVariant();
|
||||
if (!cell->formula().isEmpty())
|
||||
return QVariant(QLatin1String("=")+cell->formula());
|
||||
if (cell->hasFormula() && cell->formula().formulaType() == CellFormula::NormalType)
|
||||
return QVariant(QLatin1String("=")+cell->formula().formulaContent());
|
||||
if (cell->isDateTime()) {
|
||||
double val = cell->value().toDouble();
|
||||
QDateTime dt = cell->dateTime();
|
||||
@@ -596,7 +595,7 @@ bool Worksheet::writeString(int row, int column, const RichString &value, const
|
||||
if (value.fragmentCount() == 1 && value.fragmentFormat(0).isValid())
|
||||
fmt.mergeFormat(value.fragmentFormat(0));
|
||||
d->workbook->styles()->addXfFormat(fmt);
|
||||
QSharedPointer<Cell> cell = QSharedPointer<Cell>(new Cell(value.toPlainString(), Cell::String, fmt, this));
|
||||
QSharedPointer<Cell> cell = QSharedPointer<Cell>(new Cell(value.toPlainString(), Cell::SharedStringType, fmt, this));
|
||||
cell->d_ptr->richString = value;
|
||||
d->cellTable[row][column] = cell;
|
||||
return true;
|
||||
@@ -664,7 +663,7 @@ bool Worksheet::writeInlineString(int row, int column, const QString &value, con
|
||||
|
||||
Format fmt = format.isValid() ? format : d->cellFormat(row, column);
|
||||
d->workbook->styles()->addXfFormat(fmt);
|
||||
d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(value, Cell::InlineString, fmt, this));
|
||||
d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(value, Cell::InlineStringType, fmt, this));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -691,7 +690,7 @@ bool Worksheet::writeNumeric(int row, int column, double value, const Format &fo
|
||||
|
||||
Format fmt = format.isValid() ? format : d->cellFormat(row, column);
|
||||
d->workbook->styles()->addXfFormat(fmt);
|
||||
d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(value, Cell::Numeric, fmt, this));
|
||||
d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(value, Cell::NumberType, fmt, this));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -699,7 +698,7 @@ bool Worksheet::writeNumeric(int row, int column, double value, const Format &fo
|
||||
\overload
|
||||
Write \a formula to the cell \a row_column with the \a format and \a result.
|
||||
*/
|
||||
bool Worksheet::writeFormula(const CellReference &row_column, const QString &formula, const Format &format, double result)
|
||||
bool Worksheet::writeFormula(const CellReference &row_column, const CellFormula &formula, const Format &format, double result)
|
||||
{
|
||||
if (!row_column.isValid())
|
||||
return false;
|
||||
@@ -710,58 +709,18 @@ bool Worksheet::writeFormula(const CellReference &row_column, const QString &for
|
||||
/*!
|
||||
Write \a formula to the cell (\a row, \a column) with the \a format and \a result.
|
||||
*/
|
||||
bool Worksheet::writeFormula(int row, int column, const QString &formula, const Format &format, double result)
|
||||
bool Worksheet::writeFormula(int row, int column, const CellFormula &formula, const Format &format, double result)
|
||||
{
|
||||
Q_D(Worksheet);
|
||||
QString _formula = formula;
|
||||
if (d->checkDimensions(row, column))
|
||||
return false;
|
||||
|
||||
//Remove the formula '=' sign if exists
|
||||
if (_formula.startsWith(QLatin1String("=")))
|
||||
_formula.remove(0,1);
|
||||
|
||||
Format fmt = format.isValid() ? format : d->cellFormat(row, column);
|
||||
d->workbook->styles()->addXfFormat(fmt);
|
||||
Cell *data = new Cell(result, Cell::Formula, fmt, this);
|
||||
data->d_ptr->formula = _formula;
|
||||
d->cellTable[row][column] = QSharedPointer<Cell>(data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
Write \a formula to the \a range with the \a format
|
||||
*/
|
||||
bool Worksheet::writeArrayFormula(const CellRange &range, const QString &formula, const Format &format)
|
||||
{
|
||||
Q_D(Worksheet);
|
||||
|
||||
if (d->checkDimensions(range.firstRow(), range.firstColumn()))
|
||||
return false;
|
||||
if (d->checkDimensions(range.lastRow(), range.lastColumn()))
|
||||
return false;
|
||||
QString _formula = formula;
|
||||
//Remove the formula "{=" and "}" sign if exists
|
||||
if (_formula.startsWith(QLatin1String("{=")))
|
||||
_formula.remove(0,2);
|
||||
if (_formula.endsWith(QLatin1Char('}')))
|
||||
_formula.chop(1);
|
||||
|
||||
for (int row=range.firstRow(); row<=range.lastRow(); ++row) {
|
||||
for (int column=range.firstColumn(); column<=range.lastColumn(); ++column) {
|
||||
Format _format = format.isValid() ? format : d->cellFormat(row, column);
|
||||
d->workbook->styles()->addXfFormat(_format);
|
||||
if (row == range.firstRow() && column == range.firstColumn()) {
|
||||
QSharedPointer<Cell> data(new Cell(0, Cell::ArrayFormula, _format, this));
|
||||
data->d_ptr->formula = _formula;
|
||||
data->d_ptr->range = range;
|
||||
QSharedPointer<Cell> data = QSharedPointer<Cell>(new Cell(result, Cell::NumberType, fmt, this));
|
||||
data->d_ptr->formula = formula;
|
||||
d->cellTable[row][column] = data;
|
||||
} else {
|
||||
d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(0, Cell::Numeric, _format, this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -790,7 +749,8 @@ bool Worksheet::writeBlank(int row, int column, const Format &format)
|
||||
Format fmt = format.isValid() ? format : d->cellFormat(row, column);
|
||||
d->workbook->styles()->addXfFormat(fmt);
|
||||
|
||||
d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(QVariant(), Cell::Blank, fmt, this));
|
||||
//Note: NumberType with an invalid QVariant value means blank.
|
||||
d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(QVariant(), Cell::NumberType, fmt, this));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -817,7 +777,7 @@ bool Worksheet::writeBool(int row, int column, bool value, const Format &format)
|
||||
|
||||
Format fmt = format.isValid() ? format : d->cellFormat(row, column);
|
||||
d->workbook->styles()->addXfFormat(fmt);
|
||||
d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(value, Cell::Boolean, fmt, this));
|
||||
d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(value, Cell::BooleanType, fmt, this));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -849,7 +809,7 @@ bool Worksheet::writeDateTime(int row, int column, const QDateTime &dt, const Fo
|
||||
|
||||
double value = datetimeToNumber(dt, d->workbook->isDate1904());
|
||||
|
||||
d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(value, Cell::Numeric, fmt, this));
|
||||
d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(value, Cell::NumberType, fmt, this));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -880,7 +840,7 @@ bool Worksheet::writeTime(int row, int column, const QTime &t, const Format &for
|
||||
fmt.setNumberFormat(QStringLiteral("hh:mm:ss"));
|
||||
d->workbook->styles()->addXfFormat(fmt);
|
||||
|
||||
d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(timeToNumber(t), Cell::Numeric, fmt, this));
|
||||
d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(timeToNumber(t), Cell::NumberType, fmt, this));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -943,7 +903,7 @@ bool Worksheet::writeHyperlink(int row, int column, const QUrl &url, const Forma
|
||||
|
||||
//Write the hyperlink string as normal string.
|
||||
d->sharedStrings()->addSharedString(displayString);
|
||||
d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(displayString, Cell::String, fmt, this));
|
||||
d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(displayString, Cell::SharedStringType, fmt, this));
|
||||
|
||||
//Store the hyperlink data in a separate table
|
||||
d->urlTable[row][column] = QSharedPointer<XlsxHyperlinkData>(new XlsxHyperlinkData(XlsxHyperlinkData::External, urlString, locationString, QString(), tip));
|
||||
@@ -1275,7 +1235,7 @@ void WorksheetPrivate::saveXmlCellData(QXmlStreamWriter &writer, int row, int co
|
||||
else if (colsInfoHelper.contains(col) && !colsInfoHelper[col]->format.isEmpty())
|
||||
writer.writeAttribute(QStringLiteral("s"), QString::number(colsInfoHelper[col]->format.xfIndex()));
|
||||
|
||||
if (cell->dataType() == Cell::String) {
|
||||
if (cell->cellType() == Cell::SharedStringType) {
|
||||
int sst_idx;
|
||||
if (cell->isRichString())
|
||||
sst_idx = sharedStrings()->getSharedStringIndex(cell->d_ptr->richString);
|
||||
@@ -1284,7 +1244,7 @@ void WorksheetPrivate::saveXmlCellData(QXmlStreamWriter &writer, int row, int co
|
||||
|
||||
writer.writeAttribute(QStringLiteral("t"), QStringLiteral("s"));
|
||||
writer.writeTextElement(QStringLiteral("v"), QString::number(sst_idx));
|
||||
} else if (cell->dataType() == Cell::InlineString) {
|
||||
} else if (cell->cellType() == Cell::InlineStringType) {
|
||||
writer.writeAttribute(QStringLiteral("t"), QStringLiteral("inlineStr"));
|
||||
writer.writeStartElement(QStringLiteral("is"));
|
||||
if (cell->isRichString()) {
|
||||
@@ -1313,28 +1273,21 @@ void WorksheetPrivate::saveXmlCellData(QXmlStreamWriter &writer, int row, int co
|
||||
writer.writeEndElement(); // t
|
||||
}
|
||||
writer.writeEndElement();//is
|
||||
} else if (cell->dataType() == Cell::Numeric){
|
||||
} else if (cell->cellType() == Cell::NumberType){
|
||||
if (cell->hasFormula())
|
||||
cell->formula().saveToXml(writer);
|
||||
if (cell->value().isValid()) {//note that, invalid value means 'v' is blank
|
||||
double value = cell->value().toDouble();
|
||||
writer.writeTextElement(QStringLiteral("v"), QString::number(value, 'g', 15));
|
||||
} else if (cell->dataType() == Cell::Formula) {
|
||||
bool ok = true;
|
||||
cell->formula().toDouble(&ok);
|
||||
if (!ok) //is string
|
||||
}
|
||||
} else if (cell->cellType() == Cell::StringType) {
|
||||
writer.writeAttribute(QStringLiteral("t"), QStringLiteral("str"));
|
||||
writer.writeTextElement(QStringLiteral("f"), cell->formula());
|
||||
if (cell->hasFormula())
|
||||
cell->formula().saveToXml(writer);
|
||||
writer.writeTextElement(QStringLiteral("v"), cell->value().toString());
|
||||
} else if (cell->dataType() == Cell::ArrayFormula) {
|
||||
writer.writeStartElement(QStringLiteral("f"));
|
||||
writer.writeAttribute(QStringLiteral("t"), QStringLiteral("array"));
|
||||
writer.writeAttribute(QStringLiteral("ref"), cell->d_ptr->range.toString());
|
||||
writer.writeCharacters(cell->formula());
|
||||
writer.writeEndElement(); //f
|
||||
writer.writeTextElement(QStringLiteral("v"), cell->value().toString());
|
||||
} else if (cell->dataType() == Cell::Boolean) {
|
||||
} else if (cell->cellType() == Cell::BooleanType) {
|
||||
writer.writeAttribute(QStringLiteral("t"), QStringLiteral("b"));
|
||||
writer.writeTextElement(QStringLiteral("v"), cell->value().toBool() ? QStringLiteral("1") : QStringLiteral("0"));
|
||||
} else if (cell->dataType() == Cell::Blank) {
|
||||
//Ok, empty here.
|
||||
}
|
||||
writer.writeEndElement(); //c
|
||||
}
|
||||
@@ -1864,55 +1817,13 @@ int WorksheetPrivate::colPixelsSize(int col) const
|
||||
return pixels;
|
||||
}
|
||||
|
||||
QSharedPointer<Cell> WorksheetPrivate::loadXmlNumericCellData(QXmlStreamReader &reader)
|
||||
{
|
||||
Q_ASSERT(reader.name() == QLatin1String("c"));
|
||||
|
||||
QString v_str;
|
||||
QString f_str;
|
||||
QSharedPointer<Cell> cell;
|
||||
while (!reader.atEnd() && !(reader.name() == QLatin1String("c") && reader.tokenType() == QXmlStreamReader::EndElement)) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("v")) {
|
||||
v_str = reader.readElementText();
|
||||
} else if (reader.name() == QLatin1String("f")) {
|
||||
QXmlStreamAttributes fAttrs = reader.attributes();
|
||||
if (fAttrs.hasAttribute(QLatin1String("array"))) {
|
||||
cell = QSharedPointer<Cell>(new Cell(0, Cell::ArrayFormula));
|
||||
cell->d_ptr->range = CellRange(fAttrs.value(QLatin1String("ref")).toString());
|
||||
} else {
|
||||
cell = QSharedPointer<Cell>(new Cell(0, Cell::Formula));
|
||||
}
|
||||
f_str = reader.readElementText();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (v_str.isEmpty() && f_str.isEmpty()) {
|
||||
//blank type
|
||||
return QSharedPointer<Cell>(new Cell(QVariant(), Cell::Blank));
|
||||
} else if (f_str.isEmpty()) {
|
||||
//numeric type
|
||||
return QSharedPointer<Cell>(new Cell(v_str.toDouble(), Cell::Numeric));
|
||||
} else {
|
||||
//formula type
|
||||
cell->d_ptr->value = v_str.toDouble();
|
||||
cell->d_ptr->formula = f_str;
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
void WorksheetPrivate::loadXmlSheetData(QXmlStreamReader &reader)
|
||||
{
|
||||
Q_Q(Worksheet);
|
||||
Q_ASSERT(reader.name() == QLatin1String("sheetData"));
|
||||
|
||||
while (!reader.atEnd() && !(reader.name() == QLatin1String("sheetData") && reader.tokenType() == QXmlStreamReader::EndElement)) {
|
||||
reader.readNextStartElement();
|
||||
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
if (reader.readNextStartElement()) {
|
||||
if (reader.name() == QLatin1String("row")) {
|
||||
QXmlStreamAttributes attributes = reader.attributes();
|
||||
|
||||
@@ -1964,78 +1875,63 @@ void WorksheetPrivate::loadXmlSheetData(QXmlStreamReader &reader)
|
||||
qDebug()<<QStringLiteral("<c s=\"%1\">Invalid style index: ").arg(idx)<<idx;
|
||||
}
|
||||
|
||||
if (attributes.hasAttribute(QLatin1String("t"))) { // "t" == cell data type
|
||||
QString type = attributes.value(QLatin1String("t")).toString();
|
||||
if (type == QLatin1String("s")) {
|
||||
//string type
|
||||
Cell::CellType cellType = Cell::NumberType;
|
||||
if (attributes.hasAttribute(QLatin1String("t"))) {
|
||||
QString typeString = attributes.value(QLatin1String("t")).toString();
|
||||
if (typeString == QLatin1String("s"))
|
||||
cellType = Cell::SharedStringType;
|
||||
else if (typeString == QLatin1String("inlineStr"))
|
||||
cellType = Cell::InlineStringType;
|
||||
else if (typeString == QLatin1String("str"))
|
||||
cellType = Cell::StringType;
|
||||
else if (typeString == QLatin1String("b"))
|
||||
cellType = Cell::BooleanType;
|
||||
else if (typeString == QLatin1String("e"))
|
||||
cellType = Cell::ErrorType;
|
||||
else
|
||||
cellType = Cell::NumberType;
|
||||
}
|
||||
|
||||
QSharedPointer<Cell> cell(new Cell(QVariant() ,cellType, format, q));
|
||||
while (!reader.atEnd() && !(reader.name() == QLatin1String("c") && reader.tokenType() == QXmlStreamReader::EndElement)) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.name() == QLatin1String("v")) {
|
||||
int sst_idx = reader.readElementText().toInt();
|
||||
if (reader.readNextStartElement()) {
|
||||
if (reader.name() == QLatin1String("f")) {
|
||||
cell->d_func()->formula.loadFromXml(reader);
|
||||
} else if (reader.name() == QLatin1String("v")) {
|
||||
QString value = reader.readElementText();
|
||||
if (cellType == Cell::SharedStringType) {
|
||||
int sst_idx = value.toInt();
|
||||
sharedStrings()->incRefByStringIndex(sst_idx);
|
||||
RichString rs = sharedStrings()->getSharedString(sst_idx);
|
||||
QSharedPointer<Cell> data(new Cell(rs.toPlainString() ,Cell::String, format, q));
|
||||
cell->d_func()->value = rs.toPlainString();
|
||||
if (rs.isRichString())
|
||||
data->d_ptr->richString = rs;
|
||||
cellTable[pos.row()][pos.column()] = QSharedPointer<Cell>(data);
|
||||
cell->d_func()->richString = rs;
|
||||
} else if (cellType == Cell::NumberType) {
|
||||
cell->d_func()->value = value.toDouble();
|
||||
} else if (cellType == Cell::BooleanType) {
|
||||
cell->d_func()->value = value.toInt() ? true : false;
|
||||
} else { //Cell::ErrorType and Cell::StringType
|
||||
cell->d_func()->value = value;
|
||||
}
|
||||
}
|
||||
} else if (type == QLatin1String("inlineStr")) {
|
||||
//inline string type
|
||||
while (!reader.atEnd() && !(reader.name() == QLatin1String("c") && reader.tokenType() == QXmlStreamReader::EndElement)) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
} else if (reader.name() == QLatin1String("is")) {
|
||||
while (!reader.atEnd() && !(reader.name() == QLatin1String("is") && reader.tokenType() == QXmlStreamReader::EndElement)) {
|
||||
if (reader.readNextStartElement()) {
|
||||
//:Todo, add rich text read support
|
||||
if (reader.name() == QLatin1String("t")) {
|
||||
QString value = reader.readElementText();
|
||||
QSharedPointer<Cell> data(new Cell(value, Cell::InlineString, format, q));
|
||||
cellTable[pos.row()][pos.column()] = data;
|
||||
cell->d_func()->value = reader.readElementText();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (type == QLatin1String("b")) {
|
||||
//bool type
|
||||
} else if (reader.name() == QLatin1String("extLst")) {
|
||||
//skip extLst element
|
||||
while (!reader.atEnd() && !(reader.name() == QLatin1String("extLst")
|
||||
&& reader.tokenType() == QXmlStreamReader::EndElement)) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.name() == QLatin1String("v")) {
|
||||
QString value = reader.readElementText();
|
||||
QSharedPointer<Cell> data(new Cell(value.toInt() ? true : false, Cell::Boolean, format, q));
|
||||
cellTable[pos.row()][pos.column()] = data;
|
||||
}
|
||||
} else if (type == QLatin1String("str")) {
|
||||
//formula type
|
||||
QSharedPointer<Cell> data = loadXmlNumericCellData(reader);
|
||||
data->d_ptr->format = format;
|
||||
data->d_ptr->parent = q;
|
||||
cellTable[pos.row()][pos.column()] = data;
|
||||
} else if (type == QLatin1String("e")) {
|
||||
//error type, such as #DIV/0! #NULL! #REF! etc
|
||||
QString v_str, f_str;
|
||||
while (!reader.atEnd() && !(reader.name() == QLatin1String("c") && reader.tokenType() == QXmlStreamReader::EndElement)) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||
if (reader.name() == QLatin1String("v"))
|
||||
v_str = reader.readElementText();
|
||||
else if (reader.name() == QLatin1String("f"))
|
||||
f_str = reader.readElementText();
|
||||
}
|
||||
}
|
||||
QSharedPointer<Cell> data(new Cell(v_str, Cell::Error, format, q));
|
||||
if (!f_str.isEmpty())
|
||||
data->d_ptr->formula = f_str;
|
||||
cellTable[pos.row()][pos.column()] = data;
|
||||
} else if (type == QLatin1String("n")) {
|
||||
QSharedPointer<Cell> data = loadXmlNumericCellData(reader);
|
||||
data->d_ptr->format = format;
|
||||
data->d_ptr->parent = q;
|
||||
cellTable[pos.row()][pos.column()] = data;
|
||||
}
|
||||
} else {
|
||||
//default is "n"
|
||||
QSharedPointer<Cell> data = loadXmlNumericCellData(reader);
|
||||
data->d_ptr->format = format;
|
||||
data->d_ptr->parent = q;
|
||||
cellTable[pos.row()][pos.column()] = data;
|
||||
}
|
||||
cellTable[pos.row()][pos.column()] = cell;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,9 +69,8 @@ public:
|
||||
bool writeInlineString(int row, int column, const QString &value, const Format &format=Format());
|
||||
bool writeNumeric(const CellReference &row_column, double value, const Format &format=Format());
|
||||
bool writeNumeric(int row, int column, double value, const Format &format=Format());
|
||||
bool writeFormula(const CellReference &row_column, const QString &formula, const Format &format=Format(), double result=0);
|
||||
bool writeFormula(int row, int column, const QString &formula, const Format &format=Format(), double result=0);
|
||||
bool writeArrayFormula(const CellRange &range, const QString &formula, const Format &format=Format());
|
||||
bool writeFormula(const CellReference &row_column, const CellFormula &formula, const Format &format=Format(), double result=0);
|
||||
bool writeFormula(int row, int column, const CellFormula &formula, const Format &format=Format(), double result=0);
|
||||
bool writeBlank(const CellReference &row_column, const Format &format=Format());
|
||||
bool writeBlank(int row, int column, const Format &format=Format());
|
||||
bool writeBool(const CellReference &row_column, bool value, const Format &format=Format());
|
||||
|
||||
@@ -169,7 +169,6 @@ public:
|
||||
int rowPixelsSize(int row) const;
|
||||
int colPixelsSize(int col) const;
|
||||
|
||||
QSharedPointer<Cell> loadXmlNumericCellData(QXmlStreamReader &reader);
|
||||
void loadXmlSheetData(QXmlStreamReader &reader);
|
||||
void loadXmlColumnsInfo(QXmlStreamReader &reader);
|
||||
void loadXmlMergeCells(QXmlStreamReader &reader);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "xlsxdocument.h"
|
||||
#include "xlsxcell.h"
|
||||
#include "xlsxformat.h"
|
||||
#include "xlsxcellformula.h"
|
||||
#include <QString>
|
||||
#include <QtTest>
|
||||
|
||||
@@ -69,9 +70,9 @@ void DocumentTest::testReadWriteString()
|
||||
|
||||
device.open(QIODevice::ReadOnly);
|
||||
Document xlsx2(&device);
|
||||
QCOMPARE(xlsx2.cellAt("A1")->dataType(), Cell::String);
|
||||
QCOMPARE(xlsx2.cellAt("A1")->cellType(), Cell::SharedStringType);
|
||||
QCOMPARE(xlsx2.cellAt("A1")->value().toString(), QString("Hello Qt!"));
|
||||
QCOMPARE(xlsx2.cellAt("A2")->dataType(), Cell::String);
|
||||
QCOMPARE(xlsx2.cellAt("A2")->cellType(), Cell::SharedStringType);
|
||||
QCOMPARE(xlsx2.cellAt("A2")->value().toString(), QString("Hello Qt again!"));
|
||||
Format format2 = xlsx2.cellAt("A2")->format();
|
||||
QVERIFY(format2.isValid());
|
||||
@@ -79,7 +80,7 @@ void DocumentTest::testReadWriteString()
|
||||
// qDebug()<<format;
|
||||
QCOMPARE(format2, format);
|
||||
|
||||
QCOMPARE(xlsx2.cellAt("A3")->dataType(), Cell::String);
|
||||
QCOMPARE(xlsx2.cellAt("A3")->cellType(), Cell::SharedStringType);
|
||||
QCOMPARE(xlsx2.cellAt("A3")->value().toString(), QString("12345"));
|
||||
}
|
||||
|
||||
@@ -100,9 +101,9 @@ void DocumentTest::testReadWriteNumeric()
|
||||
|
||||
device.open(QIODevice::ReadOnly);
|
||||
Document xlsx2(&device);
|
||||
QCOMPARE(xlsx2.cellAt("A1")->dataType(), Cell::Numeric);
|
||||
QCOMPARE(xlsx2.cellAt("A1")->cellType(), Cell::NumberType);
|
||||
QCOMPARE(xlsx2.cellAt("A1")->value().toDouble(), 123.0);
|
||||
QCOMPARE(xlsx2.cellAt("A2")->dataType(), Cell::Numeric);
|
||||
QCOMPARE(xlsx2.cellAt("A2")->cellType(), Cell::NumberType);
|
||||
QCOMPARE(xlsx2.cellAt("A2")->value().toDouble(), 12345.0);
|
||||
QVERIFY(xlsx2.cellAt("A2")->format().isValid());
|
||||
QCOMPARE(xlsx2.cellAt("A2")->format(), format);
|
||||
@@ -124,9 +125,9 @@ void DocumentTest::testReadWriteBool()
|
||||
|
||||
device.open(QIODevice::ReadOnly);
|
||||
Document xlsx2(&device);
|
||||
QCOMPARE(xlsx2.cellAt("A1")->dataType(), Cell::Boolean);
|
||||
QCOMPARE(xlsx2.cellAt("A1")->cellType(), Cell::BooleanType);
|
||||
QCOMPARE(xlsx2.cellAt("A1")->value().toBool(), true);
|
||||
QCOMPARE(xlsx2.cellAt("A2")->dataType(), Cell::Boolean);
|
||||
QCOMPARE(xlsx2.cellAt("A2")->cellType(), Cell::BooleanType);
|
||||
QCOMPARE(xlsx2.cellAt("A2")->value().toBool(), false);
|
||||
QVERIFY(xlsx2.cellAt("A2")->format().isValid());
|
||||
QCOMPARE(xlsx2.cellAt("A2")->format(), format);
|
||||
@@ -149,10 +150,10 @@ void DocumentTest::testReadWriteBlank()
|
||||
device.open(QIODevice::ReadOnly);
|
||||
Document xlsx2(&device);
|
||||
QVERIFY(xlsx2.cellAt("A1"));
|
||||
QCOMPARE(xlsx2.cellAt("A1")->dataType(), Cell::Blank);
|
||||
QCOMPARE(xlsx2.cellAt("A1")->cellType(), Cell::NumberType);
|
||||
QVERIFY(!xlsx2.cellAt("A1")->value().isValid());
|
||||
QVERIFY(xlsx2.cellAt("A2"));
|
||||
QCOMPARE(xlsx2.cellAt("A2")->dataType(), Cell::Blank);
|
||||
QCOMPARE(xlsx2.cellAt("A2")->cellType(), Cell::NumberType);
|
||||
QVERIFY(!xlsx2.cellAt("A2")->value().isValid());
|
||||
QVERIFY(xlsx2.cellAt("A2")->format().isValid());
|
||||
QCOMPARE(xlsx2.cellAt("A2")->format(), format);
|
||||
@@ -175,12 +176,11 @@ void DocumentTest::testReadWriteFormula()
|
||||
|
||||
device.open(QIODevice::ReadOnly);
|
||||
Document xlsx2(&device);
|
||||
QCOMPARE(xlsx2.cellAt("A1")->dataType(), Cell::Formula);
|
||||
// QCOMPARE(xlsx2.cellAt("A1")->value().toDouble(), 0.0);
|
||||
QCOMPARE(xlsx2.cellAt("A1")->formula(), QStringLiteral("11+22"));
|
||||
QCOMPARE(xlsx2.cellAt("A2")->dataType(), Cell::Formula);
|
||||
// QCOMPARE(xlsx2.cellAt("A2")->value().toDouble(), 0.0);
|
||||
QCOMPARE(xlsx2.cellAt("A2")->formula(), QStringLiteral("22+33"));
|
||||
QCOMPARE(xlsx2.cellAt("A1")->cellType(), Cell::NumberType);
|
||||
QVERIFY(xlsx2.cellAt("A1")->hasFormula());
|
||||
QCOMPARE(xlsx2.cellAt("A1")->formula(), CellFormula("11+22"));
|
||||
QCOMPARE(xlsx2.cellAt("A2")->cellType(), Cell::NumberType);
|
||||
QCOMPARE(xlsx2.cellAt("A2")->formula(), CellFormula("22+33"));
|
||||
QVERIFY(xlsx2.cellAt("A2")->format().isValid());
|
||||
QCOMPARE(xlsx2.cellAt("A2")->format(), format);
|
||||
}
|
||||
@@ -211,17 +211,17 @@ void DocumentTest::testReadWriteDateTime()
|
||||
|
||||
device.open(QIODevice::ReadOnly);
|
||||
Document xlsx2(&device);
|
||||
QCOMPARE(xlsx2.cellAt("A1")->dataType(), Cell::Numeric);
|
||||
QCOMPARE(xlsx2.cellAt("A1")->cellType(), Cell::NumberType);
|
||||
QCOMPARE(xlsx2.cellAt("A1")->isDateTime(), true);
|
||||
QCOMPARE(xlsx2.cellAt("A1")->dateTime(), dt);
|
||||
QVERIFY(xlsx2.read("A1").userType() == QMetaType::QDateTime);
|
||||
|
||||
QCOMPARE(xlsx2.cellAt("A2")->dataType(), Cell::Numeric);
|
||||
QCOMPARE(xlsx2.cellAt("A2")->cellType(), Cell::NumberType);
|
||||
QCOMPARE(xlsx2.cellAt("A2")->isDateTime(), true);
|
||||
QCOMPARE(xlsx2.cellAt("A2")->dateTime(), dt);
|
||||
QVERIFY(xlsx2.read("A2").userType() == QMetaType::QDateTime);
|
||||
|
||||
QCOMPARE(xlsx2.cellAt("A3")->dataType(), Cell::Numeric);
|
||||
QCOMPARE(xlsx2.cellAt("A3")->cellType(), Cell::NumberType);
|
||||
QVERIFY(xlsx2.cellAt("A3")->format().isValid());
|
||||
QCOMPARE(xlsx2.cellAt("A3")->isDateTime(), true);
|
||||
QCOMPARE(xlsx2.cellAt("A3")->dateTime(), dt);
|
||||
@@ -259,16 +259,16 @@ void DocumentTest::testReadWriteDate()
|
||||
|
||||
device.open(QIODevice::ReadOnly);
|
||||
Document xlsx2(&device);
|
||||
QCOMPARE(xlsx2.cellAt("A1")->dataType(), Cell::Numeric);
|
||||
QCOMPARE(xlsx2.cellAt("A1")->cellType(), Cell::NumberType);
|
||||
QCOMPARE(xlsx2.cellAt("A1")->isDateTime(), true);
|
||||
QVERIFY(xlsx2.read("A1").userType() == QMetaType::QDate);
|
||||
QCOMPARE(xlsx2.read("A1").toDate(), d);
|
||||
|
||||
QCOMPARE(xlsx2.cellAt("A2")->dataType(), Cell::Numeric);
|
||||
QCOMPARE(xlsx2.cellAt("A2")->cellType(), Cell::NumberType);
|
||||
QCOMPARE(xlsx2.cellAt("A2")->isDateTime(), true);
|
||||
QVERIFY(xlsx2.read("A2").userType() == QMetaType::QDate);
|
||||
|
||||
QCOMPARE(xlsx2.cellAt("A3")->dataType(), Cell::Numeric);
|
||||
QCOMPARE(xlsx2.cellAt("A3")->cellType(), Cell::NumberType);
|
||||
QVERIFY(xlsx2.cellAt("A3")->format().isValid());
|
||||
QCOMPARE(xlsx2.cellAt("A3")->isDateTime(), true);
|
||||
QCOMPARE(xlsx2.cellAt("A3")->format().numberFormat(), QString("dd/mm/yyyy"));
|
||||
@@ -297,9 +297,10 @@ void DocumentTest::testReadWriteTime()
|
||||
device.open(QIODevice::ReadOnly);
|
||||
Document xlsx2(&device);
|
||||
|
||||
QCOMPARE(xlsx2.cellAt("A1")->dataType(), Cell::Blank);
|
||||
QCOMPARE(xlsx2.cellAt("A1")->cellType(), Cell::NumberType);
|
||||
QVERIFY(!xlsx2.cellAt("A1")->value().isValid());
|
||||
|
||||
QCOMPARE(xlsx2.cellAt("A2")->dataType(), Cell::Numeric);
|
||||
QCOMPARE(xlsx2.cellAt("A2")->cellType(), Cell::NumberType);
|
||||
QCOMPARE(xlsx2.cellAt("A2")->isDateTime(), true);
|
||||
QVERIFY(xlsx2.read("A2").userType() == QMetaType::QTime);
|
||||
QCOMPARE(xlsx2.read("A2").toTime(), QTime(1, 22));
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "private/xlsxworksheet_p.h"
|
||||
#include "private/xlsxsharedstrings_p.h"
|
||||
#include "xlsxrichstring.h"
|
||||
#include "xlsxcellformula.h"
|
||||
|
||||
class WorksheetTest : public QObject
|
||||
{
|
||||
@@ -114,8 +115,8 @@ void WorksheetTest::testWriteCells()
|
||||
QVERIFY2(xmldata.contains("<c r=\"A2\" t=\"s\"><v>0</v></c>"), "string");
|
||||
QVERIFY2(xmldata.contains("<c r=\"A3\" t=\"inlineStr\"><is><t>Hello inline</t></is></c>"), "inline string");
|
||||
QVERIFY2(xmldata.contains("<c r=\"A4\" t=\"b\"><v>1</v></c>"), "boolean");
|
||||
QVERIFY2(xmldata.contains("<c r=\"A5\" t=\"str\"><f>44+33</f><v>0</v></c>"), "formula");
|
||||
QVERIFY2(xmldata.contains("<c r=\"B5\" t=\"str\"><f>44+33</f><v>77</v></c>"), "formula");
|
||||
QVERIFY2(xmldata.contains("<c r=\"A5\"><f>44+33</f><v>0</v></c>"), "formula");
|
||||
QVERIFY2(xmldata.contains("<c r=\"B5\"><f>44+33</f><v>77</v></c>"), "formula");
|
||||
|
||||
QCOMPARE(sheet.d_func()->sharedStrings()->getSharedString(0).toPlainString(), QStringLiteral("Hello"));
|
||||
}
|
||||
@@ -204,29 +205,29 @@ void WorksheetTest::testReadSheetData()
|
||||
QCOMPARE(sheet.d_func()->cellTable.size(), 2);
|
||||
|
||||
//A1
|
||||
QCOMPARE(sheet.cellAt("A1")->dataType(), QXlsx::Cell::String);
|
||||
QCOMPARE(sheet.cellAt("A1")->cellType(), QXlsx::Cell::SharedStringType);
|
||||
QCOMPARE(sheet.cellAt("A1")->value().toString(), QStringLiteral("Hello"));
|
||||
|
||||
//B1
|
||||
QCOMPARE(sheet.cellAt("B1")->dataType(), QXlsx::Cell::Formula);
|
||||
QCOMPARE(sheet.cellAt("B1")->cellType(), QXlsx::Cell::NumberType);
|
||||
QCOMPARE(sheet.cellAt("B1")->value().toInt(), 77);
|
||||
QCOMPARE(sheet.cellAt("B1")->formula(), QStringLiteral("44+33"));
|
||||
QCOMPARE(sheet.cellAt("B1")->formula(), QXlsx::CellFormula("44+33"));
|
||||
|
||||
//C1
|
||||
QCOMPARE(sheet.cellAt("C1")->dataType(), QXlsx::Cell::Formula);
|
||||
QCOMPARE(sheet.cellAt("C1")->cellType(), QXlsx::Cell::StringType);
|
||||
QCOMPARE(sheet.cellAt("C1")->value().toInt(), 77);
|
||||
QCOMPARE(sheet.cellAt("C1")->formula(), QStringLiteral("44+33"));
|
||||
QCOMPARE(sheet.cellAt("C1")->formula(), QXlsx::CellFormula("44+33"));
|
||||
|
||||
//B3
|
||||
QCOMPARE(sheet.cellAt("B3")->dataType(), QXlsx::Cell::Numeric);
|
||||
QCOMPARE(sheet.cellAt("B3")->cellType(), QXlsx::Cell::NumberType);
|
||||
QCOMPARE(sheet.cellAt("B3")->value().toInt(), 12345);
|
||||
|
||||
//C3
|
||||
QCOMPARE(sheet.cellAt("C3")->dataType(), QXlsx::Cell::InlineString);
|
||||
QCOMPARE(sheet.cellAt("C3")->cellType(), QXlsx::Cell::InlineStringType);
|
||||
QCOMPARE(sheet.cellAt("C3")->value().toString(), QStringLiteral("inline test string"));
|
||||
|
||||
//E3
|
||||
QCOMPARE(sheet.cellAt("E3")->dataType(), QXlsx::Cell::Error);
|
||||
QCOMPARE(sheet.cellAt("E3")->cellType(), QXlsx::Cell::ErrorType);
|
||||
QCOMPARE(sheet.cellAt("E3")->value().toString(), QStringLiteral("#DIV/0!"));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user