Browse Source

Add setRow and setColumn

master
Debao Zhang 11 years ago
parent
commit
a6bfe24986
  1. 17
      examples/style/main.cpp
  2. 207
      src/xlsxworksheet.cpp
  3. 41
      src/xlsxworksheet.h

17
examples/style/main.cpp

@ -26,7 +26,22 @@ int main()
sheet->write("C5", "=44+33", format2);
sheet->write("D7", true, format2);
QXlsx::Format *format3 = workbook.addFormat();
format3->setFontBold(true);
format3->setFontColor(QColor(Qt::blue));
format3->setFontSize(20);
sheet->write(10, 0, "Hello Row Style");
sheet->write(10, 5, "Blue Color");
sheet->setRow(10, 40, format3);
QXlsx::Format *format4 = workbook.addFormat();
format4->setFontBold(true);
format4->setFontColor(QColor(Qt::magenta));
for (int row=20; row<40; row++)
for (int col=8; col<15; col++)
sheet->write(row, col, row+col);
sheet->setColumn(8, 15, 5.0, format4);
workbook.save(DATA_PATH"TestStyle.xlsx");
workbook.save(DATA_PATH"TestStyle.zip");
return 0;
}

207
src/xlsxworksheet.cpp

@ -38,6 +38,55 @@
namespace QXlsx {
struct XlsxCellData
{
enum CellDataType {
Blank,
String,
Number,
Formula,
ArrayFormula,
Boolean
};
XlsxCellData(const QVariant &data=QVariant(), CellDataType type=Blank, Format *format=0) :
value(data), dataType(type), format(format)
{
}
QVariant value;
QString formula;
CellDataType dataType;
Format *format;
};
struct XlsxRowInfo
{
XlsxRowInfo(double height, Format *format, bool hidden) :
height(height), format(format), hidden(hidden)
{
}
double height;
Format *format;
bool hidden;
};
struct XlsxColumnInfo
{
XlsxColumnInfo(int column_min, int column_max, double width, Format *format, bool hidden) :
column_min(column_min), column_max(column_max), width(width), format(format), hidden(hidden)
{
}
int column_min;
int column_max;
double width;
Format *format;
bool hidden;
};
/*!
* \brief Worksheet::Worksheet
* \param name Name of the worksheet
@ -70,6 +119,21 @@ Worksheet::Worksheet(const QString &name, int index, Workbook *parent) :
m_show_zeros = true;
}
Worksheet::~Worksheet()
{
typedef QMap<int, XlsxCellData *> RowMap;
foreach (RowMap row, m_cellTable) {
foreach (XlsxCellData *item, row)
delete item;
}
foreach (XlsxRowInfo *row, m_rowsInfo)
delete row;
foreach (XlsxColumnInfo *col, m_colsInfo)
delete col;
}
bool Worksheet::isChartsheet() const
{
return false;
@ -187,7 +251,7 @@ int Worksheet::writeString(int row, int column, const QString &value, Format *fo
SharedStrings *sharedStrings = m_workbook->sharedStrings();
int index = sharedStrings->addSharedString(content);
m_table[row][column] = XlsxCellData(index, XlsxCellData::String, format);
m_cellTable[row][column] = new XlsxCellData(index, XlsxCellData::String, format);
return error;
}
@ -196,7 +260,7 @@ int Worksheet::writeNumber(int row, int column, double value, Format *format)
if (checkDimensions(row, column))
return -1;
m_table[row][column] = XlsxCellData(value, XlsxCellData::Number, format);
m_cellTable[row][column] = new XlsxCellData(value, XlsxCellData::Number, format);
return 0;
}
@ -211,9 +275,9 @@ int Worksheet::writeFormula(int row, int column, const QString &content, Format
if (formula.startsWith("="))
formula.remove(0,1);
XlsxCellData data(result, XlsxCellData::Formula, format);
data.formula = formula;
m_table[row][column] = data;
XlsxCellData *data = new XlsxCellData(result, XlsxCellData::Formula, format);
data->formula = formula;
m_cellTable[row][column] = data;
return error;
}
@ -223,7 +287,7 @@ int Worksheet::writeBlank(int row, int column, Format *format)
if (checkDimensions(row, column))
return -1;
m_table[row][column] = XlsxCellData(QVariant(), XlsxCellData::Blank, format);
m_cellTable[row][column] = new XlsxCellData(QVariant(), XlsxCellData::Blank, format);
return 0;
}
@ -232,7 +296,7 @@ int Worksheet::writeBool(int row, int column, bool value, Format *format)
if (checkDimensions(row, column))
return -1;
m_table[row][column] = XlsxCellData(value, XlsxCellData::Boolean, format);
m_cellTable[row][column] = new XlsxCellData(value, XlsxCellData::Boolean, format);
return 0;
}
@ -304,6 +368,22 @@ void Worksheet::saveToXmlFile(QIODevice *device)
// writer.writeAttribute("x14ac:dyDescent", "0.25");
writer.writeEndElement();//sheetFormatPr
writer.writeStartElement("cols");
foreach (XlsxColumnInfo *col_info, m_colsInfo) {
writer.writeStartElement("col");
writer.writeAttribute("min", QString::number(col_info->column_min));
writer.writeAttribute("max", QString::number(col_info->column_max));
writer.writeAttribute("width", QString::number(col_info->width, 'g', 15));
if (col_info->format)
writer.writeAttribute("style", QString::number(col_info->format->xfIndex()));
if (col_info->hidden)
writer.writeAttribute("hidden", "1");
if (col_info->width)
writer.writeAttribute("customWidth", "1");
writer.writeEndElement();//col
}
writer.writeEndElement();//cols
writer.writeStartElement("sheetData");
if (m_dim_rowmax == INT32_MIN) {
//If the max dimensions are equal to INT32_MIN, then there is no data to write
@ -350,7 +430,7 @@ void Worksheet::writeSheetData(XmlStreamWriter &writer)
{
calculateSpans();
for (int row_num = m_dim_rowmin; row_num <= m_dim_rowmax; row_num++) {
if (!(m_table.contains(row_num) || m_comments.contains(row_num))) {
if (!(m_cellTable.contains(row_num) || m_comments.contains(row_num) || m_rowsInfo.contains(row_num))) {
//Only process rows with cell data / comments / formatting
continue;
}
@ -360,14 +440,30 @@ void Worksheet::writeSheetData(XmlStreamWriter &writer)
if (m_row_spans.contains(span_index))
span = m_row_spans[span_index];
if (m_table.contains(row_num)) {
if (m_cellTable.contains(row_num)) {
writer.writeStartElement("row");
writer.writeAttribute("r", QString::number(row_num + 1));
if (!span.isEmpty())
writer.writeAttribute("spans", span);
if (m_rowsInfo.contains(row_num)) {
XlsxRowInfo *rowInfo = m_rowsInfo[row_num];
if (rowInfo->format) {
writer.writeAttribute("s", QString::number(rowInfo->format->xfIndex()));
writer.writeAttribute("customFormat", "1");
}
if (rowInfo->height != 15) {
writer.writeAttribute("ht", QString::number(rowInfo->height));
writer.writeAttribute("customHeight", "1");
}
if (rowInfo->hidden)
writer.writeAttribute("hidden", "1");
}
for (int col_num = m_dim_colmin; col_num <= m_dim_colmax; col_num++) {
if (m_table[row_num].contains(col_num)) {
writeCellData(writer, row_num, col_num, m_table[row_num][col_num]);
if (m_cellTable[row_num].contains(col_num)) {
writeCellData(writer, row_num, col_num, m_cellTable[row_num][col_num]);
}
}
writer.writeEndElement(); //row
@ -376,11 +472,10 @@ void Worksheet::writeSheetData(XmlStreamWriter &writer)
} else {
}
}
}
void Worksheet::writeCellData(XmlStreamWriter &writer, int row, int col, const XlsxCellData &data)
void Worksheet::writeCellData(XmlStreamWriter &writer, int row, int col, XlsxCellData *cell)
{
//This is the innermost loop so efficiency is important.
QString cell_range = xl_rowcol_to_cell_fast(row, col);
@ -389,28 +484,32 @@ void Worksheet::writeCellData(XmlStreamWriter &writer, int row, int col, const X
writer.writeAttribute("r", cell_range);
//Style used by the cell, row or col
if (data.format)
writer.writeAttribute("s", QString::number(data.format->xfIndex()));
if (data.dataType == XlsxCellData::String) {
//data.data: Index of the string in sharedStringTable
if (cell->format)
writer.writeAttribute("s", QString::number(cell->format->xfIndex()));
else if (m_rowsInfo.contains(row) && m_rowsInfo[row]->format)
writer.writeAttribute("s", QString::number(m_rowsInfo[row]->format->xfIndex()));
else if (m_colsInfoHelper.contains(col) && m_colsInfoHelper[col]->format)
writer.writeAttribute("s", QString::number(m_colsInfoHelper[col]->format->xfIndex()));
if (cell->dataType == XlsxCellData::String) {
//cell->data: Index of the string in sharedStringTable
writer.writeAttribute("t", "s");
writer.writeTextElement("v", data.value.toString());
} else if (data.dataType == XlsxCellData::Number){
writer.writeTextElement("v", data.value.toString());
} else if (data.dataType == XlsxCellData::Formula) {
writer.writeTextElement("v", cell->value.toString());
} else if (cell->dataType == XlsxCellData::Number){
writer.writeTextElement("v", cell->value.toString());
} else if (cell->dataType == XlsxCellData::Formula) {
bool ok = true;
data.formula.toDouble(&ok);
cell->formula.toDouble(&ok);
if (!ok) //is string
writer.writeAttribute("t", "str");
writer.writeTextElement("f", data.formula);
writer.writeTextElement("v", data.value.toString());
} else if (data.dataType == XlsxCellData::ArrayFormula) {
writer.writeTextElement("f", cell->formula);
writer.writeTextElement("v", cell->value.toString());
} else if (cell->dataType == XlsxCellData::ArrayFormula) {
} else if (data.dataType == XlsxCellData::Boolean) {
} else if (cell->dataType == XlsxCellData::Boolean) {
writer.writeAttribute("t", "b");
writer.writeTextElement("v", data.value.toBool() ? "1" : "0");
} else if (data.dataType == XlsxCellData::Blank) {
writer.writeTextElement("v", cell->value.toBool() ? "1" : "0");
} else if (cell->dataType == XlsxCellData::Blank) {
//Ok, empty here.
}
writer.writeEndElement(); //c
@ -429,9 +528,9 @@ void Worksheet::calculateSpans()
int span_max = INT32_MIN;
for (int row_num = m_dim_rowmin; row_num <= m_dim_rowmax; row_num++) {
if (m_table.contains(row_num)) {
if (m_cellTable.contains(row_num)) {
for (int col_num = m_dim_colmin; col_num <= m_dim_colmax; col_num++) {
if (m_table[row_num].contains(col_num)) {
if (m_cellTable[row_num].contains(col_num)) {
if (span_max == INT32_MIN) {
span_min = col_num;
span_max = col_num;
@ -472,4 +571,50 @@ void Worksheet::calculateSpans()
}
}
/*
Sets row height and format. Row height measured in point size. If format
equals 0 then format is ignored.
*/
bool Worksheet::setRow(int row, double height, Format *format, bool hidden)
{
int min_col = m_dim_colmax == INT32_MIN ? 0 : m_dim_colmin;
if (checkDimensions(row, min_col))
return false;
if (m_rowsInfo.contains(row)) {
m_rowsInfo[row]->height = height;
m_rowsInfo[row]->format = format;
m_rowsInfo[row]->hidden = hidden;
} else {
m_rowsInfo[row] = new XlsxRowInfo(height, format, hidden);
}
return true;
}
/*
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.
*/
bool Worksheet::setColumn(int colFirst, int colLast, double width, Format *format, bool hidden)
{
bool ignore_row = true;
bool ignore_col = (format || (width && hidden)) ? false : true;
if (checkDimensions(0, colLast, ignore_row, ignore_col))
return false;
if (checkDimensions(0, colFirst, ignore_row, ignore_col))
return false;
XlsxColumnInfo *info = new XlsxColumnInfo(colFirst, colLast, width, format, hidden);
m_colsInfo.append(info);
for (int col=colFirst; col<=colLast; ++col)
m_colsInfoHelper[col] = info;
return true;
}
} //namespace

