From e2752e4da865d8a0528d360b70acf5a59154441f Mon Sep 17 00:00:00 2001 From: Debao Zhang Date: Tue, 14 Jan 2014 10:24:03 +0800 Subject: [PATCH] Don't do too smart thing for Worksheet::write() Implictly convert QString to other types is danger. Such as QVariant("12345").toTime() will generate a valid QTime Object. --- src/xlsx/xlsxworksheet.cpp | 46 +++++++++++++++--------- tests/auto/document/tst_documenttest.cpp | 29 +++++++++------ 2 files changed, 48 insertions(+), 27 deletions(-) diff --git a/src/xlsx/xlsxworksheet.cpp b/src/xlsx/xlsxworksheet.cpp index c5a7c67..47694b5 100755 --- a/src/xlsx/xlsxworksheet.cpp +++ b/src/xlsx/xlsxworksheet.cpp @@ -467,45 +467,59 @@ QList > Worksheet::drawingLinks() const int Worksheet::write(int row, int column, const QVariant &value, const Format &format) { Q_D(Worksheet); - bool ok; int ret = 0; if (d->checkDimensions(row, column)) return -1; - if (value.isNull()) { //blank + if (value.isNull()) { + //Blank ret = writeBlank(row, column, format); } else if (value.userType() == qMetaTypeId()) { ret = writeString(row, column, value.value(), format); - } else if (value.userType() == QMetaType::Bool) { //Bool + } else if (value.userType() == QMetaType::Bool) { + //Bool ret = writeBool(row,column, value.toBool(), format); - } else if (value.toDateTime().isValid()) { //DateTime + } else if (value.userType() == QMetaType::QDateTime || value.userType() == QMetaType::QDate) { + //DateTime, Date + // note that, QTime cann't convert to QDateTime ret = writeDateTime(row, column, value.toDateTime(), format); - } else if (value.toTime().isValid()) { //Time + } else if (value.userType() == QMetaType::QTime) { + //Time ret = writeTime(row, column, value.toTime(), format); - } else if (value.toDouble(&ok), ok) { //Number - if (!d->workbook->isStringsToNumbersEnabled() && value.userType() == QMetaType::QString) { - //Don't convert string to number if the flag not enabled. - ret = writeString(row, column, value.toString(), format); - } else { - ret = writeNumeric(row, column, value.toDouble(), format); - } - } else if (value.userType() == QMetaType::QUrl) { //url + } else if (value.userType() == QMetaType::Int || value.userType() == QMetaType::UInt + || value.userType() == QMetaType::LongLong || value.userType() == QMetaType::ULongLong + || value.userType() == QMetaType::Double || value.userType() == QMetaType::Float) { + //Number + + ret = writeNumeric(row, column, value.toDouble(), format); + } else if (value.userType() == QMetaType::QUrl) { + //Url ret = writeHyperlink(row, column, value.toUrl(), format); - } else if (value.userType() == QMetaType::QString) { //string + } else if (value.userType() == QMetaType::QString) { + //String QString token = value.toString(); + bool ok; QRegularExpression urlPattern(QStringLiteral("^([fh]tt?ps?://)|(mailto:)|(file://)")); + 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); } else if (token.contains(urlPattern)) { + //convert to url ret = writeHyperlink(row, column, QUrl(token)); + } else if (d->workbook->isStringsToNumbersEnabled() && (value.toDouble(&ok), ok)) { + //Try convert string to number if the flag enabled. + ret = writeString(row, column, value.toString(), format); } else { + //normal string now ret = writeString(row, column, token, format); } - } else { //Wrong type - + } else { + //Wrong type return -1; } diff --git a/tests/auto/document/tst_documenttest.cpp b/tests/auto/document/tst_documenttest.cpp index f83436c..6de637e 100644 --- a/tests/auto/document/tst_documenttest.cpp +++ b/tests/auto/document/tst_documenttest.cpp @@ -56,11 +56,15 @@ void DocumentTest::testReadWriteString() Document xlsx1; xlsx1.write("A1", "Hello Qt!"); + Format format; format.setFontColor(Qt::blue); format.setBorderStyle(Format::BorderDashDotDot); format.setFillPattern(Format::PatternSolid); xlsx1.write("A2", "Hello Qt again!", format); + + xlsx1.write("A3", "12345"); + xlsx1.saveAs(&device); device.open(QIODevice::ReadOnly); @@ -74,6 +78,9 @@ void DocumentTest::testReadWriteString() // qDebug()<dataType(), Cell::String); + QCOMPARE(xlsx2.cellAt("A3")->value().toString(), QString("12345")); } void DocumentTest::testReadWriteNumeric() @@ -198,7 +205,7 @@ void DocumentTest::testReadWriteDateTime() format3.setNumberFormat("dd/mm/yyyy"); xlsx1.write("A3", dt, format3); - xlsx1.write("A4", "2013-12-14T12:30"); //Auto convert to QDateTime, by QVariant +// xlsx1.write("A4", "2013-12-14T12:30"); //Auto convert to QDateTime, by QVariant xlsx1.saveAs(&device); @@ -220,10 +227,10 @@ void DocumentTest::testReadWriteDateTime() QCOMPARE(xlsx2.cellAt("A3")->dateTime(), dt); QCOMPARE(xlsx2.cellAt("A3")->format().numberFormat(), QString("dd/mm/yyyy")); - QCOMPARE(xlsx2.cellAt("A4")->dataType(), Cell::Numeric); - QCOMPARE(xlsx2.cellAt("A4")->isDateTime(), true); - QCOMPARE(xlsx2.cellAt("A4")->dateTime(), QDateTime(QDate(2013,12,14), QTime(12, 30))); - QVERIFY(xlsx2.read("A4").userType() == QMetaType::QDateTime); +// QCOMPARE(xlsx2.cellAt("A4")->dataType(), Cell::Numeric); +// QCOMPARE(xlsx2.cellAt("A4")->isDateTime(), true); +// QCOMPARE(xlsx2.cellAt("A4")->dateTime(), QDateTime(QDate(2013,12,14), QTime(12, 30))); +// QVERIFY(xlsx2.read("A4").userType() == QMetaType::QDateTime); } void DocumentTest::testReadWriteDate() @@ -246,7 +253,7 @@ void DocumentTest::testReadWriteDate() format3.setNumberFormat("dd/mm/yyyy"); xlsx1.write("A3", d, format3); - xlsx1.write("A4", "2013-12-14"); //Auto convert to QDateTime, by QVariant +// xlsx1.write("A4", "2013-12-14"); //Auto convert to QDateTime, by QVariant xlsx1.saveAs(&device); @@ -268,11 +275,11 @@ void DocumentTest::testReadWriteDate() QVERIFY(xlsx2.read("A3").userType() == QMetaType::QDate); QCOMPARE(xlsx2.read("A3").toDate(), d); - QCOMPARE(xlsx2.cellAt("A4")->dataType(), Cell::Numeric); - QCOMPARE(xlsx2.cellAt("A4")->isDateTime(), true); - QCOMPARE(xlsx2.cellAt("A4")->dateTime(), QDateTime(QDate(2013,12,14))); - QVERIFY(xlsx2.read("A4").userType() == QMetaType::QDate); - QCOMPARE(xlsx2.read("A4").toDate(), QDate(2013,12,14)); +// QCOMPARE(xlsx2.cellAt("A4")->dataType(), Cell::Numeric); +// QCOMPARE(xlsx2.cellAt("A4")->isDateTime(), true); +// QCOMPARE(xlsx2.cellAt("A4")->dateTime(), QDateTime(QDate(2013,12,14))); +// QVERIFY(xlsx2.read("A4").userType() == QMetaType::QDate); +// QCOMPARE(xlsx2.read("A4").toDate(), QDate(2013,12,14)); } void DocumentTest::testReadWriteTime()