From 7805e373220fcef3ae0ec7c78a71f54426e890e8 Mon Sep 17 00:00:00 2001 From: Debao Zhang Date: Thu, 24 Oct 2013 11:53:54 +0800 Subject: [PATCH] Add basic formula read support --- src/xlsx/xlsxworksheet.cpp | 51 ++++++++++++++++++++++---- src/xlsx/xlsxworksheet_p.h | 1 + tests/auto/worksheet/tst_worksheet.cpp | 17 ++++++++- 3 files changed, 60 insertions(+), 9 deletions(-) diff --git a/src/xlsx/xlsxworksheet.cpp b/src/xlsx/xlsxworksheet.cpp index f2767c4..d3cabbb 100755 --- a/src/xlsx/xlsxworksheet.cpp +++ b/src/xlsx/xlsxworksheet.cpp @@ -1101,6 +1101,36 @@ QByteArray Worksheet::saveToXmlData() return data; } +QSharedPointer WorksheetPrivate::readNumericCellData(XmlStreamReader &reader) +{ + Q_ASSERT(reader.name() == QLatin1String("c")); + + QString v_str; + QString f_str; + while (!(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(); + } + } + + if (v_str.isEmpty() && f_str.isEmpty()) { + //blank type + return QSharedPointer(new Cell(QVariant(), Cell::Blank)); + } else if (f_str.isEmpty()) { + //numeric type + return QSharedPointer(new Cell(v_str.toDouble(), Cell::Numeric)); + } else { + //formula type + QSharedPointer cell(new Cell(v_str.toDouble(), Cell::Formula)); + cell->d_ptr->formula = f_str; + return cell; + } +} + void WorksheetPrivate::readSheetData(XmlStreamReader &reader) { Q_ASSERT(reader.name() == QLatin1String("sheetData")); @@ -1174,16 +1204,21 @@ void WorksheetPrivate::readSheetData(XmlStreamReader &reader) QSharedPointer data(new Cell(value.toInt() ? true : false, Cell::Boolean, format)); cellTable[pos.x()][pos.y()] = data; } + } else if (type == QLatin1String("str")) { + //formula type + QSharedPointer data = readNumericCellData(reader); + data->d_ptr->format = format; + cellTable[pos.x()][pos.y()] = data; + } else if (type == QLatin1String("n")) { + QSharedPointer data = readNumericCellData(reader); + data->d_ptr->format = format; + cellTable[pos.x()][pos.y()] = data; } } else { - //number type - reader.readNextStartElement(); - if (reader.name() == QLatin1String("v")) { - QString value = reader.readElementText(); - Cell *data = new Cell(value ,Cell::Numeric, format); - cellTable[pos.x()][pos.y()] = QSharedPointer(data); - } - } + //default is "n" + QSharedPointer data = readNumericCellData(reader); + data->d_ptr->format = format; + cellTable[pos.x()][pos.y()] = data; } } } } diff --git a/src/xlsx/xlsxworksheet_p.h b/src/xlsx/xlsxworksheet_p.h index 47fcf73..cbbe78a 100644 --- a/src/xlsx/xlsxworksheet_p.h +++ b/src/xlsx/xlsxworksheet_p.h @@ -174,6 +174,7 @@ public: XlsxObjectPositionData objectPixelsPosition(int col_start, int row_start, double x1, double y1, double width, double height); XlsxObjectPositionData pixelsToEMUs(const XlsxObjectPositionData &data); + QSharedPointer readNumericCellData(XmlStreamReader &reader); void readSheetData(XmlStreamReader &reader); void readColumnsInfo(XmlStreamReader &reader); void readMergeCells(XmlStreamReader &reader); diff --git a/tests/auto/worksheet/tst_worksheet.cpp b/tests/auto/worksheet/tst_worksheet.cpp index 421bbb3..38e8c4e 100644 --- a/tests/auto/worksheet/tst_worksheet.cpp +++ b/tests/auto/worksheet/tst_worksheet.cpp @@ -46,6 +46,8 @@ void WorksheetTest::testWriteCells() sheet.write("A2", "Hello"); sheet.writeInlineString(2, 0, "Hello inline"); //A3 sheet.write("A4", true); + sheet.write("A5", "=44+33"); + sheet.writeFormula(4, 1, "44+33", 0, 77); QByteArray xmldata = sheet.saveToXmlData(); @@ -53,7 +55,8 @@ void WorksheetTest::testWriteCells() QVERIFY2(xmldata.contains("0"), "string"); QVERIFY2(xmldata.contains("Hello inline"), "inline string"); QVERIFY2(xmldata.contains("1"), "boolean"); - + QVERIFY2(xmldata.contains("44+330"), "formula"); + QVERIFY2(xmldata.contains("44+3377"), "formula"); } void WorksheetTest::testMerge() @@ -83,6 +86,8 @@ void WorksheetTest::testReadSheetData() const QByteArray xmlData = "" "" "0" + "44+3377" + "44+3377" "" "" "12345" @@ -101,6 +106,16 @@ void WorksheetTest::testReadSheetData() QCOMPARE(sheet.d_ptr->cellTable[0][0]->dataType(), QXlsx::Cell::String); QCOMPARE(sheet.d_ptr->cellTable[0][0]->value().toInt(), 0); + //B1 + QCOMPARE(sheet.d_ptr->cellTable[0][1]->dataType(), QXlsx::Cell::Formula); + QCOMPARE(sheet.d_ptr->cellTable[0][1]->value().toInt(), 77); + QCOMPARE(sheet.d_ptr->cellTable[0][1]->formula(), QStringLiteral("44+33")); + + //C1 + QCOMPARE(sheet.d_ptr->cellTable[0][2]->dataType(), QXlsx::Cell::Formula); + QCOMPARE(sheet.d_ptr->cellTable[0][2]->value().toInt(), 77); + QCOMPARE(sheet.d_ptr->cellTable[0][2]->formula(), QStringLiteral("44+33")); + //B3 QCOMPARE(sheet.d_ptr->cellTable[2][1]->dataType(), QXlsx::Cell::Numeric); QCOMPARE(sheet.d_ptr->cellTable[2][1]->value().toInt(), 12345);