Browse Source

Issue #32: Merge branch 'master' of github.com:EddoH/QtXlsxWriter into EddoH

Conflicts:
	src/xlsx/xlsxworksheet.cpp
	src/xlsx/xlsxworksheet_p.h
master
Debao Zhang 11 years ago
parent
commit
9ce8b92b4f
  1. 222
      src/xlsx/xlsxdocument.cpp
  2. 28
      src/xlsx/xlsxdocument.h
  3. 421
      src/xlsx/xlsxworksheet.cpp
  4. 23
      src/xlsx/xlsxworksheet.h
  5. 50
      src/xlsx/xlsxworksheet_p.h
  6. 8
      tests/auto/worksheet/tst_worksheet.cpp

222
src/xlsx/xlsxdocument.cpp

@ -515,47 +515,227 @@ bool Document::unmergeCells(const CellRange &range)
}
/*!
Sets the properties of \a row with the given \a height, \a format and \a hidden.
\a row is 1-indexed.
Sets width in characters of a range of columns.
Returns true on success.
*/
bool Document::setColumnWidth(const CellRange &range, double width)
{
if (Worksheet *sheet = currentWorksheet())
return sheet->setColumnWidth(range, width);
return false;
}
Returns false if failed.
/*!
Sets format property of a range of columns.
Returns true on success.
*/
bool Document::setRow(int row, double height, const Format &format, bool hidden)
bool Document::setColumnFormat(const CellRange &range, const Format &format)
{
if (Worksheet *sheet = currentWorksheet())
return sheet->setRow(row, height, format, hidden);
return sheet->setColumnFormat(range, format);
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
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.
\a colFirst and \a colLast are all 1-indexed.
Sets hidden property of a range of columns. Columns are 1-indexed.
Hidden columns are not visible.
Returns true on success.
*/
bool Document::setColumnHidden(const CellRange &range, bool hidden)
{
if (Worksheet *sheet = currentWorksheet())
return sheet->setColumnWidth(range, hidden);
return false;
}
Return false if failed.
/*!
Sets width in characters of a range of columns. Columns are 1-indexed.
Returns true on success.
*/
bool Document::setColumn(int colFirst, int colLast, double width, const Format &format, bool hidden)
bool Document::setColumnWidth(int column, double width)
{
return setColumnWidth(column,column,width);
}
/*!
Sets format property of a range of columns. Columns are 1-indexed.
*/
bool Document::setColumnFormat(int column, const Format &format)
{
return setColumnFormat(column,column,format);
}
/*!
Sets hidden property of a column. Columns are 1-indexed.
*/
bool Document::setColumnHidden(int column, bool hidden)
{
return setColumnHidden(column,column,hidden);
}
/*!
Sets width in characters of a range of columns. Columns are 1-indexed.
Returns true on success.
*/
bool Document::setColumnWidth(int colFirst, int colLast, double width)
{
if (Worksheet *sheet = currentWorksheet())
return sheet->setColumn(colFirst, colLast, width, format, hidden);
return sheet->setColumnWidth(colFirst, colLast, width);
return false;
}
/*!
\overload
Sets format property of a range of columns. Columns are 1-indexed.
*/
bool Document::setColumnFormat(int colFirst, int colLast, const Format &format)
{
if (Worksheet *sheet = currentWorksheet())
return sheet->setColumnFormat(colFirst, colLast, format);
return false;
}
Sets column width and format for all columns from \a colFirst to \a colLast with
the given \a width and \a format. Column
\a 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.
\a colFirst and \a colLast should be "A", "B", "C", ...
/*!
Sets hidden property of a range of columns. Columns are 1-indexed.
*/
bool Document::setColumn(const QString &colFirst, const QString &colLast, double width, const Format &format, bool hidden)
bool Document::setColumnHidden(int colFirst, int colLast, bool hidden)
{
if (Worksheet *sheet = currentWorksheet())
return sheet->setColumnHidden(colFirst, colLast, hidden);
return false;
}
/*!
Returns width of the column in characters of the normal font. Columns are 1-indexed.
*/
double Document::columnWidth(int column)
{
if (Worksheet *sheet = currentWorksheet())
return sheet->columnWidth(column);
return 0.0;
}
/*!
Returns formatting of the column. Columns are 1-indexed.
*/
Format Document::columnFormat(int column)
{
if (Worksheet *sheet = currentWorksheet())
return sheet->columnFormat(column);
return Format();
}
/*!
Returns true if column is hidden. Columns are 1-indexed.
*/
bool Document::isColumnHidden(int column)
{
if (Worksheet *sheet = currentWorksheet())
return sheet->isColumnHidden(column);
return false;
}
/*!
Sets the \a format of the row \a row.
Rows are 1-indexed.
Returns true if success.
*/
bool Document::setRowFormat(int row, const Format &format)
{
return setRowFormat(row,row, format);
}
/*!
Sets the \a format of the rows including and between \a rowFirst and \a rowLast.
Rows are 1-indexed.
Returns true if success.
*/
bool Document::setRowFormat(int rowFirst, int rowLast, const Format &format)
{
if (Worksheet *sheet = currentWorksheet())
return sheet->setRowFormat(rowFirst, rowLast, format);
return false;
}
/*!
Sets the \a hidden property of the row \a row.
Rows are 1-indexed. If hidden is true rows will not be visible.
Returns true if success.
*/
bool Document::setRowHidden(int row, bool hidden)
{
return setRowHidden(row,row,hidden);
}
/*!
Sets the \a hidden property of the rows including and between \a rowFirst and \a rowLast.
Rows are 1-indexed. If hidden is true rows will not be visible.
Returns true if success.
*/
bool Document::setRowHidden(int rowFirst, int rowLast, bool hidden)
{
if (Worksheet *sheet = currentWorksheet())
return sheet->setRowHidden(rowFirst, rowLast, hidden);
return false;
}
/*!
Sets the \a height of the row \a row.
Row height measured in point size.
Rows are 1-indexed.
Returns true if success.
*/
bool Document::setRowHeight(int row, double height)
{
return setRowHeight(row,row,height);
}
/*!
Sets the \a height of the rows including and between \a rowFirst and \a rowLast.
Row height measured in point size.
Rows are 1-indexed.
Returns true if success.
*/
bool Document::setRowHeight(int rowFirst, int rowLast, double height)
{
if (Worksheet *sheet = currentWorksheet())
return sheet->setRowHeight(rowFirst, rowLast, height);
return false;
}
/*!
Returns height of \a row in points.
*/
double Document::rowHeight(int row)
{
if (Worksheet *sheet = currentWorksheet())
return sheet->rowHeight(row);
return 0.0;
}
/*!
Returns format of \a row.
*/
Format Document::rowFormat(int row)
{
if (Worksheet *sheet = currentWorksheet())
return sheet->rowFormat(row);
return Format();
}
/*!
Returns true if \a row is hidden.
*/
bool Document::isRowHidden(int row)
{
if (Worksheet *sheet = currentWorksheet())
return sheet->setColumn(colFirst, colLast, width, format, hidden);
return sheet->isRowHidden(row);
return false;
}

28
src/xlsx/xlsxdocument.h

@ -65,9 +65,31 @@ public:
bool mergeCells(const QString &range, const Format &format=Format());
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 CellRange &range, double width);
bool setColumnFormat(const CellRange &range, const Format &format);
bool setColumnHidden(const CellRange &range, 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);

