Browse Source

Grouping rows and cols works now

master
Debao Zhang 11 years ago
parent
commit
68f4190fa5
  1. 15
      examples/xlsx/demo/main.cpp
  2. 16
      src/xlsx/xlsxdocument.cpp
  3. 2
      src/xlsx/xlsxdocument.h
  4. 127
      src/xlsx/xlsxworksheet.cpp
  5. 4
      src/xlsx/xlsxworksheet_p.h
  6. 4
      tests/auto/worksheet/tst_worksheet.cpp

15
examples/xlsx/demo/main.cpp

@ -270,6 +270,21 @@ int main()
xlsx.write("E8", 2); xlsx.write("E8", 2);
xlsx.mergeCells("E8:F21", centerAlign); xlsx.mergeCells("E8:F21", centerAlign);
//---------------------------------------------------------------
//Create the fifth sheet.
xlsx.addWorksheet("Grouping");
qsrand(QDateTime::currentMSecsSinceEpoch());
for (int row=1; row<31; ++row) {
for (int col=0; col<10; ++col)
xlsx.write(row, col, qrand() % 100);
}
xlsx.groupRows(3, 6);
xlsx.groupRows(10, 25, false);
xlsx.groupRows(14, 16, false);
xlsx.groupRows(19, 21, false);
xlsx.groupColumns(0, 1);
xlsx.groupColumns(4, 7, false);
xlsx.saveAs("Book1.xlsx"); xlsx.saveAs("Book1.xlsx");
//Make sure that read/write works well. //Make sure that read/write works well.

16
src/xlsx/xlsxdocument.cpp

