From 5a035ede93fdc90fcb31e974351235059ff1c741 Mon Sep 17 00:00:00 2001 From: Debao Zhang Date: Fri, 1 Nov 2013 10:37:41 +0800 Subject: [PATCH] Add format param to the mergeCells() API --- examples/xlsx/demo/main.cpp | 26 +++++---- .../mergecells/doc/images/xlsx-mergecells.png | Bin 0 -> 30545 bytes .../xlsx/mergecells/doc/src/mergecells.qdoc | 19 ++++++ examples/xlsx/mergecells/main.cpp | 25 +++++--- src/xlsx/xlsxdocument.cpp | 31 ++++++++-- src/xlsx/xlsxdocument.h | 4 +- src/xlsx/xlsxworksheet.cpp | 55 +++++++++++++----- src/xlsx/xlsxworksheet.h | 6 +- 8 files changed, 125 insertions(+), 41 deletions(-) create mode 100644 examples/xlsx/mergecells/doc/images/xlsx-mergecells.png create mode 100644 examples/xlsx/mergecells/doc/src/mergecells.qdoc diff --git a/examples/xlsx/demo/main.cpp b/examples/xlsx/demo/main.cpp index dab7a5f..6e82a04 100644 --- a/examples/xlsx/demo/main.cpp +++ b/examples/xlsx/demo/main.cpp @@ -19,17 +19,9 @@ void writeVerticalAlignCell(Document &xlsx, const QString &range, const QString Format *format = xlsx.createFormat(); format->setVerticalAlignment(align); format->setBorderStyle(Format::BorderThin); - xlsx.mergeCells(range); - CellRange r(range); - for (int row=r.firstRow(); row<=r.lastRow(); ++row) { - for (int col=r.firstColumn(); col<=r.lastColumn(); ++col) { - if (row == r.firstRow() && col == r.firstColumn()) - xlsx.write(row, col, text, format); - else - xlsx.write(row, col, QVariant(), format); - } - } + xlsx.write(r.firstRow(), r.firstColumn(), text); + xlsx.mergeCells(r, format); } void writeBorderStyleCell(Document &xlsx, const QString &cell, const QString &text, Format::BorderStyle bs) @@ -83,7 +75,7 @@ void writeInternalNumFormatsCell(Document &xlsx, int row, double value, int numF Format *format = xlsx.createFormat(); format->setNumberFormatIndex(numFmt); xlsx.write(row, 0, value); - xlsx.write(row, 1, numFmt); + xlsx.write(row, 1, QString("Builtin NumFmt %1").arg(numFmt)); xlsx.write(row, 2, value, format); } @@ -265,6 +257,18 @@ int main() writeCustomNumFormatsCell(xlsx, 14, 1.23, "0.00 \"RMB\""); writeCustomNumFormatsCell(xlsx, 15, 60, "[Red][<=100];[Green][>100]"); + //--------------------------------------------------------------- + //Create the fifth sheet. + xlsx.addWorksheet("Merging"); + Format *centerAlign = xlsx.createFormat(); + centerAlign->setHorizontalAlignment(Format::AlignHCenter); + centerAlign->setVerticalAlignment(Format::AlignVCenter); + xlsx.write("B4", "Hello Qt!"); + xlsx.mergeCells("B4:F6", centerAlign); + xlsx.write("B8", 1); + xlsx.mergeCells("B8:C21", centerAlign); + xlsx.write("E8", 2); + xlsx.mergeCells("E8:F21", centerAlign); xlsx.saveAs("Book1.xlsx"); diff --git a/examples/xlsx/mergecells/doc/images/xlsx-mergecells.png b/examples/xlsx/mergecells/doc/images/xlsx-mergecells.png new file mode 100644 index 0000000000000000000000000000000000000000..fdd266b231b063dcf350ea34a169d93ab1dcc7fc GIT binary patch literal 30545 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 P>XZmsxwHP(O|$h_3p%5JbQADDneX-nsa`1y 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 literal 0 HcmV?d00001 diff --git a/examples/xlsx/mergecells/doc/src/mergecells.qdoc b/examples/xlsx/mergecells/doc/src/mergecells.qdoc new file mode 100644 index 0000000..3198cc3 --- /dev/null +++ b/examples/xlsx/mergecells/doc/src/mergecells.qdoc @@ -0,0 +1,19 @@ +/*! + \example mergecells + \title Merge Cells Example + \brief Demonstrates how to merge cells + \ingroup qtxlsx-examples + + This example demonstrates how to generate a + simplest .xlsx file which contians merged cells with + Qt Xlsx Library. + + \image xlsx-mergecells.png + + Create an format which will be applied to the merged cells: + \snippet mergecells/main.cpp 0 + + Merge cells. + \snippet mergecells/main.cpp 1 + +*/ diff --git a/examples/xlsx/mergecells/main.cpp b/examples/xlsx/mergecells/main.cpp index 536bc33..076994a 100644 --- a/examples/xlsx/mergecells/main.cpp +++ b/examples/xlsx/mergecells/main.cpp @@ -1,15 +1,24 @@ #include "xlsxdocument.h" +#include "xlsxformat.h" + +QTXLSX_USE_NAMESPACE int main() { - QXlsx::Document xlsx; - - xlsx.write("B1", "Merge Cells"); - xlsx.mergeCells("B1:B5"); - - xlsx.write("E2", "Merge Cells 2"); - xlsx.mergeCells("E2:G4"); - + Document xlsx; + //![0] + Format *format = xlsx.createFormat(); + format->setHorizontalAlignment(Format::AlignHCenter); + format->setVerticalAlignment(Format::AlignVCenter); + //![0] + //![1] + xlsx.write("B4", "Hello Qt!"); + xlsx.mergeCells("B4:F6", format); + xlsx.write("B8", 1); + xlsx.mergeCells("B8:C21", format); + xlsx.write("E8", 2); + xlsx.mergeCells("E8:F21", format); + //![1] xlsx.save(); return 0; diff --git a/src/xlsx/xlsxdocument.cpp b/src/xlsx/xlsxdocument.cpp index dd0e956..a2e4ee8 100644 --- a/src/xlsx/xlsxdocument.cpp +++ b/src/xlsx/xlsxdocument.cpp @@ -142,21 +142,44 @@ int Document::insertImage(int row, int column, const QImage &image, double xOffs } /*! - * Merge cell \a range. + Merge a \a range of cells. The first cell should contain the data and the others should + be blank. All cells will be applied the same style if a valid \a format is given. + + \note All cells except the top-left one will be cleared. */ -int Document::mergeCells(const QString &range) +int Document::mergeCells(const CellRange &range, Format *format) { - return currentWorksheet()->mergeCells(range); + return currentWorksheet()->mergeCells(range, format); } /*! - * Unmerge cell \a range. + \overload + Merge a \a range of cells. The first cell should contain the data and the others should + be blank. All cells will be applied the same style if a valid \a format is given. + + \note All cells except the top-left one will be cleared. */ +int Document::mergeCells(const QString &range, Format *format) +{ + return currentWorksheet()->mergeCells(range, format); +} + +/*! + Unmerge the cells in the \a range. +*/ int Document::unmergeCells(const QString &range) { return currentWorksheet()->unmergeCells(range); } +/*! + Unmerge the cells in the \a range. +*/ +int Document::unmergeCells(const CellRange &range) +{ + return currentWorksheet()->unmergeCells(range); +} + /*! * \brief Set properties for a row of cells. * \param row The worksheet row (zero indexed). diff --git a/src/xlsx/xlsxdocument.h b/src/xlsx/xlsxdocument.h index bfaf55e..4d61c5c 100644 --- a/src/xlsx/xlsxdocument.h +++ b/src/xlsx/xlsxdocument.h @@ -58,7 +58,9 @@ public: int write(const QString &cell, const QVariant &value, Format *format=0); int write(int row, int col, const QVariant &value, Format *format=0); int insertImage(int row, int column, const QImage &image, double xOffset=0, double yOffset=0, double xScale=1, double yScale=1); - int mergeCells(const QString &range); + int mergeCells(const CellRange &range, Format *format=0); + int mergeCells(const QString &range, Format *format=0); + int unmergeCells(const CellRange &range); int unmergeCells(const QString &range); bool setRow(int row, double height, Format* format=0, bool hidden=false); bool setRow(const QString &row, double height, Format* format=0, bool hidden=false); diff --git a/src/xlsx/xlsxworksheet.cpp b/src/xlsx/xlsxworksheet.cpp index d60a402..3220f28 100755 --- a/src/xlsx/xlsxworksheet.cpp +++ b/src/xlsx/xlsxworksheet.cpp @@ -679,7 +679,13 @@ int Worksheet::insertImage(int row, int column, const QImage &image, const QPoin return 0; } -int Worksheet::mergeCells(const CellRange &range) +/*! + Merge a \a range of cells. The first cell should contain the data and the others should + be blank. All cells will be applied the same style if a valid \a format is given. + + \note All cells except the top-left one will be cleared. + */ +int Worksheet::mergeCells(const CellRange &range, Format *format) { Q_D(Worksheet); if (range.rowCount() < 2 && range.columnCount() < 2) @@ -688,11 +694,37 @@ int Worksheet::mergeCells(const CellRange &range) if (d->checkDimensions(range.firstRow(), range.firstColumn())) return -1; + for (int row = range.firstRow(); row <= range.lastRow(); ++row) { + for (int col = range.firstColumn(); col <= range.lastColumn(); ++col) { + if (row == range.firstRow() && col == range.firstColumn()) { + Cell *cell = cellAt(row, col); + if (cell) { + if (format) + cell->d_ptr->format = format; + } else { + writeBlank(row, col, format); + } + } else { + writeBlank(row, col, format); + } + } + } + + if (format) + d->workbook->styles()->addFormat(format); + d->merges.append(range); return 0; } -int Worksheet::mergeCells(const QString &range) +/*! + \overload + Merge a \a range of cells. The first cell should contain the data and the others should + be blank. All cells will be applied the same style if a valid \a format is given. + + \note All cells except the top-left one will be cleared. + */ +int Worksheet::mergeCells(const QString &range, Format *format) { QStringList cells = range.split(QLatin1Char(':')); if (cells.size() != 2) @@ -703,14 +735,12 @@ int Worksheet::mergeCells(const QString &range) if (cell1 == QPoint(-1,-1) || cell2 == QPoint(-1, -1)) return -1; - return mergeCells(CellRange(cell1.x(), cell1.y(), cell2.x(), cell2.y())); -} - -int Worksheet::mergeCells(int row_begin, int column_begin, int row_end, int column_end) -{ - return mergeCells(CellRange(row_begin, column_begin, row_end, column_end)); + return mergeCells(CellRange(cell1.x(), cell1.y(), cell2.x(), cell2.y()), format); } +/*! + Unmerge the cells in the \a range. +*/ int Worksheet::unmergeCells(const CellRange &range) { Q_D(Worksheet); @@ -721,6 +751,10 @@ int Worksheet::unmergeCells(const CellRange &range) return 0; } +/*! + \overload + Unmerge the cells in the \a range. +*/ int Worksheet::unmergeCells(const QString &range) { QStringList cells = range.split(QLatin1Char(':')); @@ -735,11 +769,6 @@ int Worksheet::unmergeCells(const QString &range) return unmergeCells(CellRange(cell1.x(), cell1.y(), cell2.x(), cell2.y())); } -int Worksheet::unmergeCells(int row_begin, int column_begin, int row_end, int column_end) -{ - return unmergeCells(CellRange(row_begin, column_begin, row_end, column_end)); -} - void Worksheet::saveToXmlFile(QIODevice *device) { Q_D(Worksheet); diff --git a/src/xlsx/xlsxworksheet.h b/src/xlsx/xlsxworksheet.h index e4f9ad6..0aa5632 100755 --- a/src/xlsx/xlsxworksheet.h +++ b/src/xlsx/xlsxworksheet.h @@ -71,10 +71,8 @@ public: int insertImage(int row, int column, const QImage &image, const QPointF &offset=QPointF(), double xScale=1, double yScale=1); - int mergeCells(int row_begin, int column_begin, int row_end, int column_end); - int mergeCells(const QString &range); - int mergeCells(const CellRange &range); - int unmergeCells(int row_begin, int column_begin, int row_end, int column_end); + int mergeCells(const QString &range, Format *format=0); + int mergeCells(const CellRange &range, Format *format=0); int unmergeCells(const QString &range); int unmergeCells(const CellRange &range);