mirror of
https://github.com/QtExcel/QXlsx.git
synced 2025-02-06 05:08:22 +08:00
Create a CellTable class that stores cells with QHash
QMap is too slow to use as storage for cells, with QHash I was able cut writeBool() & friends time by half.
This commit is contained in:
parent
ee6b265b07
commit
0868573fd4
@ -9,11 +9,22 @@
|
|||||||
|
|
||||||
QT_BEGIN_NAMESPACE_XLSX
|
QT_BEGIN_NAMESPACE_XLSX
|
||||||
|
|
||||||
|
const int XLSX_ROW_MAX = 1048576;
|
||||||
|
const int XLSX_COLUMN_MAX = 16384;
|
||||||
|
const int XLSX_STRING_MAX = 32767;
|
||||||
|
|
||||||
class QXLSX_EXPORT CellReference
|
class QXLSX_EXPORT CellReference
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CellReference();
|
CellReference();
|
||||||
CellReference(int row, int column);
|
/*!
|
||||||
|
Constructs the Reference from the given \a row, and \a column.
|
||||||
|
*/
|
||||||
|
constexpr CellReference(int row, int column)
|
||||||
|
: _row(row)
|
||||||
|
, _column(column)
|
||||||
|
{
|
||||||
|
}
|
||||||
CellReference(const QString &cell);
|
CellReference(const QString &cell);
|
||||||
CellReference(const char *cell);
|
CellReference(const char *cell);
|
||||||
CellReference(const CellReference &other);
|
CellReference(const CellReference &other);
|
||||||
@ -36,9 +47,15 @@ public:
|
|||||||
return _row != other._row || _column != other._column;
|
return _row != other._row || _column != other._column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool operator>(const CellReference &other) const
|
||||||
|
{
|
||||||
|
return _row > other._row || _column != other._column;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init(const QString &cell);
|
void init(const QString &cell);
|
||||||
int _row, _column;
|
int _row{-1};
|
||||||
|
int _column{-1};
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE_XLSX
|
QT_END_NAMESPACE_XLSX
|
||||||
|
@ -16,17 +16,13 @@
|
|||||||
#include <QSharedPointer>
|
#include <QSharedPointer>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include <QtGlobal>
|
#include <QHash>
|
||||||
|
|
||||||
class QXmlStreamWriter;
|
class QXmlStreamWriter;
|
||||||
class QXmlStreamReader;
|
class QXmlStreamReader;
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE_XLSX
|
QT_BEGIN_NAMESPACE_XLSX
|
||||||
|
|
||||||
const int XLSX_ROW_MAX = 1048576;
|
|
||||||
const int XLSX_COLUMN_MAX = 16384;
|
|
||||||
const int XLSX_STRING_MAX = 32767;
|
|
||||||
|
|
||||||
class SharedStrings;
|
class SharedStrings;
|
||||||
|
|
||||||
struct XlsxHyperlinkData {
|
struct XlsxHyperlinkData {
|
||||||
@ -137,6 +133,53 @@ struct XlsxColumnInfo {
|
|||||||
bool collapsed;
|
bool collapsed;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CellTable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static QList<int> sorteIntList(QList<int> &&keys) {
|
||||||
|
std::sort(keys.begin(), keys.end());
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QList<int> sortedRows() const {
|
||||||
|
QList<int> keys = cells.keys();
|
||||||
|
std::sort(keys.begin(), keys.end());
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setValue(int row, int column, const std::shared_ptr<Cell> &cell) {
|
||||||
|
cells[row].insert(column, cell);
|
||||||
|
firstRow = qMin(firstRow, row);
|
||||||
|
firstColumn = qMin(firstColumn, column);
|
||||||
|
lastRow = qMin(lastRow, row);
|
||||||
|
lastColumn = qMin(lastColumn, column);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Cell> cellAt(int row, int column) const{
|
||||||
|
return cells.value(row).value(column);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool contains(int row, int column) const{
|
||||||
|
auto it = cells.find(row);
|
||||||
|
if (it != cells.end()) {
|
||||||
|
return it->contains(column);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isEmpty() const {
|
||||||
|
return cells.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
// It's faster with a single QHash, but in Qt5 it's capacity limits
|
||||||
|
// how much cells we can hold
|
||||||
|
QHash<int, QHash<int, std::shared_ptr<Cell>>> cells;
|
||||||
|
int firstRow = -1;
|
||||||
|
int firstColumn = -1;
|
||||||
|
int lastRow = -1;
|
||||||
|
int lastColumn = -1;
|
||||||
|
};
|
||||||
|
|
||||||
class WorksheetPrivate : public AbstractSheetPrivate
|
class WorksheetPrivate : public AbstractSheetPrivate
|
||||||
{
|
{
|
||||||
Q_DECLARE_PUBLIC(Worksheet)
|
Q_DECLARE_PUBLIC(Worksheet)
|
||||||
@ -182,7 +225,7 @@ public:
|
|||||||
SharedStrings *sharedStrings() const;
|
SharedStrings *sharedStrings() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QMap<int, QMap<int, std::shared_ptr<Cell>>> cellTable;
|
CellTable cellTable;
|
||||||
|
|
||||||
QMap<int, QMap<int, QString>> comments;
|
QMap<int, QMap<int, QString>> comments;
|
||||||
QMap<int, QMap<int, QSharedPointer<XlsxHyperlinkData>>> urlTable;
|
QMap<int, QMap<int, QSharedPointer<XlsxHyperlinkData>>> urlTable;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// xlsxcellreference.cpp
|
// xlsxcellreference.cpp
|
||||||
|
|
||||||
#include "xlsxcellreference.h"
|
#include "xlsxcellreference.h"
|
||||||
|
#include "xlsxworksheet_p.h"
|
||||||
|
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
@ -62,20 +63,7 @@ int col_from_name(const QString &col_str)
|
|||||||
/*!
|
/*!
|
||||||
Constructs an invalid Cell Reference
|
Constructs an invalid Cell Reference
|
||||||
*/
|
*/
|
||||||
CellReference::CellReference()
|
CellReference::CellReference() = default;
|
||||||
: _row(-1)
|
|
||||||
, _column(-1)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Constructs the Reference from the given \a row, and \a column.
|
|
||||||
*/
|
|
||||||
CellReference::CellReference(int row, int column)
|
|
||||||
: _row(row)
|
|
||||||
, _column(column)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\overload
|
\overload
|
||||||
|
@ -76,23 +76,21 @@ void WorksheetPrivate::calculateSpans() const
|
|||||||
int span_max = -1;
|
int span_max = -1;
|
||||||
|
|
||||||
for (int row_num = dimension.firstRow(); row_num <= dimension.lastRow(); row_num++) {
|
for (int row_num = dimension.firstRow(); row_num <= dimension.lastRow(); row_num++) {
|
||||||
auto it = cellTable.constFind(row_num);
|
for (int col_num = dimension.firstColumn(); col_num <= dimension.lastColumn();
|
||||||
if (it != cellTable.constEnd()) {
|
col_num++) {
|
||||||
for (int col_num = dimension.firstColumn(); col_num <= dimension.lastColumn();
|
if (cellTable.contains(row_num, col_num)) {
|
||||||
col_num++) {
|
if (span_max == -1) {
|
||||||
if (it->contains(col_num)) {
|
span_min = col_num;
|
||||||
if (span_max == -1) {
|
span_max = col_num;
|
||||||
|
} else {
|
||||||
|
if (col_num < span_min)
|
||||||
span_min = col_num;
|
span_min = col_num;
|
||||||
|
else if (col_num > span_max)
|
||||||
span_max = col_num;
|
span_max = col_num;
|
||||||
} else {
|
|
||||||
if (col_num < span_min)
|
|
||||||
span_min = col_num;
|
|
||||||
else if (col_num > span_max)
|
|
||||||
span_max = col_num;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cIt = comments.constFind(row_num);
|
auto cIt = comments.constFind(row_num);
|
||||||
if (cIt != comments.constEnd()) {
|
if (cIt != comments.constEnd()) {
|
||||||
for (int col_num = dimension.firstColumn(); col_num <= dimension.lastColumn();
|
for (int col_num = dimension.firstColumn(); col_num <= dimension.lastColumn();
|
||||||
@ -190,13 +188,9 @@ Worksheet *Worksheet::copy(const QString &distName, int distId) const
|
|||||||
|
|
||||||
sheet_d->dimension = d->dimension;
|
sheet_d->dimension = d->dimension;
|
||||||
|
|
||||||
QMapIterator<int, QMap<int, std::shared_ptr<Cell>>> it(d->cellTable);
|
for (auto it = d->cellTable.cells.begin(); it != d->cellTable.cells.end(); ++it) {
|
||||||
while (it.hasNext()) {
|
|
||||||
it.next();
|
|
||||||
int row = it.key();
|
int row = it.key();
|
||||||
QMapIterator<int, std::shared_ptr<Cell>> it2(it.value());
|
for (auto it2 = it.value().begin(); it2 != it.value().end(); ++it2) {
|
||||||
while (it2.hasNext()) {
|
|
||||||
it2.next();
|
|
||||||
int col = it2.key();
|
int col = it2.key();
|
||||||
|
|
||||||
auto cell = std::make_shared<Cell>(it2.value().get());
|
auto cell = std::make_shared<Cell>(it2.value().get());
|
||||||
@ -205,10 +199,20 @@ Worksheet *Worksheet::copy(const QString &distName, int distId) const
|
|||||||
if (cell->cellType() == Cell::SharedStringType)
|
if (cell->cellType() == Cell::SharedStringType)
|
||||||
d->workbook->sharedStrings()->addSharedString(cell->d_ptr->richString);
|
d->workbook->sharedStrings()->addSharedString(cell->d_ptr->richString);
|
||||||
|
|
||||||
sheet_d->cellTable[row][col] = cell;
|
sheet_d->cellTable.setValue(row, col, cell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for (auto it = d->cellTable.cells.begin(); it != d->cellTable.cells.end(); ++it) {
|
||||||
|
// auto cell = std::make_shared<Cell>(it.value().get());
|
||||||
|
// cell->d_ptr->parent = sheet;
|
||||||
|
|
||||||
|
// if (cell->cellType() == Cell::SharedStringType)
|
||||||
|
// d->workbook->sharedStrings()->addSharedString(cell->d_ptr->richString);
|
||||||
|
|
||||||
|
// sheet_d->cellTable.setValue(CellTable::row(it.key()), CellTable::column(it.key()), cell);
|
||||||
|
// }
|
||||||
|
|
||||||
sheet_d->merges = d->merges;
|
sheet_d->merges = d->merges;
|
||||||
// sheet_d->rowsInfo = d->rowsInfo;
|
// sheet_d->rowsInfo = d->rowsInfo;
|
||||||
// sheet_d->colsInfo = d->colsInfo;
|
// sheet_d->colsInfo = d->colsInfo;
|
||||||
@ -557,23 +561,17 @@ Cell *Worksheet::cellAt(const CellReference &row_column) const
|
|||||||
Cell *Worksheet::cellAt(int row, int col) const
|
Cell *Worksheet::cellAt(int row, int col) const
|
||||||
{
|
{
|
||||||
Q_D(const Worksheet);
|
Q_D(const Worksheet);
|
||||||
auto it = d->cellTable.constFind(row);
|
return d->cellTable.cellAt(row, col).get();
|
||||||
if (it == d->cellTable.constEnd())
|
|
||||||
return nullptr;
|
|
||||||
if (!it->contains(col))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
return (*it)[col].get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Format WorksheetPrivate::cellFormat(int row, int col) const
|
Format WorksheetPrivate::cellFormat(int row, int col) const
|
||||||
{
|
{
|
||||||
auto it = cellTable.constFind(row);
|
auto cell = cellTable.cellAt(row, col);
|
||||||
if (it == cellTable.constEnd())
|
if (cell) {
|
||||||
return Format();
|
return cell->format();
|
||||||
if (!it->contains(col))
|
}
|
||||||
return Format();
|
|
||||||
return (*it)[col]->format();
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -615,7 +613,7 @@ bool Worksheet::writeString(int row, int column, const RichString &value, const
|
|||||||
d->workbook->styles()->addXfFormat(fmt);
|
d->workbook->styles()->addXfFormat(fmt);
|
||||||
auto cell = std::make_shared<Cell>(value.toPlainString(), Cell::SharedStringType, fmt, this);
|
auto cell = std::make_shared<Cell>(value.toPlainString(), Cell::SharedStringType, fmt, this);
|
||||||
cell->d_ptr->richString = value;
|
cell->d_ptr->richString = value;
|
||||||
d->cellTable[row][column] = cell;
|
d->cellTable.setValue(row, column, cell);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -687,7 +685,9 @@ bool Worksheet::writeInlineString(int row, int column, const QString &value, con
|
|||||||
|
|
||||||
Format fmt = format.isValid() ? format : d->cellFormat(row, column);
|
Format fmt = format.isValid() ? format : d->cellFormat(row, column);
|
||||||
d->workbook->styles()->addXfFormat(fmt);
|
d->workbook->styles()->addXfFormat(fmt);
|
||||||
d->cellTable[row][column] = std::make_shared<Cell>(value, Cell::InlineStringType, fmt, this);
|
auto cell = std::make_shared<Cell>(value, Cell::InlineStringType, fmt, this);
|
||||||
|
d->cellTable.setValue(row, column, cell);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -716,7 +716,9 @@ bool Worksheet::writeNumeric(int row, int column, double value, const Format &fo
|
|||||||
|
|
||||||
Format fmt = format.isValid() ? format : d->cellFormat(row, column);
|
Format fmt = format.isValid() ? format : d->cellFormat(row, column);
|
||||||
d->workbook->styles()->addXfFormat(fmt);
|
d->workbook->styles()->addXfFormat(fmt);
|
||||||
d->cellTable[row][column] = std::make_shared<Cell>(value, Cell::NumberType, fmt, this);
|
auto cell = std::make_shared<Cell>(value, Cell::NumberType, fmt, this);
|
||||||
|
d->cellTable.setValue(row, column, cell);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -768,7 +770,7 @@ bool Worksheet::writeFormula(int row,
|
|||||||
|
|
||||||
auto data = std::make_shared<Cell>(result, Cell::NumberType, fmt, this);
|
auto data = std::make_shared<Cell>(result, Cell::NumberType, fmt, this);
|
||||||
data->d_ptr->formula = formula;
|
data->d_ptr->formula = formula;
|
||||||
d->cellTable[row][column] = data;
|
d->cellTable.setValue(row, column, data);
|
||||||
|
|
||||||
CellRange range = formula.reference();
|
CellRange range = formula.reference();
|
||||||
if (formula.formulaType() == CellFormula::SharedType) {
|
if (formula.formulaType() == CellFormula::SharedType) {
|
||||||
@ -782,7 +784,7 @@ bool Worksheet::writeFormula(int row,
|
|||||||
} else {
|
} else {
|
||||||
auto newCell = std::make_shared<Cell>(result, Cell::NumberType, fmt, this);
|
auto newCell = std::make_shared<Cell>(result, Cell::NumberType, fmt, this);
|
||||||
newCell->d_ptr->formula = sf;
|
newCell->d_ptr->formula = sf;
|
||||||
d->cellTable[r][c] = newCell;
|
d->cellTable.setValue(row, column, newCell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -819,7 +821,8 @@ bool Worksheet::writeBlank(int row, int column, const Format &format)
|
|||||||
d->workbook->styles()->addXfFormat(fmt);
|
d->workbook->styles()->addXfFormat(fmt);
|
||||||
|
|
||||||
// Note: NumberType with an invalid QVariant value means blank.
|
// Note: NumberType with an invalid QVariant value means blank.
|
||||||
d->cellTable[row][column] = std::make_shared<Cell>(QVariant{}, Cell::NumberType, fmt, this);
|
auto cell = std::make_shared<Cell>(QVariant{}, Cell::NumberType, fmt, this);
|
||||||
|
d->cellTable.setValue(row, column, cell);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -848,7 +851,8 @@ bool Worksheet::writeBool(int row, int column, bool value, const Format &format)
|
|||||||
|
|
||||||
Format fmt = format.isValid() ? format : d->cellFormat(row, column);
|
Format fmt = format.isValid() ? format : d->cellFormat(row, column);
|
||||||
d->workbook->styles()->addXfFormat(fmt);
|
d->workbook->styles()->addXfFormat(fmt);
|
||||||
d->cellTable[row][column] = std::make_shared<Cell>(value, Cell::BooleanType, fmt, this);
|
auto cell = std::make_shared<Cell>(value, Cell::BooleanType, fmt, this);
|
||||||
|
d->cellTable.setValue(row, column, cell);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -884,7 +888,8 @@ bool Worksheet::writeDateTime(int row, int column, const QDateTime &dt, const Fo
|
|||||||
|
|
||||||
double value = datetimeToNumber(dt, d->workbook->isDate1904());
|
double value = datetimeToNumber(dt, d->workbook->isDate1904());
|
||||||
|
|
||||||
d->cellTable[row][column] = std::make_shared<Cell>(value, Cell::NumberType, fmt, this);
|
auto cell = std::make_shared<Cell>(value, Cell::NumberType, fmt, this);
|
||||||
|
d->cellTable.setValue(row, column, cell);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -914,7 +919,8 @@ bool Worksheet::writeDate(int row, int column, const QDate &dt, const Format &fo
|
|||||||
|
|
||||||
double value = datetimeToNumber(QDateTime(dt, QTime(0, 0, 0)), d->workbook->isDate1904());
|
double value = datetimeToNumber(QDateTime(dt, QTime(0, 0, 0)), d->workbook->isDate1904());
|
||||||
|
|
||||||
d->cellTable[row][column] = std::make_shared<Cell>(value, Cell::NumberType, fmt, this);
|
auto cell = std::make_shared<Cell>(value, Cell::NumberType, fmt, this);
|
||||||
|
d->cellTable.setValue(row, column, cell);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -947,8 +953,8 @@ bool Worksheet::writeTime(int row, int column, const QTime &t, const Format &for
|
|||||||
fmt.setNumberFormat(QStringLiteral("hh:mm:ss"));
|
fmt.setNumberFormat(QStringLiteral("hh:mm:ss"));
|
||||||
d->workbook->styles()->addXfFormat(fmt);
|
d->workbook->styles()->addXfFormat(fmt);
|
||||||
|
|
||||||
d->cellTable[row][column] =
|
auto cell = std::make_shared<Cell>(timeToNumber(t), Cell::NumberType, fmt, this);
|
||||||
std::make_shared<Cell>(timeToNumber(t), Cell::NumberType, fmt, this);
|
d->cellTable.setValue(row, column, cell);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1023,8 +1029,8 @@ bool Worksheet::writeHyperlink(int row,
|
|||||||
|
|
||||||
// Write the hyperlink string as normal string.
|
// Write the hyperlink string as normal string.
|
||||||
d->sharedStrings()->addSharedString(displayString);
|
d->sharedStrings()->addSharedString(displayString);
|
||||||
d->cellTable[row][column] =
|
auto cell = std::make_shared<Cell>(displayString, Cell::SharedStringType, fmt, this);
|
||||||
std::make_shared<Cell>(displayString, Cell::SharedStringType, fmt, this);
|
d->cellTable.setValue(row, column, cell);
|
||||||
|
|
||||||
// Store the hyperlink data in a separate table
|
// Store the hyperlink data in a separate table
|
||||||
d->urlTable[row][column] = QSharedPointer<XlsxHyperlinkData>(new XlsxHyperlinkData(
|
d->urlTable[row][column] = QSharedPointer<XlsxHyperlinkData>(new XlsxHyperlinkData(
|
||||||
@ -1477,10 +1483,11 @@ bool Worksheet::setStartPage(int spagen)
|
|||||||
void WorksheetPrivate::saveXmlSheetData(QXmlStreamWriter &writer) const
|
void WorksheetPrivate::saveXmlSheetData(QXmlStreamWriter &writer) const
|
||||||
{
|
{
|
||||||
calculateSpans();
|
calculateSpans();
|
||||||
|
|
||||||
for (int row_num = dimension.firstRow(); row_num <= dimension.lastRow(); row_num++) {
|
for (int row_num = dimension.firstRow(); row_num <= dimension.lastRow(); row_num++) {
|
||||||
auto ctIt = cellTable.constFind(row_num);
|
auto ctIt = cellTable.cells.constFind(row_num);
|
||||||
auto riIt = rowsInfo.constFind(row_num);
|
auto riIt = rowsInfo.constFind(row_num);
|
||||||
if (ctIt == cellTable.constEnd() && riIt == rowsInfo.constEnd() &&
|
if (ctIt == cellTable.cells.constEnd() && riIt == rowsInfo.constEnd() &&
|
||||||
!comments.contains(row_num)) {
|
!comments.contains(row_num)) {
|
||||||
// Only process rows with cell data / comments / formatting
|
// Only process rows with cell data / comments / formatting
|
||||||
continue;
|
continue;
|
||||||
@ -1525,11 +1532,12 @@ void WorksheetPrivate::saveXmlSheetData(QXmlStreamWriter &writer) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Write cell data if row contains filled cells
|
// Write cell data if row contains filled cells
|
||||||
if (ctIt != cellTable.constEnd()) {
|
if (ctIt != cellTable.cells.constEnd()) {
|
||||||
for (int col_num = dimension.firstColumn(); col_num <= dimension.lastColumn();
|
for (int col_num = dimension.firstColumn(); col_num <= dimension.lastColumn();
|
||||||
col_num++) {
|
col_num++) {
|
||||||
if (ctIt->contains(col_num)) {
|
auto cellIt = ctIt->find(col_num);
|
||||||
saveXmlCellData(writer, row_num, col_num, (*ctIt)[col_num]);
|
if (cellIt != ctIt->end()) {
|
||||||
|
saveXmlCellData(writer, row_num, col_num, *cellIt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2443,7 +2451,7 @@ void WorksheetPrivate::loadXmlSheetData(QXmlStreamReader &reader)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cellTable[pos.row()][pos.column()] = cell;
|
cellTable.setValue(pos.row(), pos.column(), cell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2820,25 +2828,7 @@ void WorksheetPrivate::validateDimension()
|
|||||||
if (dimension.isValid() || cellTable.isEmpty())
|
if (dimension.isValid() || cellTable.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto firstRow = cellTable.constBegin().key();
|
CellRange cr(cellTable.firstRow, cellTable.firstColumn, cellTable.lastRow, cellTable.lastColumn);
|
||||||
|
|
||||||
const auto lastRow = (--cellTable.constEnd()).key();
|
|
||||||
|
|
||||||
int firstColumn = -1;
|
|
||||||
int lastColumn = -1;
|
|
||||||
|
|
||||||
for (auto &&it = cellTable.constBegin(); it != cellTable.constEnd(); ++it) {
|
|
||||||
Q_ASSERT(!it.value().isEmpty());
|
|
||||||
|
|
||||||
if (firstColumn == -1 || it.value().constBegin().key() < firstColumn)
|
|
||||||
firstColumn = it.value().constBegin().key();
|
|
||||||
|
|
||||||
if (lastColumn == -1 || (--it.value().constEnd()).key() > lastColumn) {
|
|
||||||
lastColumn = (--it.value().constEnd()).key();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CellRange cr(firstRow, firstColumn, lastRow, lastColumn);
|
|
||||||
|
|
||||||
if (cr.isValid())
|
if (cr.isValid())
|
||||||
dimension = cr;
|
dimension = cr;
|
||||||
@ -2875,33 +2865,27 @@ QVector<CellLocation> Worksheet::getFullCells(int *maxRow, int *maxCol)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMapIterator<int, QMap<int, std::shared_ptr<Cell>>> _it(d->cellTable);
|
for (const auto row : d->cellTable.sortedRows()) {
|
||||||
|
auto &columns = d->cellTable.cells[row];
|
||||||
while (_it.hasNext()) {
|
auto columnsSorted = CellTable::sorteIntList(columns.keys());
|
||||||
_it.next();
|
for (const auto col : columnsSorted) {
|
||||||
|
// It's faster to iterate but cellTable is unordered which might not
|
||||||
int keyI = _it.key(); // key (cell row)
|
// be what callers want?
|
||||||
QMapIterator<int, std::shared_ptr<Cell>> _iit(_it.value()); // value
|
auto cell = std::make_shared<Cell>(columns.value(col).get());
|
||||||
|
|
||||||
while (_iit.hasNext()) {
|
|
||||||
_iit.next();
|
|
||||||
|
|
||||||
int keyII = _iit.key(); // key (cell column)
|
|
||||||
std::shared_ptr<Cell> ptrCell = _iit.value(); // value
|
|
||||||
|
|
||||||
CellLocation cl;
|
CellLocation cl;
|
||||||
|
|
||||||
cl.row = keyI;
|
cl.row = row;
|
||||||
if (keyI > (*maxRow)) {
|
if (row > (*maxRow)) {
|
||||||
(*maxRow) = keyI;
|
(*maxRow) = row;
|
||||||
}
|
}
|
||||||
|
|
||||||
cl.col = keyII;
|
cl.col = col;
|
||||||
if (keyII > (*maxCol)) {
|
if (col > (*maxCol)) {
|
||||||
(*maxCol) = keyII;
|
(*maxCol) = col;
|
||||||
}
|
}
|
||||||
|
|
||||||
cl.cell = ptrCell;
|
cl.cell = cell;
|
||||||
|
|
||||||
ret.push_back(cl);
|
ret.push_back(cl);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user