Grouping rows and cols works now
This commit is contained in:
@@ -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.
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
+120
-7
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user