41
src/xlsxworksheet.h

@ -37,27 +37,9 @@ class Workbook;
class XmlStreamWriter;
class Format;
struct XlsxCellData
{
enum CellDataType {
Blank,
String,
Number,
Formula,
ArrayFormula,
Boolean
};
XlsxCellData(const QVariant &data=QVariant(), CellDataType type=Blank, Format *format=0) :
value(data), dataType(type), format(format)
{
}
QVariant value;
QString formula;
CellDataType dataType;
Format *format;
};
struct XlsxCellData;
struct XlsxRowInfo;
struct XlsxColumnInfo;
class Worksheet : public QObject
{
@ -71,13 +53,18 @@ public:
int writeBlank(int row, int column, Format *format=0);
int writeBool(int row, int column, bool value, Format *format=0);
bool setRow(int row, double height, Format* format=0, bool hidden=false);
bool setColumn(int colFirst, int colLast, double width, Format* format=0, bool hidden=false);
void setRightToLeft(bool enable);
void setZeroValuesHidden(bool enable);
private:
friend class Package;
friend class Workbook;
explicit Worksheet(const QString &sheetName, int sheetIndex, Workbook *parent=0);
Worksheet(const QString &sheetName, int sheetIndex, Workbook *parent=0);
~Worksheet();
virtual bool isChartsheet() const;
QString name() const;
int index() const;
@ -91,12 +78,16 @@ private:
int checkDimensions(int row, int col, bool ignore_row=false, bool ignore_col=false);
QString generateDimensionString();
void writeSheetData(XmlStreamWriter &writer);
void writeCellData(XmlStreamWriter &writer, int row, int col, const XlsxCellData &data);
void writeCellData(XmlStreamWriter &writer, int row, int col, XlsxCellData *cell);
void calculateSpans();
Workbook *m_workbook;
QMap<int, QMap<int, XlsxCellData> > m_table;
QMap<int, QMap<int, XlsxCellData *> > m_cellTable;
QMap<int, QMap<int, QString> > m_comments;
QMap<int, XlsxRowInfo *> m_rowsInfo;
QList<XlsxColumnInfo *> m_colsInfo;
QMap<int, XlsxColumnInfo *> m_colsInfoHelper;//Not owns the XlsxColumnInfo
int m_xls_rowmax;
int m_xls_colmax;
@ -126,6 +117,4 @@ private:
} //QXlsx
Q_DECLARE_TYPEINFO(QXlsx::XlsxCellData, Q_MOVABLE_TYPE);
#endif // XLSXWORKSHEET_H

Loading…
Cancel
Save