diff --git a/src/xlsx/xlsxsharedstrings.cpp b/src/xlsx/xlsxsharedstrings.cpp index 25f26fb..8f913a3 100755 --- a/src/xlsx/xlsxsharedstrings.cpp +++ b/src/xlsx/xlsxsharedstrings.cpp @@ -61,6 +61,11 @@ int SharedStrings::addSharedString(const QString &string) void SharedStrings::incRefByStringIndex(int idx) { + if (idx <0 || idx >= m_stringList.size()) { + qDebug("SharedStrings: invlid index"); + return; + } + addSharedString(m_stringList[idx]); } diff --git a/src/xlsx/xlsxstyles.cpp b/src/xlsx/xlsxstyles.cpp index e879bab..1a2cb7d 100755 --- a/src/xlsx/xlsxstyles.cpp +++ b/src/xlsx/xlsxstyles.cpp @@ -63,7 +63,7 @@ Format *Styles::createFormat() Format *Styles::xfFormat(int idx) const { - if (idx <0 || idx > m_xf_formatsList.size()) + if (idx <0 || idx >= m_xf_formatsList.size()) return 0; return m_xf_formatsList[idx]; diff --git a/src/xlsx/xlsxworkbook.h b/src/xlsx/xlsxworkbook.h index 607198d..c9e54b2 100755 --- a/src/xlsx/xlsxworkbook.h +++ b/src/xlsx/xlsxworkbook.h @@ -69,6 +69,7 @@ public: private: friend class Package; friend class Worksheet; + friend class WorksheetPrivate; friend class Document; friend class DocumentPrivate; diff --git a/src/xlsx/xlsxworksheet.cpp b/src/xlsx/xlsxworksheet.cpp index 45e8fa7..adb056c 100755 --- a/src/xlsx/xlsxworksheet.cpp +++ b/src/xlsx/xlsxworksheet.cpp @@ -1076,65 +1076,89 @@ QByteArray Worksheet::saveToXmlData() return data; } +void WorksheetPrivate::readSheetData(XmlStreamReader &reader) +{ + Q_ASSERT(reader.name() == QLatin1String("sheetData")); + + while(!(reader.name() == QLatin1String("sheetData") && reader.tokenType() == QXmlStreamReader::EndElement)) { + reader.readNextStartElement(); + + if (reader.tokenType() == QXmlStreamReader::StartElement) { + if (reader.name() == QLatin1String("c")) { + QXmlStreamAttributes attributes = reader.attributes(); + QString r = attributes.value(QLatin1String("r")).toString(); + QPoint pos = xl_cell_to_rowcol(r); + + //get format + Format *format = 0; + if (attributes.hasAttribute(QLatin1String("s"))) { + int idx = attributes.value(QLatin1String("s")).toInt(); + format = workbook->styles()->xfFormat(idx); + } + + if (attributes.hasAttribute(QLatin1String("t"))) { + QString type = attributes.value(QLatin1String("t")).toString(); + if (type == QLatin1String("s")) { + //string type + reader.readNextStartElement(); + if (reader.name() == QLatin1String("v")) { + QString value = reader.readElementText(); + workbook->sharedStrings()->incRefByStringIndex(value.toInt()); + XlsxCellData *data = new XlsxCellData(value ,XlsxCellData::String, format); + cellTable[pos.x()][pos.y()] = QSharedPointer(data); + } + } else if (type == QLatin1String("b")) { + //bool type + } + } else { + //number type + reader.readNextStartElement(); + if (reader.name() == QLatin1String("v")) { + QString value = reader.readElementText(); + XlsxCellData *data = new XlsxCellData(value ,XlsxCellData::Number, format); + cellTable[pos.x()][pos.y()] = QSharedPointer(data); + } + } + } + } + } +} + bool Worksheet::loadFromXmlFile(QIODevice *device) { Q_D(Worksheet); XmlStreamReader reader(device); while(!reader.atEnd()) { - QXmlStreamReader::TokenType token = reader.readNext(); - if (token == QXmlStreamReader::StartElement) { - if (reader.name() == QLatin1String("dimension")) { - QXmlStreamAttributes attributes = reader.attributes(); - QStringList range = attributes.value(QLatin1String("ref")).toString().split(QLatin1Char(':')); - if (range.size() == 2) { - QPoint start = xl_cell_to_rowcol(range[0]); - QPoint end = xl_cell_to_rowcol(range[1]); - d->dim_rowmin = start.x(); - d->dim_colmin = start.y(); - d->dim_rowmax = end.x(); - d->dim_colmax = end.y(); - } else { - QPoint p = xl_cell_to_rowcol(range[0]); - d->dim_rowmin = p.x(); - d->dim_colmin = p.y(); - d->dim_rowmax = p.x(); - d->dim_colmax = p.y(); - } - } else if (reader.name() == QLatin1String("c")) { - QXmlStreamAttributes attributes = reader.attributes(); - QString r = attributes.value(QLatin1String("r")).toString(); - QPoint pos = xl_cell_to_rowcol(r); - - Format *format = 0; - if (attributes.hasAttribute(QLatin1String("s"))) { - int idx = attributes.value(QLatin1String("s")).toInt(); - format = d->workbook->styles()->xfFormat(idx); - } - - if (attributes.hasAttribute(QLatin1String("t"))) { - QString type = attributes.value(QLatin1String("t")).toString(); - if (type == QLatin1String("s")) { - //string type - reader.readNextStartElement(); - if (reader.name() == QLatin1String("v")) { - QString value = reader.readElementText(); - d->workbook->sharedStrings()->incRefByStringIndex(value.toInt()); - XlsxCellData *data = new XlsxCellData(value ,XlsxCellData::String, format); - d->cellTable[pos.x()][pos.y()] = QSharedPointer(data); - } - } - } else { - //number type - reader.readNextStartElement(); - if (reader.name() == QLatin1String("v")) { - QString value = reader.readElementText(); - XlsxCellData *data = new XlsxCellData(value ,XlsxCellData::Number, format); - d->cellTable[pos.x()][pos.y()] = QSharedPointer(data); - } - } - } - } + reader.readNextStartElement(); + if (reader.tokenType() == QXmlStreamReader::StartElement) { + if (reader.name() == QLatin1String("dimension")) { + QXmlStreamAttributes attributes = reader.attributes(); + QStringList range = attributes.value(QLatin1String("ref")).toString().split(QLatin1Char(':')); + if (range.size() == 2) { + QPoint start = xl_cell_to_rowcol(range[0]); + QPoint end = xl_cell_to_rowcol(range[1]); + d->dim_rowmin = start.x(); + d->dim_colmin = start.y(); + d->dim_rowmax = end.x(); + d->dim_colmax = end.y(); + } else { + QPoint p = xl_cell_to_rowcol(range[0]); + d->dim_rowmin = p.x(); + d->dim_colmin = p.y(); + d->dim_rowmax = p.x(); + d->dim_colmax = p.y(); + } + } else if (reader.name() == QLatin1String("sheetViews")) { + + } else if (reader.name() == QLatin1String("sheetFormatPr")) { + + } else if (reader.name() == QLatin1String("cols")) { + + } else if (reader.name() == QLatin1String("sheetData")) { + d->readSheetData(reader); + } + } } return true; diff --git a/src/xlsx/xlsxworksheet.h b/src/xlsx/xlsxworksheet.h index e42036d..5236444 100755 --- a/src/xlsx/xlsxworksheet.h +++ b/src/xlsx/xlsxworksheet.h @@ -40,7 +40,6 @@ class WorksheetTest; QT_BEGIN_NAMESPACE_XLSX class Package; class Workbook; -class XmlStreamWriter; class Format; class Drawing; struct XlsxImageData; diff --git a/src/xlsx/xlsxworksheet_p.h b/src/xlsx/xlsxworksheet_p.h index 28e3d1e..485d759 100644 --- a/src/xlsx/xlsxworksheet_p.h +++ b/src/xlsx/xlsxworksheet_p.h @@ -24,6 +24,7 @@ ****************************************************************************/ #ifndef XLSXWORKSHEET_P_H #define XLSXWORKSHEET_P_H +#include "xlsxglobal.h" #include "xlsxworksheet.h" #include @@ -31,6 +32,9 @@ namespace QXlsx { +class XmlStreamWriter; +class XmlStreamReader; + struct XlsxCellData { enum CellDataType { @@ -173,7 +177,7 @@ struct XlsxColumnInfo bool hidden; }; -class WorksheetPrivate +class XLSX_AUTOTEST_EXPORT WorksheetPrivate { Q_DECLARE_PUBLIC(Worksheet) public: @@ -192,6 +196,8 @@ public: XlsxObjectPositionData objectPixelsPosition(int col_start, int row_start, double x1, double y1, double width, double height); XlsxObjectPositionData pixelsToEMUs(const XlsxObjectPositionData &data); + void readSheetData(XmlStreamReader &reader); + Workbook *workbook; Drawing *drawing; QMap > > cellTable; diff --git a/tests/auto/worksheet/tst_worksheet.cpp b/tests/auto/worksheet/tst_worksheet.cpp index 65b5f8c..f263076 100644 --- a/tests/auto/worksheet/tst_worksheet.cpp +++ b/tests/auto/worksheet/tst_worksheet.cpp @@ -2,6 +2,8 @@ #include #include "xlsxworksheet.h" +#include "private/xlsxworksheet_p.h" +#include "private/xlsxxmlreader_p.h" class WorksheetTest : public QObject { @@ -14,6 +16,8 @@ private Q_SLOTS: void testEmptySheet(); void testMerge(); void testUnMerge(); + + void testReadSheetData(); }; WorksheetTest::WorksheetTest() @@ -51,6 +55,25 @@ void WorksheetTest::testUnMerge() QVERIFY2(!xmldata.contains("" + "0" + "" + "" + "12345" + "" + ""; + QXlsx::XmlStreamReader reader(xmlData); + reader.readNextStartElement();//current node is sheetData + + QXlsx::Worksheet sheet("", 0); + sheet.d_ptr->readSheetData(reader); + + QCOMPARE(sheet.d_ptr->cellTable.size(), 2); +} + QTEST_APPLESS_MAIN(WorksheetTest) #include "tst_worksheet.moc"