421
src/xlsx/xlsxworksheet.cpp

@ -1291,7 +1291,6 @@ void WorksheetPrivate::saveXmlSheetData(QXmlStreamWriter &writer) const
if (row_spans.contains(span_index))
span = row_spans[span_index];
if (cellTable.contains(row_num)) {
writer.writeStartElement(QStringLiteral("row"));
writer.writeAttribute(QStringLiteral("r"), QString::number(row_num));
@ -1304,10 +1303,15 @@ 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"));
} else {
writer.writeAttribute(QStringLiteral("customHeight"), QStringLiteral("0"));
}
if (rowInfo->hidden)
writer.writeAttribute(QStringLiteral("hidden"), QStringLiteral("1"));
if (rowInfo->outlineLevel > 0)
@ -1316,17 +1320,15 @@ void WorksheetPrivate::saveXmlSheetData(QXmlStreamWriter &writer) const
writer.writeAttribute(QStringLiteral("collapsed"), QStringLiteral("1"));
}
//Write cell data if row contains filled cells
if (cellTable.contains(row_num)) {
for (int col_num = dimension.firstColumn(); col_num <= dimension.lastColumn(); col_num++) {
if (cellTable[row_num].contains(col_num)) {
saveXmlCellData(writer, row_num, col_num, cellTable[row_num][col_num]);
}
}
writer.writeEndElement(); //row
} else if (comments.contains(row_num)){
} else {
}
writer.writeEndElement(); //row
}
}
@ -1491,26 +1493,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() < 1 ? 1 : d->dimension.firstColumn();
if (d->checkDimensions(row, min_col, false, true))
return false;
d->rowsInfo[row] = QSharedPointer<XlsxRowInfo>(new XlsxRowInfo(height, format, hidden));
d->workbook->styles()->addXfFormat(format);
return true;
}
void WorksheetPrivate::splitColsInfo(int colFirst, int colLast)
{
// Split current columnInfo, for example, if "A:H" has been set,
@ -1553,78 +1535,280 @@ 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 WorksheetPrivate::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;
if (d->checkDimensions(1, colLast, ignore_row, ignore_col))
if (checkDimensions(1, colLast, ignore_row, ignore_col))
return false;
if (d->checkDimensions(1, colFirst, ignore_row, ignore_col))
if (checkDimensions(1, colFirst, ignore_row, ignore_col))
return false;
d->splitColsInfo(colFirst, colLast);
return true;
}
QList<int> WorksheetPrivate ::getColumnIndexes(int colFirst, int colLast)
{
splitColsInfo(colFirst, colLast);
QList<int> nodes;
nodes.append(colFirst);
for (int col = colFirst; col <= colLast; ++col) {
if (d->colsInfo.contains(col)) {
if (colsInfo.contains(col)) {
if (nodes.last() != col)
nodes.append(col);
int nextCol = d->colsInfo[col]->lastColumn + 1;
int nextCol = 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;
return nodes;
}
/*!
Sets width in characters of a range of columns.
Returns true on success.
*/
bool Worksheet::setColumnWidth(const CellRange &range, double width)
{
int col1 = range.firstColumn();
int col2 = range.lastColumn();
if (col1 < 0|| col2 < 0)
return false;
return setColumnWidth(col1, col2, width);
}
/*!
Sets format property of a range of columns. Columns are 1-indexed.
Returns true on success.
*/
bool Worksheet::setColumnFormat(const CellRange& range, const Format &format)
{
int col1 = range.firstColumn();
int col2 = range.lastColumn();
if (col1 < 0|| col2 < 0)
return false;
return setColumnFormat(col1, col2, format);
}
/*!
Sets hidden property of a range of columns. Columns are 1-indexed.
Hidden columns are not visible.
Returns true on success.
*/
bool Worksheet::setColumnHidden(const CellRange &range, bool hidden)
{
int col1 = range.firstColumn();
int col2 = range.lastColumn();
if (col1 < 0|| col2 < 0)
return false;
return setColumnHidden(col1, col2, hidden);
}
/*!
Sets width in characters of a range of columns. Columns are 1-indexed.
Returns true on success.
*/
bool Worksheet::setColumnWidth(int colFirst, int colLast, double width)
{
Q_D(Worksheet);
QList <QSharedPointer<XlsxColumnInfo> > columnInfoList = d->getColumnInfoList(colFirst, colLast);
foreach(QSharedPointer<XlsxColumnInfo> columnInfo, columnInfoList) {
columnInfo->width = width;
}
return (columnInfoList.count() > 0);
}
/*!
Sets format property of a range of columns. Columns are 1-indexed.
*/
bool Worksheet::setColumnFormat(int colFirst, int colLast, const Format &format)
{
Q_D(Worksheet);
QList <QSharedPointer<XlsxColumnInfo> > columnInfoList = d->getColumnInfoList(colFirst, colLast);
foreach(QSharedPointer<XlsxColumnInfo> columnInfo, columnInfoList) {
columnInfo->format = format;
}
d->workbook->styles()->addXfFormat(format);
if(columnInfoList.count() > 0) {
d->workbook->styles()->addXfFormat(format);
return true;
}
return false;
}
/*!
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
numbers 0, 1, 2, ..., 9 as rendered in the normal style's font. If format
equals 0 then format is ignored. \a colFirst and \a colLast should be "A", "B", "C", ...
Sets hidden property of a range of columns. Columns are 1-indexed.
*/
bool Worksheet::setColumn(const QString &colFirst, const QString &colLast, double width, const Format &format, bool hidden)
bool Worksheet::setColumnHidden(int colFirst, int colLast, bool hidden)
{
int col1 = xl_col_name_to_value(colFirst);
int col2 = xl_col_name_to_value(colLast);
Q_D(Worksheet);
QList <QSharedPointer<XlsxColumnInfo> > columnInfoList = d->getColumnInfoList(colFirst, colLast);
foreach(QSharedPointer<XlsxColumnInfo> columnInfo, columnInfoList) {
columnInfo->hidden = hidden;
}
return (columnInfoList.count() > 0);
}
/*!
Returns width of the column in characters of the normal font. Columns are 1-indexed.
*/
double Worksheet::columnWidth(int column)
{
Q_D(Worksheet);
QList <QSharedPointer<XlsxColumnInfo> > columnInfoList = d->getColumnInfoList(column, column);
if (columnInfoList.count() == 1) {
return columnInfoList.at(0)->width ;
}
return d->sheetFormatProps.defaultColWidth;
}
/*!
Returns formatting of the column. Columns are 1-indexed.
*/
Format Worksheet::columnFormat(int column)
{
Q_D(Worksheet);
QList <QSharedPointer<XlsxColumnInfo> > columnInfoList = d->getColumnInfoList(column, column);
if (columnInfoList.count() == 1) {
return columnInfoList.at(0)->format;
}
return Format();
}
/*!
Returns true if column is hidden. Columns are 1-indexed.
*/
bool Worksheet::isColumnHidden(int column)
{
Q_D(Worksheet);
QList <QSharedPointer<XlsxColumnInfo> > columnInfoList = d->getColumnInfoList(column, column);
if (columnInfoList.count() == 1) {
return columnInfoList.at(0)->hidden;
}
if (col1 == -1 || col2 == -1)
return false;
}
/*!
Sets the \a height of the rows including and between \a rowFirst and \a rowLast.
Row height measured in point size.
Rows are 1-indexed.
Returns true if success.
*/
bool Worksheet::setRowHeight(int rowFirst,int rowLast, double height)
{
Q_D(Worksheet);
QList <QSharedPointer<XlsxRowInfo> > rowInfoList = d->getRowInfoList(rowFirst,rowLast);
foreach(QSharedPointer<XlsxRowInfo> rowInfo, rowInfoList) {
rowInfo->height = height;
rowInfo->customHeight = true;
}
return rowInfoList.count() > 0;
}
/*!
Sets the \a format of the rows including and between \a rowFirst and \a rowLast.
Rows are 1-indexed.
Returns true if success.
*/
bool Worksheet::setRowFormat(int rowFirst,int rowLast, const Format &format)
{
Q_D(Worksheet);
QList <QSharedPointer<XlsxRowInfo> > rowInfoList = d->getRowInfoList(rowFirst,rowLast);
foreach(QSharedPointer<XlsxRowInfo> rowInfo, rowInfoList) {
rowInfo->format = format;
}
d->workbook->styles()->addXfFormat(format);
return rowInfoList.count() > 0;
}
/*!
Sets the \a hidden proeprty of the rows including and between \a rowFirst and \a rowLast.
Rows are 1-indexed. If hidden is true rows will not be visible.
Returns true if success.
*/
bool Worksheet::setRowHidden(int rowFirst,int rowLast, bool hidden)
{
Q_D(Worksheet);
QList <QSharedPointer<XlsxRowInfo> > rowInfoList = d->getRowInfoList(rowFirst,rowLast);
foreach(QSharedPointer<XlsxRowInfo> rowInfo, rowInfoList) {
rowInfo->hidden = hidden;
}
return rowInfoList.count() > 0;
}
/*!
Returns height of \a row in points.
*/
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;
}
/*!
Returns format of \a row.
*/
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;
}
/*!
Returns true if \a row is hidden.
*/
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 setColumn(col1, col2, width, format, hidden);
return d->rowsInfo[row]->hidden;
}
/*!
@ -1837,9 +2021,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"))) {
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");
@ -1961,7 +2151,11 @@ 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");
}
//Note, node may have "width" without "customWidth"
if (colAttrs.hasAttribute(QLatin1String("width"))) {
double width = colAttrs.value(QLatin1String("width")).toString().toDouble();
@ -2060,6 +2254,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().toString().toInt();
} else if(attrib.name() == QLatin1String("customHeight")) {
formatProps.customHeight = attrib.value() == QLatin1String("1");
} else if(attrib.name() == QLatin1String("defaultColWidth")) {
formatProps.defaultColWidth = attrib.value().toString().toDouble();
} else if(attrib.name() == QLatin1String("defaultRowHeight")) {
formatProps.defaultRowHeight = attrib.value().toString().toDouble();
} else if(attrib.name() == QLatin1String("outlineLevelCol")) {
formatProps.outlineLevelCol = attrib.value().toString().toInt();
} else if(attrib.name() == QLatin1String("outlineLevelRow")) {
formatProps.outlineLevelRow = attrib.value().toString().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 +2325,52 @@ void WorksheetPrivate::loadXmlHyperlinks(QXmlStreamReader &reader)
}
}
QList <QSharedPointer<XlsxColumnInfo> > WorksheetPrivate::getColumnInfoList(int colFirst, int colLast)
{
QList <QSharedPointer<XlsxColumnInfo> > columnsInfoList;
if(isColumnRangeValid(colFirst,colLast))
{
QList<int> nodes = getColumnIndexes(colFirst, colLast);
for (int idx = 0; idx < nodes.size(); ++idx) {
int colStart = nodes[idx];
if (colsInfo.contains(colStart)) {
QSharedPointer<XlsxColumnInfo> info = colsInfo[colStart];
columnsInfoList.append(info);
} else {
int colEnd = (idx == nodes.size() - 1) ? colLast : nodes[idx+1] - 1;
QSharedPointer<XlsxColumnInfo> info(new XlsxColumnInfo(colStart, colEnd));
colsInfo.insert(colFirst, info);
columnsInfoList.append(info);
for (int c = colStart; c <= colEnd; ++c)
colsInfoHelper[c] = info;
}
}
}
return columnsInfoList;
}
QList <QSharedPointer<XlsxRowInfo> > WorksheetPrivate::getRowInfoList(int rowFirst, int rowLast)
{
QList <QSharedPointer<XlsxRowInfo> > rowInfoList;
int min_col = dimension.firstColumn() < 0 ? 0 : dimension.firstColumn();
for(int row = rowFirst; row <= rowLast; ++row) {
if (checkDimensions(row, min_col, false, true))
continue;
QSharedPointer<XlsxRowInfo> rowInfo;
if ((rowsInfo[row]).isNull()){
rowsInfo[row] = QSharedPointer<XlsxRowInfo>(new XlsxRowInfo());
}
rowInfoList.append(rowsInfo[row]);
}
return rowInfoList;
}
bool Worksheet::loadFromXmlFile(QIODevice *device)
{
Q_D(Worksheet);
@ -2105,7 +2386,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")) {

23
src/xlsx/xlsxworksheet.h

@ -99,9 +99,24 @@ public:
bool unmergeCells(const CellRange &range);
QList<CellRange> 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 setColumnWidth(const CellRange& range, double width);
bool setColumnFormat(const CellRange& range, const Format &format);
bool setColumnHidden(const CellRange& range, 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 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 +144,8 @@ public:
void setWhiteSpaceVisible(bool visible);
~Worksheet();
private:
friend class DocumentPrivate;
friend class Workbook;

50
src/xlsx/xlsxworksheet_p.h

@ -79,15 +79,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;
@ -98,13 +133,14 @@ 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;
bool customWidth;
double width;
Format format;
bool hidden;
@ -138,9 +174,15 @@ 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);
QList<QSharedPointer<XlsxRowInfo> > getRowInfoList(int rowFirst, int rowLast);
QList <QSharedPointer<XlsxColumnInfo> > getColumnInfoList(int colFirst, int colLast);
QList<int> getColumnIndexes(int colFirst, int colLast);
bool isColumnRangeValid(int colFirst, int colLast);
SharedStrings *sharedStrings() const;
QMap<int, QMap<int, QSharedPointer<Cell> > > cellTable;
@ -167,6 +209,8 @@ public:
int default_row_height;
bool default_row_zeroed;
XlsxSheetFormatProps sheetFormatProps;
bool windowProtection;
bool showFormulas;
bool showGridLines;
@ -179,6 +223,8 @@ public:
bool showWhiteSpace;
QRegularExpression urlPattern;
private:
static double calculateColWidth(int characters);
};
}

8
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();

Loading…
Cancel
Save