diff --git a/src/xlsx/xlsx.pro b/src/xlsx/xlsx.pro index 1449014..1d357fd 100644 --- a/src/xlsx/xlsx.pro +++ b/src/xlsx/xlsx.pro @@ -13,4 +13,3 @@ include(qtxlsx.pri) QMAKE_TARGET_COMPANY = "Debao Zhang" QMAKE_TARGET_COPYRIGHT = "Copyright (C) 2013-2014 Debao Zhang " QMAKE_TARGET_DESCRIPTION = ".Xlsx file wirter for Qt5" - diff --git a/src/xlsx/xlsxdocument.cpp b/src/xlsx/xlsxdocument.cpp index 2701a0e..0158790 100644 --- a/src/xlsx/xlsxdocument.cpp +++ b/src/xlsx/xlsxdocument.cpp @@ -514,19 +514,6 @@ bool Document::unmergeCells(const CellRange &range) return false; } -/*! - Sets the properties of \a row with the given \a height, \a format and \a hidden. - \a row is 1-indexed. - - Returns false if failed. - */ -bool Document::setRow(int row, double height, const Format &format, bool hidden) -{ - if (Worksheet *sheet = currentWorksheet()) - return sheet->setRow(row, height, format, hidden); - return false; -} - /*! Sets the column properties for all columns from \a colFirst to \a colLast with the given \a width, \a format and \a hidden. Column @@ -559,6 +546,169 @@ bool Document::setColumn(const QString &colFirst, const QString &colLast, double return false; } +bool Document::setColumnWidth(const QString &column, double width) +{ + return setColumnWidth(column,column,width); +} + +bool Document::setColumnFormat(const QString &column, const Format &format) +{ + return setColumnFormat(column,column,format); +} + +bool Document::setColumnHidden(const QString &column, bool hidden) +{ + return setColumnHidden(column,column,hidden); +} + +bool Document::setColumnWidth(const QString &colFirst, const QString &colLast, double width) +{ + if (Worksheet *sheet = currentWorksheet()) + return sheet->setColumnWidth(colFirst, colLast, width); + return false; +} + +bool Document::setColumnFormat(const QString &colFirst, const QString &colLast, const Format &format) +{ + if (Worksheet *sheet = currentWorksheet()) + return sheet->setColumnFormat(colFirst, colLast, format); + return false; +} + +bool Document::setColumnHidden(const QString &colFirst, const QString &colLast, bool hidden) +{ + if (Worksheet *sheet = currentWorksheet()) + return sheet->setColumnWidth(colFirst, colLast, hidden); + return false; +} + +bool Document::setColumnWidth(int column, double width) +{ + return setColumnWidth(column,column,width); +} + +bool Document::setColumnFormat(int column, const Format &format) +{ + return setColumnFormat(column,column,format); +} + +bool Document::setColumnHidden(int column, bool hidden) +{ + return setColumnHidden(column,column,hidden); +} + +bool Document::setColumnWidth(int colFirst, int colLast, double width) +{ + if (Worksheet *sheet = currentWorksheet()) + return sheet->setColumnWidth(colFirst, colLast, width); + return false; +} + +bool Document::setColumnFormat(int colFirst, int colLast, const Format &format) +{ + if (Worksheet *sheet = currentWorksheet()) + return sheet->setColumnFormat(colFirst, colLast, format); + return false; +} + +bool Document::setColumnHidden(int colFirst, int colLast, bool hidden) +{ + if (Worksheet *sheet = currentWorksheet()) + return sheet->setColumnHidden(colFirst, colLast, hidden); + return false; +} + +double Document::columnWidth(int column) +{ + if (Worksheet *sheet = currentWorksheet()) + return sheet->columnWidth(column); + return 0.0; +} + +Format Document::columnFormat(int column) +{ + if (Worksheet *sheet = currentWorksheet()) + return sheet->columnFormat(column); + return Format(); +} + +bool Document::isColumnHidden(int column) +{ + if (Worksheet *sheet = currentWorksheet()) + return sheet->isColumnHidden(column); + return false; +} + +/*! + Sets the properties of \a row with the given \a height, \a format and \a hidden. + \a row is 1-indexed. + + Returns false if failed. + */ +bool Document::setRow(int row, double height, const Format &format, bool hidden) +{ + if (Worksheet *sheet = currentWorksheet()) + return sheet->setRow(row, height, format, hidden); + return false; +} + +bool Document::setRowFormat(int row, const Format &format) +{ + return setRowFormat(row,row, format); +} + +bool Document::setRowFormat(int rowFirst, int rowLast, const Format &format) +{ + if (Worksheet *sheet = currentWorksheet()) + return sheet->setRowFormat(rowFirst, rowLast, format); + return false; +} + +bool Document::setRowHidden(int row, bool hidden) +{ + return setRowHidden(row,row,hidden); +} + +bool Document::setRowHidden(int rowFirst, int rowLast, bool hidden) +{ + if (Worksheet *sheet = currentWorksheet()) + return sheet->setRowHidden(rowFirst, rowLast, hidden); + return false; +} + +bool Document::setRowHeight(int row, double height) +{ + return setRowHeight(row,row,height); +} + +bool Document::setRowHeight(int rowFirst, int rowLast, double height) +{ + if (Worksheet *sheet = currentWorksheet()) + return sheet->setRowHeight(rowFirst, rowLast, height); + return false; +} + +double Document::rowHeight(int row) +{ + if (Worksheet *sheet = currentWorksheet()) + return sheet->rowHeight(row); + return 0.0; // ? +} + +Format Document::rowFormat(int row) +{ + if (Worksheet *sheet = currentWorksheet()) + return sheet->rowFormat(row); + return Format(); // ? +} + +bool Document::isRowHidden(int row) +{ + if (Worksheet *sheet = currentWorksheet()) + return sheet->isRowHidden(row); + return false; // ? +} + /*! Groups rows from \a rowFirst to \a rowLast with the given \a collapsed. Returns false if error occurs. diff --git a/src/xlsx/xlsxdocument.h b/src/xlsx/xlsxdocument.h index 48e10c8..c3552ea 100644 --- a/src/xlsx/xlsxdocument.h +++ b/src/xlsx/xlsxdocument.h @@ -66,8 +66,38 @@ public: bool unmergeCells(const CellRange &range); bool unmergeCells(const QString &range); bool setRow(int row, double height, const Format &format=Format(), bool hidden=false); + bool setColumn(int colFirst, int colLast, double width, const Format &format=Format(), bool hidden=false); bool setColumn(const QString &colFirst, const QString &colLast, double width, const Format &format=Format(), bool hidden=false); + bool setColumnWidth(const QString &column, double width); + bool setColumnFormat(const QString &column, const Format &format); + bool setColumnHidden(const QString &column, bool hidden); + bool setColumnWidth(const QString &colFirst, const QString &colLast, double width); + bool setColumnFormat(const QString &colFirst, const QString &colLast, const Format &format); + bool setColumnHidden(const QString &colFirst, const QString &colLast, bool hidden); + bool setColumnWidth(int column, double width); + bool setColumnFormat(int column, const Format &format); + bool setColumnHidden(int column, bool hidden); + bool setColumnWidth(int colFirst, int colLast, double width); + bool setColumnFormat(int colFirst, int colLast, const Format &format); + bool setColumnHidden(int colFirst, int colLast, bool hidden); + double columnWidth(int column); + Format columnFormat(int column); + bool isColumnHidden(int column); + + bool setRowHeight(int row, double height); + bool setRowFormat(int row, const Format &format); + bool setRowHidden(int row, bool hidden); + bool setRowHeight(int rowFirst, int rowLast, double height); + bool setRowFormat(int rowFirst, int rowLast, const Format &format); + bool setRowHidden(int rowFirst, int rowLast, bool hidden); + + double rowHeight(int row); + Format rowFormat(int row); + bool isRowHidden(int row); + + + bool groupRows(int rowFirst, int rowLast, bool collapsed = true); bool groupColumns(int colFirst, int colLast, bool collapsed = true); bool addDataValidation(const DataValidation &validation); diff --git a/src/xlsx/xlsxworksheet.cpp b/src/xlsx/xlsxworksheet.cpp index 121263e..ee61edf 100755 --- a/src/xlsx/xlsxworksheet.cpp +++ b/src/xlsx/xlsxworksheet.cpp @@ -1302,10 +1302,19 @@ void WorksheetPrivate::saveXmlSheetData(QXmlStreamWriter &writer) const writer.writeAttribute(QStringLiteral("s"), QString::number(rowInfo->format.xfIndex())); writer.writeAttribute(QStringLiteral("customFormat"), QStringLiteral("1")); } - if (rowInfo->height != 15 && rowInfo->height != 0) { + //!Todo: support customHeight from info struct + //!Todo: where does this magic number '15' come from? + if (rowInfo->customHeight) { writer.writeAttribute(QStringLiteral("ht"), QString::number(rowInfo->height)); writer.writeAttribute(QStringLiteral("customHeight"), QStringLiteral("1")); + qDebug() << "custom height: " << rowInfo->height; + } else { + writer.writeAttribute(QStringLiteral("customHeight"), QStringLiteral("0")); + qDebug() << "no height: "; } + + + if (rowInfo->hidden) writer.writeAttribute(QStringLiteral("hidden"), QStringLiteral("1")); if (rowInfo->outlineLevel > 0) @@ -1483,25 +1492,6 @@ void WorksheetPrivate::saveXmlDrawings(QXmlStreamWriter &writer) const writer.writeAttribute(QStringLiteral("r:id"), QStringLiteral("rId%1").arg(relationships->count())); } -/*! - Sets the \a height and \a format of the row \a row. Row height measured in point size. If format - equals 0 then format is ignored. \a row is 1-indexed. - Hides the row if \a hidden is true. - - Returns true if success. - */ -bool Worksheet::setRow(int row, double height, const Format &format, bool hidden) -{ - Q_D(Worksheet); - int min_col = d->dimension.firstColumn() < 0 ? 0 : d->dimension.firstColumn(); - - if (d->checkDimensions(row, min_col, false, true)) - return false; - - d->rowsInfo[row] = QSharedPointer(new XlsxRowInfo(height, format, hidden)); - d->workbook->styles()->addXfFormat(format); - return true; -} void WorksheetPrivate::splitColsInfo(int colFirst, int colLast) { @@ -1545,20 +1535,11 @@ void WorksheetPrivate::splitColsInfo(int colFirst, int colLast) } } -/*! - Sets column \a width and \a format for all columns from \a colFirst to \a colLast. Column - width measured as the number of characters of the maximum digit width of the - numbers 0, 1, 2, ..., 9 as rendered in the normal style's font. If format - equals 0 then format is ignored. Both \a colFirst and \a colLast are all 1-indexed. - Hides the column if \a hidden is true. - - Return true if success. - */ -bool Worksheet::setColumn(int colFirst, int colLast, double width, const Format &format, bool hidden) +bool Worksheet::isColumnRangeValid(int colFirst, int colLast) { Q_D(Worksheet); bool ignore_row = true; - bool ignore_col = (format.isValid() || (width && hidden)) ? false : true; + bool ignore_col = false; if (colFirst > colLast) return false; @@ -1568,6 +1549,13 @@ bool Worksheet::setColumn(int colFirst, int colLast, double width, const Format if (d->checkDimensions(0, colFirst, ignore_row, ignore_col)) return false; + return true; +} + +QList Worksheet::getColumnIndexes(int colFirst, int colLast) +{ + Q_D(Worksheet); + d->splitColsInfo(colFirst, colLast); QList nodes; @@ -1582,24 +1570,35 @@ bool Worksheet::setColumn(int colFirst, int colLast, double width, const Format } } - for (int idx = 0; idx < nodes.size(); ++idx) { - int colStart = nodes[idx]; - if (d->colsInfo.contains(colStart)) { - QSharedPointer 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 info(new XlsxColumnInfo(colStart, colEnd, width, format, hidden)); - d->colsInfo.insert(colFirst, info); - for (int c = colStart; c <= colEnd; ++c) - d->colsInfoHelper[c] = info; - } + return nodes; +} + +/*! + Sets column \a width and \a format for all columns from \a colFirst to \a colLast. Column + width measured as the number of characters of the maximum digit width of the + numbers 0, 1, 2, ..., 9 as rendered in the normal style's font. If format + equals 0 then format is ignored. Both \a colFirst and \a colLast are all 1-indexed. + Hides the column if \a hidden is true. + + Return true if success. + */ +bool Worksheet::setColumn(int colFirst, int colLast, double width, const Format &format, bool hidden) +{ + Q_D(Worksheet); + + QList > columnInfoList = getColumnInfoList(colFirst, colLast); + foreach(QSharedPointer columnInfo, columnInfoList) { + columnInfo->width = width; + columnInfo->format = format; + columnInfo->hidden = hidden; } - d->workbook->styles()->addXfFormat(format); - return true; + if(columnInfoList.count() > 0) { + d->workbook->styles()->addXfFormat(format); + return true; + } + + return false; } /*! @@ -1619,6 +1618,256 @@ bool Worksheet::setColumn(const QString &colFirst, const QString &colLast, doubl return setColumn(col1, col2, width, format, hidden); } +bool Worksheet::setColumnWidth(const QString &colFirst, const QString &colLast, double width) +{ + int col1 = xl_col_name_to_value(colFirst); + int col2 = xl_col_name_to_value(colLast); + if (col1 == -1 || col2 == -1) + return false; + + return setColumnWidth(col1, col2, width); +} + +bool Worksheet::setColumnFormat(const QString &colFirst, const QString &colLast, const Format &format) +{ + int col1 = xl_col_name_to_value(colFirst); + int col2 = xl_col_name_to_value(colLast); + if (col1 == -1 || col2 == -1) + return false; + + return setColumnFormat(col1, col2, format); +} + +bool Worksheet::setColumnHidden(const QString &colFirst, const QString &colLast, bool hidden) +{ + int col1 = xl_col_name_to_value(colFirst); + int col2 = xl_col_name_to_value(colLast); + if (col1 == -1 || col2 == -1) + return false; + + return setColumnHidden(col1, col2, hidden); +} + +QList > Worksheet::getColumnInfoList(int colFirst, int colLast) +{ + Q_D(Worksheet); + QList > columnsInfoList; + if(isColumnRangeValid(colFirst,colLast)) + { + QList nodes = getColumnIndexes(colFirst, colLast); + + for (int idx = 0; idx < nodes.size(); ++idx) { + int colStart = nodes[idx]; + if (d->colsInfo.contains(colStart)) { + QSharedPointer info = d->colsInfo[colStart]; + columnsInfoList.append(info); + } else { + int colEnd = (idx == nodes.size() - 1) ? colLast : nodes[idx+1] - 1; + QSharedPointer info(new XlsxColumnInfo(colStart, colEnd)); + d->colsInfo.insert(colFirst, info); + columnsInfoList.append(info); + for (int c = colStart; c <= colEnd; ++c) + d->colsInfoHelper[c] = info; + } + } + } + + return columnsInfoList; +} + +QList > Worksheet::getRowInfoList(int rowFirst, int rowLast) +{ + Q_D(Worksheet); + QList > rowInfoList; + + int min_col = d->dimension.firstColumn() < 0 ? 0 : d->dimension.firstColumn(); + + for(int row = rowFirst; row <= rowLast; ++row) { + if (d->checkDimensions(row, min_col, false, true)) + continue; + + QSharedPointer rowInfo; + if ((d->rowsInfo[row]).isNull()){ + d->rowsInfo[row] = QSharedPointer(new XlsxRowInfo()); + } + rowInfoList.append(d->rowsInfo[row]); + } + + return rowInfoList; +} + +bool Worksheet::setColumnWidth(int colFirst, int colLast, double width) +{ + QList > columnInfoList = getColumnInfoList(colFirst, colLast); + foreach(QSharedPointer columnInfo, columnInfoList) { + columnInfo->width = width; + } + + return (columnInfoList.count() > 0); +} + +bool Worksheet::setColumnFormat(int colFirst, int colLast, const Format &format) +{ + Q_D(Worksheet); + + QList > columnInfoList = getColumnInfoList(colFirst, colLast); + foreach(QSharedPointer columnInfo, columnInfoList) { + columnInfo->format = format; + } + + if(columnInfoList.count() > 0) { + d->workbook->styles()->addXfFormat(format); + return true; + } + + return false; +} + +bool Worksheet::setColumnHidden(int colFirst, int colLast, bool hidden) +{ + QList > columnInfoList = getColumnInfoList(colFirst, colLast); + foreach(QSharedPointer columnInfo, columnInfoList) { + columnInfo->hidden = hidden; + } + + return (columnInfoList.count() > 0); +} + +double Worksheet::columnWidth(int column) +{ + Q_D(Worksheet); + + QList > columnInfoList = getColumnInfoList(column, column); + if (columnInfoList.count() == 1) { + qDebug() << "Whoopie Width"; + return columnInfoList.at(0)->width ; + } + + qDebug() << "Default Width"; + return d->sheetFormatProps.defaultColWidth; +} + +Format Worksheet::columnFormat(int column) +{ + QList > columnInfoList = getColumnInfoList(column, column); + if (columnInfoList.count() == 1) { + qDebug() << "Whoopie Format"; + return columnInfoList.at(0)->format; + } + + qDebug() << "Default Format"; + return Format(); +} + +bool Worksheet::isColumnHidden(int column) +{ + QList > columnInfoList = getColumnInfoList(column, column); + if (columnInfoList.count() == 1) { + qDebug() << "Whoopie Hidden"; + return columnInfoList.at(0)->hidden; + } + + qDebug() << "Default Hidden"; + return false; +} + +/*! + Sets the \a height and \a format of the row \a row. Row height measured in point size. If format + equals 0 then format is ignored. \a row is 1-indexed. + Hides the row if \a hidden is true. + + Returns true if success. + */ +bool Worksheet::setRow(int row, double height, const Format &format, bool hidden) +{ + return setRow(row,row, height, format, hidden); +} + +bool Worksheet::setRow(int rowFirst,int rowLast, double height, const Format &format, bool hidden) +{ + Q_D(Worksheet); + QList > rowInfoList = getRowInfoList(rowFirst,rowLast); + + foreach(QSharedPointer rowInfo, rowInfoList) { + rowInfo->height = height; + rowInfo->customHeight = true; + rowInfo->format = format; + rowInfo->hidden = hidden; + } + d->workbook->styles()->addXfFormat(format); + return true; +} + +bool Worksheet::setRowHeight(int rowFirst,int rowLast, double height) +{ + QList > rowInfoList = getRowInfoList(rowFirst,rowLast); + + foreach(QSharedPointer rowInfo, rowInfoList) { + rowInfo->height = height; + rowInfo->customHeight = true; + } + + return rowInfoList.count() > 0; +} + +bool Worksheet::setRowFormat(int rowFirst,int rowLast, const Format &format) +{ + Q_D(Worksheet); + + QList > rowInfoList = getRowInfoList(rowFirst,rowLast); + + foreach(QSharedPointer rowInfo, rowInfoList) { + rowInfo->format = format; + } + + d->workbook->styles()->addXfFormat(format); + return rowInfoList.count() > 0; +} + +bool Worksheet::setRowHidden(int rowFirst,int rowLast, bool hidden) +{ + QList > rowInfoList = getRowInfoList(rowFirst,rowLast); + + foreach(QSharedPointer rowInfo, rowInfoList) { + rowInfo->hidden = hidden; + } + + return rowInfoList.count() > 0; +} + +double Worksheet::rowHeight(int row) +{ + Q_D(Worksheet); + int min_col = d->dimension.firstColumn() < 0 ? 0 : d->dimension.firstColumn(); + + if (d->checkDimensions(row, min_col, false, true)) + return d->sheetFormatProps.defaultRowHeight; //return default on invalid row? + + return d->rowsInfo[row]->height; +} + +Format Worksheet::rowFormat(int row) +{ + Q_D(Worksheet); + int min_col = d->dimension.firstColumn() < 0 ? 0 : d->dimension.firstColumn(); + + if (d->checkDimensions(row, min_col, false, true)) + return Format(); //return default on invalid row? + + return d->rowsInfo[row]->format; +} + +bool Worksheet::isRowHidden(int row) +{ + Q_D(Worksheet); + int min_col = d->dimension.firstColumn() < 0 ? 0 : d->dimension.firstColumn(); + + if (d->checkDimensions(row, min_col, false, true)) + return false; //return default on invalid row? + + return d->rowsInfo[row]->hidden; +} + /*! Groups rows from \a rowFirst to \a rowLast with the given \a collapsed. @@ -1829,9 +2078,15 @@ void WorksheetPrivate::loadXmlSheetData(QXmlStreamReader &reader) int idx = attributes.value(QLatin1String("s")).toString().toInt(); info->format = workbook->styles()->xfFormat(idx); } - if (attributes.hasAttribute(QLatin1String("customHeight")) && attributes.hasAttribute(QLatin1String("ht"))) { - info->height = attributes.value(QLatin1String("ht")).toString().toDouble(); + + if (attributes.hasAttribute(QLatin1String("customHeight"))) { + info->customHeight = attributes.value(QLatin1String("customHeight")) == QLatin1String("1"); + //Row height is only specified when customHeight is set + if(attributes.hasAttribute(QLatin1String("ht"))) { + info->height = attributes.value(QLatin1String("ht")).toString().toDouble(); + } } + //both "hidden" and "collapsed" default are false info->hidden = attributes.value(QLatin1String("hidden")) == QLatin1String("1"); info->collapsed = attributes.value(QLatin1String("collapsed")) == QLatin1String("1"); @@ -1953,11 +2208,17 @@ void WorksheetPrivate::loadXmlColumnsInfo(QXmlStreamReader &reader) info->firstColumn = min; info->lastColumn = max; - //!Todo, customWidth support. + //Flag indicating that the column width for the affected column(s) is different from the + // default or has been manually set + if(colAttrs.hasAttribute(QLatin1String("customWidth"))) { + info->customWidth = colAttrs.value(QLatin1String("customWidth")) == QLatin1String("1"); + qDebug() << "Custom width: " << info->customWidth; + } //Note, node may have "width" without "customWidth" if (colAttrs.hasAttribute(QLatin1String("width"))) { double width = colAttrs.value(QLatin1String("width")).toString().toDouble(); info->width = width; + qDebug() << "Width: " << info->width; } info->hidden = colAttrs.value(QLatin1String("hidden")) == QLatin1String("1"); @@ -2052,6 +2313,47 @@ void WorksheetPrivate::loadXmlSheetViews(QXmlStreamReader &reader) } } +void WorksheetPrivate::loadXmlSheetFormatProps(QXmlStreamReader &reader) +{ + Q_ASSERT(reader.name() == QLatin1String("sheetFormatPr")); + QXmlStreamAttributes attributes = reader.attributes(); + XlsxSheetFormatProps formatProps; + + //Retain default values + foreach (QXmlStreamAttribute attrib, attributes) { + if(attrib.name() == QLatin1String("baseColWidth") ) { + formatProps.baseColWidth = attrib.value().toInt(); + } else if(attrib.name() == QLatin1String("customHeight")) { + formatProps.customHeight = attrib.value() == QLatin1String("1"); + } else if(attrib.name() == QLatin1String("defaultColWidth")) { + formatProps.defaultColWidth = attrib.value().toDouble(); + } else if(attrib.name() == QLatin1String("defaultRowHeight")) { + formatProps.defaultRowHeight = attrib.value().toDouble(); + } else if(attrib.name() == QLatin1String("outlineLevelCol")) { + formatProps.outlineLevelCol = attrib.value().toInt(); + } else if(attrib.name() == QLatin1String("outlineLevelRow")) { + formatProps.outlineLevelRow = attrib.value().toInt(); + } else if(attrib.name() == QLatin1String("thickBottom")) { + formatProps.thickBottom = attrib.value() == QLatin1String("1"); + } else if(attrib.name() == QLatin1String("thickTop")) { + formatProps.thickTop = attrib.value() == QLatin1String("1"); + } else if(attrib.name() == QLatin1String("zeroHeight")) { + formatProps.zeroHeight = attrib.value() == QLatin1String("1"); + } + } + + if(formatProps.defaultColWidth == 0.0) { //not set + formatProps.defaultColWidth = WorksheetPrivate::calculateColWidth(formatProps.baseColWidth); + } + +} +double WorksheetPrivate::calculateColWidth(int characters) +{ + //!Todo + //Take normal style' font maximum width and add padding and margin pixels + return characters + 0.5; +} + void WorksheetPrivate::loadXmlHyperlinks(QXmlStreamReader &reader) { Q_ASSERT(reader.name() == QLatin1String("hyperlinks")); @@ -2090,6 +2392,7 @@ bool Worksheet::loadFromXmlFile(QIODevice *device) while (!reader.atEnd()) { reader.readNextStartElement(); if (reader.tokenType() == QXmlStreamReader::StartElement) { + qDebug() << "TOKEN: " << reader.name(); if (reader.name() == QLatin1String("dimension")) { QXmlStreamAttributes attributes = reader.attributes(); QString range = attributes.value(QLatin1String("ref")).toString(); @@ -2097,7 +2400,7 @@ bool Worksheet::loadFromXmlFile(QIODevice *device) } else if (reader.name() == QLatin1String("sheetViews")) { d->loadXmlSheetViews(reader); } else if (reader.name() == QLatin1String("sheetFormatPr")) { - + d->loadXmlSheetFormatProps(reader); } else if (reader.name() == QLatin1String("cols")) { d->loadXmlColumnsInfo(reader); } else if (reader.name() == QLatin1String("sheetData")) { diff --git a/src/xlsx/xlsxworksheet.h b/src/xlsx/xlsxworksheet.h index 59a04d6..96004f0 100755 --- a/src/xlsx/xlsxworksheet.h +++ b/src/xlsx/xlsxworksheet.h @@ -50,6 +50,8 @@ class CellRange; class RichString; class Relationships; class Chart; +class XlsxColumnInfo; +class XlsxRowInfo; class WorksheetPrivate; class Q_XLSX_EXPORT Worksheet : public AbstractSheet @@ -99,9 +101,29 @@ public: bool unmergeCells(const CellRange &range); QList mergedCells() const; - bool setRow(int row, double height, const Format &format=Format(), bool hidden=false); - bool setColumn(int colFirst, int colLast, double width, const Format &format=Format(), bool hidden=false); - bool setColumn(const QString &colFirst, const QString &colLast, double width, const Format &format=Format(), bool hidden=false); + + bool setColumn(int colFirst, int colLast, double width, const Format &format, bool hidden); + bool setColumn(const QString &colFirst, const QString &colLast, double width, const Format &format, bool hidden); + bool setColumnWidth(const QString &colFirst, const QString &colLast, double width); + bool setColumnFormat(const QString &colFirst, const QString &colLast, const Format &format); + bool setColumnHidden(const QString &colFirst, const QString &colLast, bool hidden); + bool setColumnWidth(int colFirst, int colLast, double width); + bool setColumnFormat(int colFirst, int colLast, const Format &format); + bool setColumnHidden(int colFirst, int colLast, bool hidden); + double columnWidth(int column); + Format columnFormat(int column); + bool isColumnHidden(int column); + + bool setRow(int rowFirst, int rowLast, double height, const Format &format, bool hidden); + bool setRow(int row, double height, const Format &format, bool hidden); + bool setRowHeight(int rowFirst,int rowLast, double height); + bool setRowFormat(int rowFirst,int rowLast, const Format &format); + bool setRowHidden(int rowFirst,int rowLast, bool hidden); + double rowHeight(int row); + Format rowFormat(int row); + bool isRowHidden(int row); + + bool groupRows(int rowFirst, int rowLast, bool collapsed = true); bool groupColumns(int colFirst, int colLast, bool collapsed = true); bool groupColumns(const QString &colFirst, const QString &colLast, bool collapsed = true); @@ -129,6 +151,8 @@ public: void setWhiteSpaceVisible(bool visible); ~Worksheet(); + + private: friend class DocumentPrivate; friend class Workbook; @@ -138,6 +162,11 @@ private: void saveToXmlFile(QIODevice *device) const; bool loadFromXmlFile(QIODevice *device); + + QList > getRowInfoList(int rowFirst, int rowLast); + QList > getColumnInfoList(int colFirst, int colLast); + QList getColumnIndexes(int colFirst, int colLast); + bool isColumnRangeValid(int colFirst, int colLast); }; QT_END_NAMESPACE_XLSX diff --git a/src/xlsx/xlsxworksheet_p.h b/src/xlsx/xlsxworksheet_p.h index 5507eeb..870003d 100644 --- a/src/xlsx/xlsxworksheet_p.h +++ b/src/xlsx/xlsxworksheet_p.h @@ -78,15 +78,50 @@ struct XlsxHyperlinkData QString tooltip; }; +// ECMA-376 Part1 18.3.1.81 +struct XlsxSheetFormatProps +{ + XlsxSheetFormatProps(int baseColWidth = 8, + bool customHeight = false, + double defaultColWidth = 0.0, + double defaultRowHeight = 15, + quint8 outlineLevelCol = 0, + quint8 outlineLevelRow = 0, + bool thickBottom = false, + bool thickTop = false, + bool zeroHeight = false) : + baseColWidth(baseColWidth), + customHeight(customHeight), + defaultColWidth(defaultColWidth), + defaultRowHeight(defaultRowHeight), + outlineLevelCol(outlineLevelCol), + outlineLevelRow(outlineLevelRow), + thickBottom(thickBottom), + thickTop(thickTop), + zeroHeight(zeroHeight) { + } + + int baseColWidth; + bool customHeight; + double defaultColWidth; + double defaultRowHeight; + quint8 outlineLevelCol; + quint8 outlineLevelRow; + bool thickBottom; + bool thickTop; + bool zeroHeight; +}; + struct XlsxRowInfo { XlsxRowInfo(double height=0, const Format &format=Format(), bool hidden=false) : - height(height), format(format), hidden(hidden), outlineLevel(0) + customHeight(false), height(height), format(format), hidden(hidden), outlineLevel(0) , collapsed(false) { } + bool customHeight; double height; Format format; bool hidden; @@ -97,14 +132,15 @@ struct XlsxRowInfo struct XlsxColumnInfo { XlsxColumnInfo(int firstColumn=0, int lastColumn=1, double width=0, const Format &format=Format(), bool hidden=false) : - firstColumn(firstColumn), lastColumn(lastColumn), width(width), format(format), hidden(hidden) + firstColumn(firstColumn), lastColumn(lastColumn), customWidth(false), width(width), format(format), hidden(hidden) , outlineLevel(0), collapsed(false) { } int firstColumn; int lastColumn; - double width; + bool customWidth; + double width; Format format; bool hidden; int outlineLevel; @@ -137,6 +173,7 @@ public: void loadXmlColumnsInfo(QXmlStreamReader &reader); void loadXmlMergeCells(QXmlStreamReader &reader); void loadXmlDataValidations(QXmlStreamReader &reader); + void loadXmlSheetFormatProps(QXmlStreamReader &reader); void loadXmlSheetViews(QXmlStreamReader &reader); void loadXmlHyperlinks(QXmlStreamReader &reader); @@ -166,6 +203,8 @@ public: int default_row_height; bool default_row_zeroed; + XlsxSheetFormatProps sheetFormatProps; + bool windowProtection; bool showFormulas; bool showGridLines; @@ -176,6 +215,9 @@ public: bool showRuler; bool showOutlineSymbols; bool showWhiteSpace; + +private: + static double calculateColWidth(int characters); }; } diff --git a/tests/auto/worksheet/tst_worksheet.cpp b/tests/auto/worksheet/tst_worksheet.cpp index 0f8cdae..e6aa54c 100644 --- a/tests/auto/worksheet/tst_worksheet.cpp +++ b/tests/auto/worksheet/tst_worksheet.cpp @@ -82,10 +82,10 @@ void WorksheetTest::testSheetView() void WorksheetTest::testSetColumn() { QXlsx::Worksheet sheet("", 1, 0, QXlsx::Worksheet::F_NewFromScratch); - sheet.setColumn(1, 11, 20.0); //"A:K" - sheet.setColumn(4, 8, 10.0); //"D:H" - sheet.setColumn(6, 6, 15.0); //"F:F" - sheet.setColumn(1, 9, 8.8); //"A:H" + sheet.setColumnWidth(1, 11, 20.0); //"A:K" + sheet.setColumnWidth(4, 8, 10.0); //"D:H" + sheet.setColumnWidth(6, 6, 15.0); //"F:F" + sheet.setColumnWidth(1, 9, 8.8); //"A:H" QByteArray xmldata = sheet.saveToXmlData();