From e232e7eae983c683e462da76cdb8d2bf7a350ccb Mon Sep 17 00:00:00 2001 From: Debao Zhang Date: Fri, 27 Dec 2013 16:29:41 +0800 Subject: [PATCH] Add QTime read write support --- src/xlsx/xlsxutility.cpp | 5 +++ src/xlsx/xlsxutility_p.h | 2 ++ src/xlsx/xlsxworksheet.cpp | 41 ++++++++++++++++++++++++ src/xlsx/xlsxworksheet.h | 3 ++ tests/auto/document/tst_documenttest.cpp | 30 +++++++++++++++++ tests/auto/utility/tst_utilitytest.cpp | 22 +++++++++++++ 6 files changed, 103 insertions(+) diff --git a/src/xlsx/xlsxutility.cpp b/src/xlsx/xlsxutility.cpp index 8ff7511..03f60ab 100755 --- a/src/xlsx/xlsxutility.cpp +++ b/src/xlsx/xlsxutility.cpp @@ -67,6 +67,11 @@ double datetimeToNumber(const QDateTime &dt, bool is1904) return excel_time; } +double timeToNumber(const QTime &time) +{ + return QTime(0,0).msecsTo(time) / (1000*60*60*24.0); +} + QDateTime datetimeFromNumber(double num, bool is1904) { if (!is1904 && num > 60) diff --git a/src/xlsx/xlsxutility_p.h b/src/xlsx/xlsxutility_p.h index 9d77d86..008fb33 100755 --- a/src/xlsx/xlsxutility_p.h +++ b/src/xlsx/xlsxutility_p.h @@ -42,6 +42,7 @@ class QString; class QStringList; class QColor; class QDateTime; +class QTime; namespace QXlsx { @@ -49,6 +50,7 @@ XLSX_AUTOTEST_EXPORT int intPow(int x, int p); XLSX_AUTOTEST_EXPORT QStringList splitPath(const QString &path); XLSX_AUTOTEST_EXPORT double datetimeToNumber(const QDateTime &dt, bool is1904=false); XLSX_AUTOTEST_EXPORT QDateTime datetimeFromNumber(double num, bool is1904=false); +XLSX_AUTOTEST_EXPORT double timeToNumber(const QTime &t); XLSX_AUTOTEST_EXPORT QPoint xl_cell_to_rowcol(const QString &cell_str); XLSX_AUTOTEST_EXPORT QString xl_col_to_name(int col_num); diff --git a/src/xlsx/xlsxworksheet.cpp b/src/xlsx/xlsxworksheet.cpp index 77f4cb2..ae87c2d 100755 --- a/src/xlsx/xlsxworksheet.cpp +++ b/src/xlsx/xlsxworksheet.cpp @@ -444,6 +444,8 @@ int Worksheet::write(int row, int column, const QVariant &value, const Format &f ret = writeBool(row,column, value.toBool(), format); } else if (value.toDateTime().isValid()) { //DateTime ret = writeDateTime(row, column, value.toDateTime(), format); + } else if (value.toTime().isValid()) { //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. @@ -509,6 +511,13 @@ QVariant Worksheet::read(int row, int column) const return QVariant(); if (!cell->formula().isEmpty()) return QVariant(QLatin1String("=")+cell->formula()); + if (cell->isDateTime()) { + double val = cell->value().toDouble(); + QDateTime dt = cell->dateTime(); + if (val < 1) + return dt.time(); + return dt; + } return cell->value(); } @@ -851,6 +860,38 @@ int Worksheet::writeDateTime(int row, int column, const QDateTime &dt, const For return 0; } +/*! + \overload + */ +int Worksheet::writeTime(const QString &row_column, const QTime &t, const Format &format) +{ + //convert the "A1" notation to row/column notation + QPoint pos = xl_cell_to_rowcol(row_column); + if (pos == QPoint(-1, -1)) + return -1; + + return writeTime(pos.x(), pos.y(), t, format); +} + +/*! + Write a QTime \a value to the cell (\a row, \a column) with the \a format + */ +int Worksheet::writeTime(int row, int column, const QTime &t, const Format &format) +{ + Q_D(Worksheet); + if (d->checkDimensions(row, column)) + return -1; + + Format fmt = format; + if (!fmt.isValid()) + fmt.setNumberFormat(QStringLiteral("hh:mm:ss")); + d->workbook->styles()->addXfFormat(fmt); + + d->cellTable[row][column] = QSharedPointer(new Cell(timeToNumber(t), Cell::Numeric, fmt, this)); + + return 0; +} + /*! \overload */ diff --git a/src/xlsx/xlsxworksheet.h b/src/xlsx/xlsxworksheet.h index f38c04a..50c054f 100755 --- a/src/xlsx/xlsxworksheet.h +++ b/src/xlsx/xlsxworksheet.h @@ -77,6 +77,9 @@ public: int writeBool(int row, int column, bool value, const Format &format=Format()); int writeDateTime(const QString &row_column, const QDateTime& dt, const Format &format=Format()); int writeDateTime(int row, int column, const QDateTime& dt, const Format &format=Format()); + int writeTime(const QString &row_column, const QTime& t, const Format &format=Format()); + int writeTime(int row, int column, const QTime& t, const Format &format=Format()); + int writeHyperlink(const QString &row_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()); diff --git a/tests/auto/document/tst_documenttest.cpp b/tests/auto/document/tst_documenttest.cpp index 4cb4abd..c8a0f4d 100644 --- a/tests/auto/document/tst_documenttest.cpp +++ b/tests/auto/document/tst_documenttest.cpp @@ -21,6 +21,7 @@ private Q_SLOTS: void testReadWriteBlank(); void testReadWriteFormula(); void testReadWriteDateTime(); + void testReadWriteTime(); }; DocumentTest::DocumentTest() @@ -192,6 +193,8 @@ void DocumentTest::testReadWriteDateTime() format3.setNumberFormat("dd/mm/yyyy"); xlsx1.write("A3", dt, format3); + xlsx1.write("A4", "2013-12-14"); //Auto convert to QDateTime, by QVariant + xlsx1.saveAs(&device); device.open(QIODevice::ReadOnly); @@ -210,6 +213,33 @@ void DocumentTest::testReadWriteDateTime() QCOMPARE(xlsx2.cellAt("A3")->isDateTime(), true); 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))); +} + +void DocumentTest::testReadWriteTime() +{ + QBuffer device; + device.open(QIODevice::WriteOnly); + + Document xlsx1; + + xlsx1.write("A1", QTime()); //Blank cell + xlsx1.write("A2", QTime(1, 22)); + + xlsx1.saveAs(&device); + + device.open(QIODevice::ReadOnly); + Document xlsx2(&device); + + QCOMPARE(xlsx2.cellAt("A1")->dataType(), Cell::Blank); + + QCOMPARE(xlsx2.cellAt("A2")->dataType(), Cell::Numeric); + QCOMPARE(xlsx2.cellAt("A2")->isDateTime(), true); + qDebug()<value().toDouble(); + //QCOMPARE(xlsx2.read("A2").toTime(), QTime(1, 22)); //01:21:59.999 ??? } QTEST_APPLESS_MAIN(DocumentTest) diff --git a/tests/auto/utility/tst_utilitytest.cpp b/tests/auto/utility/tst_utilitytest.cpp index da61ced..19a59b1 100644 --- a/tests/auto/utility/tst_utilitytest.cpp +++ b/tests/auto/utility/tst_utilitytest.cpp @@ -44,6 +44,9 @@ private Q_SLOTS: void test_datetimeToNumber_data(); void test_datetimeToNumber(); + void test_timeToNumber_data(); + void test_timeToNumber(); + void test_datetimeFromNumber_data(); void test_datetimeFromNumber(); }; @@ -133,6 +136,25 @@ void UtilityTest::test_datetimeToNumber() QCOMPARE(QXlsx::datetimeToNumber(dt, is1904), num); } +void UtilityTest::test_timeToNumber_data() +{ + QTest::addColumn("t"); + QTest::addColumn("num"); + + QTest::newRow("0") << QTime(0,0) << 0.0; + QTest::newRow("0.0625") << QTime(1, 30) << 0.0625; + QTest::newRow("0.25") << QTime(6, 0) << 0.25; + QTest::newRow("0.5") << QTime(12, 0) << 0.5; +} + +void UtilityTest::test_timeToNumber() +{ + QFETCH(QTime, t); + QFETCH(double, num); + + QCOMPARE(QXlsx::timeToNumber(t), num); +} + void UtilityTest::test_datetimeFromNumber_data() { QTest::addColumn("dt");