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.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");
//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);
}
/*!
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
* \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 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 groupRows(int rowFirst, int rowLast, bool collapsed = true);
bool groupColumns(int colFirst, int colLast, bool collapsed = true);
bool addDataValidation(const DataValidation &validation);
Cell *cellAt(const QString &cell) const;

127
src/xlsx/xlsxworksheet.cpp

@ -845,8 +845,10 @@ void Worksheet::saveToXmlFile(QIODevice *device)
if (!d->colsInfo.isEmpty()) {
writer.writeStartElement(QStringLiteral("cols"));
for (int i=0; i<d->colsInfo.size(); ++i) {
QSharedPointer<XlsxColumnInfo> col_info = d->colsInfo[i];
QMapIterator<int, QSharedPointer<XlsxColumnInfo> > it(d->colsInfo);
while (it.hasNext()) {
it.next();
QSharedPointer<XlsxColumnInfo> col_info = it.value();
writer.writeStartElement(QStringLiteral("col"));
writer.writeAttribute(QStringLiteral("min"), QString::number(col_info->firstColumn + 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;
}
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
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))
return false;
QSharedPointer<XlsxColumnInfo> info(new XlsxColumnInfo(colFirst, colLast, width, format, hidden));
d->colsInfo.append(info);
d->splitColsInfo(colFirst, colLast);
for (int col=colFirst; col<=colLast; ++col)
d->colsInfoHelper[col] = info;
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->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);
return true;
@ -1237,6 +1304,52 @@ bool Worksheet::groupColumns(int colFirst, int colLast, bool collapsed)
{
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;
}
@ -1638,7 +1751,7 @@ void WorksheetPrivate::readColumnsInfo(XmlStreamReader &reader)
if (colAttrs.hasAttribute(QLatin1String("outlineLevel")))
info->outlineLevel = colAttrs.value(QLatin1String("outlineLevel")).toInt();
colsInfo.append(info);
colsInfo.insert(min, info);
for (int col=min; col<=max; ++col)
colsInfoHelper[col] = info;
}

4
src/xlsx/xlsxworksheet_p.h

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

4
tests/auto/worksheet/tst_worksheet.cpp

@ -221,7 +221,7 @@ void WorksheetTest::testReadColsInfo()
sheet.d_ptr->readColumnsInfo(reader);
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()
@ -241,7 +241,7 @@ void WorksheetTest::testReadRowsInfo()
sheet.d_ptr->readSheetData(reader);
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()

Loading…
Cancel
Save