@ -224,6 +224,22 @@ bool Document::setColumn(const QString &colFirst, const QString &colLast, double
return currentWorksheet()->setColumn(colFirst, colLast, width, format, hidden); return currentWorksheet()->setColumn(colFirst, colLast, width, format, hidden);
} }
/*!
Groups rows from rowFirst to rowLast. Returns false if error occurs.
*/
bool Document::groupRows(int rowFirst, int rowLast, bool collapsed)
{
return currentWorksheet()->groupRows(rowFirst, rowLast, collapsed);
}
/*!
Groups columns from colFirst to colLast. Returns false if error occurs.
*/
bool Document::groupColumns(int colFirst, int colLast, bool collapsed)
{
return currentWorksheet()->groupColumns(colFirst, colLast, collapsed);
}
/*! /*!
* \brief Add a data validation rule for current worksheet * \brief Add a data validation rule for current worksheet
* \param validation * \param validation

2
src/xlsx/xlsxdocument.h

@ -66,6 +66,8 @@ public:
bool setRow(const QString &row, double height, Format* format=0, bool hidden=false); bool setRow(const QString &row, double height, Format* format=0, bool hidden=false);
bool setColumn(int colFirst, int colLast, double width, Format* format=0, bool hidden=false); bool setColumn(int colFirst, int colLast, double width, Format* format=0, bool hidden=false);
bool setColumn(const QString &colFirst, const QString &colLast, double width, Format* format=0, bool hidden=false); bool setColumn(const QString &colFirst, const QString &colLast, double width, Format* format=0, bool hidden=false);
bool groupRows(int rowFirst, int rowLast, bool collapsed = true);
bool groupColumns(int colFirst, int colLast, bool collapsed = true);
bool addDataValidation(const DataValidation &validation); bool addDataValidation(const DataValidation &validation);
Cell *cellAt(const QString &cell) const; Cell *cellAt(const QString &cell) const;

127
src/xlsx/xlsxworksheet.cpp

@ -845,8 +845,10 @@ void Worksheet::saveToXmlFile(QIODevice *device)
if (!d->colsInfo.isEmpty()) { if (!d->colsInfo.isEmpty()) {
writer.writeStartElement(QStringLiteral("cols")); writer.writeStartElement(QStringLiteral("cols"));
for (int i=0; i<d->colsInfo.size(); ++i) { QMapIterator<int, QSharedPointer<XlsxColumnInfo> > it(d->colsInfo);
QSharedPointer<XlsxColumnInfo> col_info = d->colsInfo[i]; while (it.hasNext()) {
it.next();
QSharedPointer<XlsxColumnInfo> col_info = it.value();
writer.writeStartElement(QStringLiteral("col")); writer.writeStartElement(QStringLiteral("col"));
writer.writeAttribute(QStringLiteral("min"), QString::number(col_info->firstColumn + 1)); writer.writeAttribute(QStringLiteral("min"), QString::number(col_info->firstColumn + 1));
writer.writeAttribute(QStringLiteral("max"), QString::number(col_info->lastColumn + 1)); writer.writeAttribute(QStringLiteral("max"), QString::number(col_info->lastColumn + 1));
@ -1156,6 +1158,48 @@ bool Worksheet::setRow(const QString &row, double height, Format *format, bool h
return false; return false;
} }
void WorksheetPrivate::splitColsInfo(int colFirst, int colLast)
{
// Split current columnInfo, for example, if "A:H" has been set,
// we are trying to set "B:D", there should be "A", "B:D", "E:H".
// This will be more complex if we try to set "C:F" after "B:D".
{
QMapIterator<int, QSharedPointer<XlsxColumnInfo> > it(colsInfo);
while(it.hasNext()) {
it.next();
QSharedPointer<XlsxColumnInfo> info = it.value();
if (colFirst > info->firstColumn && colFirst <= info->lastColumn) {
//split the range,
QSharedPointer<XlsxColumnInfo> info2(new XlsxColumnInfo(*info));
info->lastColumn = colFirst - 1;
info2->firstColumn = colFirst;
colsInfo.insert(colFirst, info2);
for (int c = info2->firstColumn; c <= info2->lastColumn; ++c)
colsInfoHelper[c] = info2;
break;
}
}
}
{
QMapIterator<int, QSharedPointer<XlsxColumnInfo> > it(colsInfo);
while(it.hasNext()) {
it.next();
QSharedPointer<XlsxColumnInfo> info = it.value();
if (colLast >= info->firstColumn && colLast < info->lastColumn) {
QSharedPointer<XlsxColumnInfo> info2(new XlsxColumnInfo(*info));
info->lastColumn = colLast;
info2->firstColumn = colLast + 1;
colsInfo.insert(colLast + 1, info2);
for (int c = info2->firstColumn; c <= info2->lastColumn; ++c)
colsInfoHelper[c] = info2;
break;
}
}
}
}
/*! /*!
Sets column width and format for all columns from colFirst to colLast. Column Sets column width and format for all columns from colFirst to colLast. Column
width measured as the number of characters of the maximum digit width of the width measured as the number of characters of the maximum digit width of the
@ -1176,12 +1220,35 @@ bool Worksheet::setColumn(int colFirst, int colLast, double width, Format *forma
if (d->checkDimensions(0, colFirst, ignore_row, ignore_col)) if (d->checkDimensions(0, colFirst, ignore_row, ignore_col))
return false; return false;
QSharedPointer<XlsxColumnInfo> info(new XlsxColumnInfo(colFirst, colLast, width, format, hidden)); d->splitColsInfo(colFirst, colLast);
d->colsInfo.append(info);
for (int col=colFirst; col<=colLast; ++col) QList<int> nodes;
d->colsInfoHelper[col] = info; nodes.append(colFirst);
for (int col = colFirst; col <= colLast; ++col) {
if (d->colsInfo.contains(col)) {
if (nodes.last() != col)
nodes.append(col);
int nextCol = d->colsInfo[col]->lastColumn + 1;
if (nextCol <= colLast)
nodes.append(nextCol);
}
}
for (int idx = 0; idx < nodes.size(); ++idx) {
int colStart = nodes[idx];
if (d->colsInfo.contains(colStart)) {
QSharedPointer<XlsxColumnInfo> info = d->colsInfo[colStart];
info->width = width;
info->format = format;
info->hidden = hidden;
} else {
int colEnd = (idx == nodes.size() - 1) ? colLast : nodes[idx+1] - 1;
QSharedPointer<XlsxColumnInfo> info(new XlsxColumnInfo(colStart, colEnd, width, format, hidden));
d->colsInfo.insert(colFirst, info);
for (int c = colStart; c <= colEnd; ++c)
d->colsInfoHelper[c] = info;
}
}
d->workbook->styles()->addFormat(format); d->workbook->styles()->addFormat(format);
return true; return true;
@ -1237,6 +1304,52 @@ bool Worksheet::groupColumns(int colFirst, int colLast, bool collapsed)
{ {
Q_D(Worksheet); Q_D(Worksheet);
d->splitColsInfo(colFirst, colLast);
QList<int> nodes;
nodes.append(colFirst);
for (int col = colFirst; col <= colLast; ++col) {
if (d->colsInfo.contains(col)) {
if (nodes.last() != col)
nodes.append(col);
int nextCol = d->colsInfo[col]->lastColumn + 1;
if (nextCol <= colLast)
nodes.append(nextCol);
}
}
for (int idx = 0; idx < nodes.size(); ++idx) {
int colStart = nodes[idx];
if (d->colsInfo.contains(colStart)) {
QSharedPointer<XlsxColumnInfo> info = d->colsInfo[colStart];
info->outlineLevel += 1;
if (collapsed)
info->hidden = true;
} else {
int colEnd = (idx == nodes.size() - 1) ? colLast : nodes[idx+1] - 1;
QSharedPointer<XlsxColumnInfo> info(new XlsxColumnInfo(colStart, colEnd));
info->outlineLevel += 1;
d->colsInfo.insert(colFirst, info);
if (collapsed)
info->hidden = true;
for (int c = colStart; c <= colEnd; ++c)
d->colsInfoHelper[c] = info;
}
}
if (collapsed) {
int col = colLast+1;
d->splitColsInfo(col, col);
if (d->colsInfo.contains(col))
d->colsInfo[col]->collapsed = true;
else {
QSharedPointer<XlsxColumnInfo> info(new XlsxColumnInfo(col, col));
info->collapsed = true;
d->colsInfo.insert(col, info);
d->colsInfoHelper[col] = info;
}
}
return false; return false;
} }
@ -1638,7 +1751,7 @@ void WorksheetPrivate::readColumnsInfo(XmlStreamReader &reader)
if (colAttrs.hasAttribute(QLatin1String("outlineLevel"))) if (colAttrs.hasAttribute(QLatin1String("outlineLevel")))
info->outlineLevel = colAttrs.value(QLatin1String("outlineLevel")).toInt(); info->outlineLevel = colAttrs.value(QLatin1String("outlineLevel")).toInt();
colsInfo.append(info); colsInfo.insert(min, info);
for (int col=min; col<=max; ++col) for (int col=min; col<=max; ++col)
colsInfoHelper[col] = info; colsInfoHelper[col] = info;
} }

4
src/xlsx/xlsxworksheet_p.h

@ -163,6 +163,8 @@ public:
Format *cellFormat(int row, int col) const; Format *cellFormat(int row, int col) const;
QString generateDimensionString(); QString generateDimensionString();
void calculateSpans(); void calculateSpans();
void splitColsInfo(int colFirst, int colLast);
void writeSheetData(XmlStreamWriter &writer); void writeSheetData(XmlStreamWriter &writer);
void writeCellData(XmlStreamWriter &writer, int row, int col, QSharedPointer<Cell> cell); void writeCellData(XmlStreamWriter &writer, int row, int col, QSharedPointer<Cell> cell);
void writeMergeCells(XmlStreamWriter &writer); void writeMergeCells(XmlStreamWriter &writer);
@ -195,7 +197,7 @@ public:
QStringList externDrawingList; QStringList externDrawingList;
QList<XlsxImageData *> imageList; QList<XlsxImageData *> imageList;
QMap<int, QSharedPointer<XlsxRowInfo> > rowsInfo; QMap<int, QSharedPointer<XlsxRowInfo> > rowsInfo;
QList<QSharedPointer<XlsxColumnInfo> > colsInfo; QMap<int, QSharedPointer<XlsxColumnInfo> > colsInfo;
QMap<int, QSharedPointer<XlsxColumnInfo> > colsInfoHelper; QMap<int, QSharedPointer<XlsxColumnInfo> > colsInfoHelper;
QList<QPair<QString, QString> > drawingLinks; QList<QPair<QString, QString> > drawingLinks;

4
tests/auto/worksheet/tst_worksheet.cpp

@ -221,7 +221,7 @@ void WorksheetTest::testReadColsInfo()
sheet.d_ptr->readColumnsInfo(reader); sheet.d_ptr->readColumnsInfo(reader);
QCOMPARE(sheet.d_ptr->colsInfo.size(), 1); QCOMPARE(sheet.d_ptr->colsInfo.size(), 1);
QCOMPARE(sheet.d_ptr->colsInfo[0]->width, 5.0); QCOMPARE(sheet.d_ptr->colsInfo[9]->width, 5.0);
} }
void WorksheetTest::testReadRowsInfo() void WorksheetTest::testReadRowsInfo()
@ -241,7 +241,7 @@ void WorksheetTest::testReadRowsInfo()
sheet.d_ptr->readSheetData(reader); sheet.d_ptr->readSheetData(reader);
QCOMPARE(sheet.d_ptr->rowsInfo.size(), 1); QCOMPARE(sheet.d_ptr->rowsInfo.size(), 1);
QCOMPARE(sheet.d_ptr->rowsInfo[3]->height, 40.0); QCOMPARE(sheet.d_ptr->rowsInfo[2]->height, 40.0);
} }
void WorksheetTest::testReadMergeCells() void WorksheetTest::testReadMergeCells()

Loading…
Cancel
Save