Browse Source

Add Fill & Border Style control for cell

master
Debao Zhang 11 years ago
parent
commit
3d47093e38
  1. 2
      examples/style/main.cpp
  2. 392
      src/xlsxformat.cpp
  3. 201
      src/xlsxformat.h
  4. 2
      src/xlsxpackage.cpp
  5. 203
      src/xlsxstyles.cpp
  6. 6
      src/xlsxstyles_p.h

2
examples/style/main.cpp

@ -18,12 +18,14 @@ int main()
format1->setFontColor(QColor(Qt::red));
format1->setFontSize(15);
format1->setHorizontalAlignment(QXlsx::Format::AlignHCenter);
format1->setBorderStyle(QXlsx::Format::BorderDashDotDot);
sheet->write("A1", "Hello Qt!", format1);
sheet->write("B3", 12345, format1);
QXlsx::Format *format2 = workbook.addFormat();
format2->setFontBold(true);
format2->setFontUnderline(QXlsx::Format::FontUnderlineDouble);
format2->setFillPattern(QXlsx::Format::PatternLightUp);
sheet->write("C5", "=44+33", format2);
sheet->write("D7", true, format2);

392
src/xlsxformat.cpp

@ -23,11 +23,18 @@
**
****************************************************************************/
#include "xlsxformat.h"
#include <QDataStream>
#include <QDebug>
namespace QXlsx {
QList<Format *> Format::s_xfFormats;
QList<Format *> Format::s_dxfFormats;
Format::Format()
{
m_number.formatIndex = 0;
m_font.bold = false;
m_font.color = QColor(Qt::black);
m_font.italic = false;
@ -43,8 +50,9 @@ Format::Format()
m_font.charset = 0;
m_font.condense = 0;
m_font.extend = 0;
m_font.redundant = false;
m_font.index = 0;
m_font._dirty = true;
m_font._redundant = false;
m_font._index = -1;
m_alignment.alignH = AlignHGeneral;
m_alignment.alignV = AlignBottom;
@ -53,20 +61,50 @@ Format::Format()
m_alignment.indent = 0;
m_alignment.shinkToFit = false;
m_is_dxf_fomat = false;
m_border.left = BorderNone;
m_border.right = BorderNone;
m_border.top = BorderNone;
m_border.bottom = BorderNone;
m_border.diagonal = BorderNone;
m_border.diagonalType = DiagonalBorderNone;
m_border.leftColor = QColor();
m_border.rightColor = QColor();
m_border.topColor = QColor();
m_border.bottomColor = QColor();
m_border.diagonalColor = QColor();
m_border._dirty = true;
m_border._redundant = false;
m_border._index = -1;
m_fill.pattern = PatternNone;
m_fill.bgColor = QColor();
m_fill.fgColor = QColor();
m_fill._dirty = true;
m_fill._redundant = false;
m_fill._index = -1;
m_protection.locked = false;
m_protection.hidden = false;
m_dirty = true;
m_xf_index = 0;
m_dxf_index = 0;
m_is_dxf_fomat = false;
m_xf_index = -1;
m_dxf_index = -1;
m_num_format_index = 0;
m_theme = 0;
m_color_indexed = 0;
}
m_has_fill = false;
m_fill_index = 0;
int Format::numberFormat() const
{
return m_number.formatIndex;
}
m_has_borders = false;
m_border_index = false;
void Format::setNumberFormat(int format)
{
m_dirty = true;
m_number.formatIndex = format;
}
int Format::fontSize() const
@ -77,6 +115,7 @@ int Format::fontSize() const
void Format::setFontSize(int size)
{
m_font.size = size;
m_font._dirty = true;
}
bool Format::fontItalic() const
@ -87,6 +126,7 @@ bool Format::fontItalic() const
void Format::setFontItalic(bool italic)
{
m_font.italic = italic;
m_font._dirty = true;
}
bool Format::fontStrikeOut() const
@ -94,9 +134,10 @@ bool Format::fontStrikeOut() const
return m_font.strikeOut;
}
void Format::setFontStricOut(bool stricOut)
void Format::setFontStrikeOut(bool strikeOut)
{
m_font.strikeOut = stricOut;
m_font.strikeOut = strikeOut;
m_font._dirty = true;
}
QColor Format::fontColor() const
@ -107,6 +148,7 @@ QColor Format::fontColor() const
void Format::setFontColor(const QColor &color)
{
m_font.color = color;
m_font._dirty = true;
}
bool Format::fontBold() const
@ -117,6 +159,7 @@ bool Format::fontBold() const
void Format::setFontBold(bool bold)
{
m_font.bold = bold;
m_font._dirty = true;
}
Format::FontScript Format::fontScript() const
@ -127,6 +170,7 @@ Format::FontScript Format::fontScript() const
void Format::setFontScript(FontScript script)
{
m_font.scirpt = script;
m_font._dirty = true;
}
Format::FontUnderline Format::fontUnderline() const
@ -137,6 +181,7 @@ Format::FontUnderline Format::fontUnderline() const
void Format::setFontUnderline(FontUnderline underline)
{
m_font.underline = underline;
m_font._dirty = true;
}
bool Format::fontOutline() const
@ -147,6 +192,7 @@ bool Format::fontOutline() const
void Format::setFontOutline(bool outline)
{
m_font.outline = outline;
m_font._dirty = true;
}
QString Format::fontName() const
@ -157,6 +203,27 @@ QString Format::fontName() const
void Format::setFontName(const QString &name)
{
m_font.name = name;
m_font._dirty = true;
}
/* Internal
*/
QByteArray Format::fontKey() const
{
if (m_font._dirty) {
QByteArray key;
QDataStream stream(&key, QIODevice::WriteOnly);
stream<<m_font.bold<<m_font.charset<<m_font.color<<m_font.condense
<<m_font.extend<<m_font.family<<m_font.italic<<m_font.name
<<m_font.outline<<m_font.scheme<<m_font.scirpt<<m_font.shadow
<<m_font.size<<m_font.strikeOut<<m_font.underline;
const_cast<Format*>(this)->m_font._key = key;
const_cast<Format*>(this)->m_font._dirty = false;
const_cast<Format*>(this)->m_dirty = true; //Make sure formatKey() will be re-generated.
}
return m_font._key;
}
Format::HorizontalAlignment Format::horizontalAlignment() const
@ -177,6 +244,7 @@ void Format::setHorizontalAlignment(HorizontalAlignment align)
}
m_alignment.alignH = align;
m_dirty = true;
}
Format::VerticalAlignment Format::verticalAlignment() const
@ -187,6 +255,7 @@ Format::VerticalAlignment Format::verticalAlignment() const
void Format::setVerticalAlignment(VerticalAlignment align)
{
m_alignment.alignV = align;
m_dirty = true;
}
bool Format::textWrap() const
@ -200,6 +269,7 @@ void Format::setTextWarp(bool wrap)
m_alignment.shinkToFit = false;
m_alignment.wrap = wrap;
m_dirty = true;
}
int Format::rotation() const
@ -210,6 +280,7 @@ int Format::rotation() const
void Format::setRotation(int rotation)
{
m_alignment.rotation = rotation;
m_dirty = true;
}
int Format::indent() const
@ -226,6 +297,7 @@ void Format::setIndent(int indent)
m_alignment.alignH = AlignLeft;
}
m_alignment.indent = indent;
m_dirty = true;
}
bool Format::shrinkToFit() const
@ -244,6 +316,7 @@ void Format::setShrinkToFit(bool shink)
}
m_alignment.shinkToFit = shink;
m_dirty = true;
}
bool Format::alignmentChanged() const
@ -309,20 +382,303 @@ QString Format::verticalAlignmentString() const
return align;
}
bool Format::isDxfFormat() const
void Format::setBorderStyle(BorderStyle style)
{
return m_is_dxf_fomat;
setLeftBorderStyle(style);
setRightBorderStyle(style);
setBottomBorderStyle(style);
setTopBorderStyle(style);
}
void Format::setBorderColor(const QColor &color)
{
setLeftBorderColor(color);
setRightBorderColor(color);
setTopBorderColor(color);
setBottomBorderColor(color);
}
Format::BorderStyle Format::leftBorderStyle() const
{
return m_border.left;
}
void Format::setLeftBorderStyle(BorderStyle style)
{
m_border.left = style;
m_border._dirty = true;
}
QColor Format::leftBorderColor() const
{
return m_border.leftColor;
}
void Format::setLeftBorderColor(const QColor &color)
{
m_border.leftColor = color;
m_border._dirty = true;
}
Format::BorderStyle Format::rightBorderStyle() const
{
return m_border.right;
}
void Format::setRightBorderStyle(BorderStyle style)
{
m_border.right = style;
m_border._dirty = true;
}
QColor Format::rightBorderColor() const
{
return m_border.rightColor;
}
void Format::setRightBorderColor(const QColor &color)
{
m_border.rightColor = color;
m_border._dirty = true;
}
Format::BorderStyle Format::topBorderStyle() const
{
return m_border.top;
}
void Format::setTopBorderStyle(BorderStyle style)
{
m_border.top = style;
m_border._dirty = true;
}
QColor Format::topBorderColor() const
{
return m_border.topColor;
}
void Format::setTopBorderColor(const QColor &color)
{
m_border.topColor = color;
m_border._dirty = true;
}
Format::BorderStyle Format::bottomBorderStyle() const
{
return m_border.bottom;
}
void Format::setBottomBorderStyle(BorderStyle style)
{
m_border.bottom = style;
m_border._dirty = true;
}
QColor Format::bottomBorderColor() const
{
return m_border.bottomColor;
}
void Format::setBottomBorderColor(const QColor &color)
{
m_border.bottomColor = color;
m_border._dirty = true;
}
Format::BorderStyle Format::diagonalBorderStyle() const
{
return m_border.diagonal;
}
void Format::setDiagonalBorderStyle(BorderStyle style)
{
m_border.diagonal = style;
m_border._dirty = true;
}
Format::DiagonalBorderType Format::diagonalBorderType() const
{
return m_border.diagonalType;
}
void Format::setDiagonalBorderType(DiagonalBorderType style)
{
m_border.diagonalType = style;
m_border._dirty = true;
}
void Format::setForegroundColor(const QColor &color)
QColor Format::diagonalBorderColor() const
{
m_fg_color = color;
return m_border.diagonalColor;
}
void Format::setDiagonalBorderColor(const QColor &color)
{
m_border.diagonalColor = color;
m_border._dirty = true;
}
/* Internal
*/
QByteArray Format::borderKey() const
{
if (m_border._dirty) {
QByteArray key;
QDataStream stream(&key, QIODevice::WriteOnly);
stream<<m_border.bottom<<m_border.bottomColor
<<m_border.diagonal<<m_border.diagonalColor<<m_border.diagonalType
<<m_border.left<<m_border.leftColor
<<m_border.right<<m_border.rightColor
<<m_border.top<<m_border.topColor;
const_cast<Format*>(this)->m_border._key = key;
const_cast<Format*>(this)->m_border._dirty = false;
const_cast<Format*>(this)->m_dirty = true; //Make sure formatKey() will be re-generated.
}
return m_border._key;
}
Format::FillPattern Format::fillPattern() const
{
return m_fill.pattern;
}
void Format::setFillPattern(FillPattern pattern)
{
m_fill.pattern = pattern;
m_fill._dirty = true;
}
QColor Format::patternForegroundColor() const
{
return m_fill.fgColor;
}
void Format::setPatternForegroundColor(const QColor &color)
{
if (color.isValid() && m_fill.pattern == PatternNone)
m_fill.pattern = PatternSolid;
m_fill.fgColor = color;
m_fill._dirty = true;
}
QColor Format::patternBackgroundColor() const
{
return m_fill.bgColor;
}
void Format::setPatternBackgroundColor(const QColor &color)
{
if (color.isValid() && m_fill.pattern == PatternNone)
m_fill.pattern = PatternSolid;
m_fill.bgColor = color;
m_fill._dirty = true;
}
/* Internal
*/
QByteArray Format::fillKey() const
{
if (m_fill._dirty) {
QByteArray key;
QDataStream stream(&key, QIODevice::WriteOnly);
stream<<m_fill.bgColor<<m_fill.fgColor<<m_fill.pattern;
const_cast<Format*>(this)->m_fill._key = key;
const_cast<Format*>(this)->m_fill._dirty = false;
const_cast<Format*>(this)->m_dirty = true; //Make sure formatKey() will be re-generated.
}
return m_fill._key;
}
void Format::setBackgroundColor(const QColor &color)
bool Format::hidden() const
{
m_bg_color = color;
return m_protection.hidden;
}
void Format::setHidden(bool hidden)
{
m_protection.hidden = hidden;
m_dirty = true;
}
bool Format::locked() const
{
return m_protection.locked;
}
void Format::setLocked(bool locked)
{
m_protection.locked = locked;
m_dirty = true;
}
QByteArray Format::formatKey() const
{
if (m_dirty || m_font._dirty || m_border._dirty || m_fill._dirty) {
QByteArray key;
QDataStream stream(&key, QIODevice::WriteOnly);
stream<<fontKey()<<borderKey()<<fillKey()
<<m_number.formatIndex
<<m_alignment.alignH<<m_alignment.alignV<<m_alignment.indent
<<m_alignment.rotation<<m_alignment.shinkToFit<<m_alignment.wrap
<<m_protection.hidden<<m_protection.locked;
const_cast<Format*>(this)->m_formatKey = key;
const_cast<Format*>(this)->m_dirty = false;
}
return m_formatKey;
}
bool Format::operator ==(const Format &format) const
{
return this->formatKey() == format.formatKey();
}
bool Format::operator !=(const Format &format) const
{
return this->formatKey() != format.formatKey();
}
/* Internal
*
* This function will be called when wirte the cell contents of worksheet to xml files.
* Depending on the order of the Format used instead of the Format created, we assign a
* index to it.
*/
int Format::xfIndex(bool generateIfNotValid)
{
if (m_xf_index == -1 && generateIfNotValid) { //Generate a valid xf_index for this format
int index = -1;
for (int i=0; i<s_xfFormats.size(); ++i) {
if (*s_xfFormats[i] == *this) {
index = i;
break;
}
}
if (index != -1) {
m_xf_index = index;
} else {
m_xf_index = s_xfFormats.size();
s_xfFormats.append(this);
}
}
return m_xf_index;
}
void Format::clearExtraInfos()
{
m_xf_index = -1;
m_dxf_index = -1;
s_xfFormats.clear();
s_dxfFormats.clear();
}
bool Format::isDxfFormat() const
{
return m_is_dxf_fomat;
}
} // namespace QXlsx

201
src/xlsxformat.h

@ -27,6 +27,8 @@
#include <QFont>
#include <QColor>
#include <QByteArray>
#include <QList>
namespace QXlsx {
@ -73,12 +75,63 @@ public:
AlignVDistributed
};
enum BorderStyle
{
BorderNone,
BorderThin,
BorderMedium,
BorderDashed,
BorderDotted,
BorderThick,
BorderDouble,
BorderHair,
BorderMediumDashed,
BorderDashDot,
BorderMediumDashDot,
BorderDashDotDot,
BorderMediumDashDotDot,
BorderSlantDashDot
};
enum DiagonalBorderType
{
DiagonalBorderNone,
DiagonalBorderDown,
DiagonalBorderUp,
DiagnoalBorderBoth
};
enum FillPattern
{
PatternNone,
PatternSolid,
PatternMediumGray,
PatternDarkGray,
PatternLightGray,
PatternDarkHorizontal,
PatternDarkVertical,
PatternDarkDown,
PatternDarkUp,
PatternDarkGrid,
PatternDarkTrellis,
PatternLightHorizontal,
PatternLightVertical,
PatternLightDown,
PatternLightUp,
PatternLightTrellis,
PatternGray125,
PatternGray0625
};
int numberFormat() const;
void setNumberFormat(int format);
int fontSize() const;
void setFontSize(int size);
bool fontItalic() const;
void setFontItalic(bool italic);
bool fontStrikeOut() const;
void setFontStricOut(bool);
void setFontStrikeOut(bool);
QColor fontColor() const;
void setFontColor(const QColor &);
bool fontBold() const;
@ -105,14 +158,56 @@ public:
bool shrinkToFit() const;
void setShrinkToFit(bool shink);
void setForegroundColor(const QColor &color);
void setBackgroundColor(const QColor &color);
void setBorderStyle(BorderStyle style);
void setBorderColor(const QColor &color);
BorderStyle leftBorderStyle() const;
void setLeftBorderStyle(BorderStyle style);
QColor leftBorderColor() const;
void setLeftBorderColor(const QColor &color);
BorderStyle rightBorderStyle() const;
void setRightBorderStyle(BorderStyle style);
QColor rightBorderColor() const;
void setRightBorderColor(const QColor &color);
BorderStyle topBorderStyle() const;
void setTopBorderStyle(BorderStyle style);
QColor topBorderColor() const;
void setTopBorderColor(const QColor &color);
BorderStyle bottomBorderStyle() const;
void setBottomBorderStyle(BorderStyle style);
QColor bottomBorderColor() const;
void setBottomBorderColor(const QColor &color);
BorderStyle diagonalBorderStyle() const;
void setDiagonalBorderStyle(BorderStyle style);
DiagonalBorderType diagonalBorderType() const;
void setDiagonalBorderType(DiagonalBorderType style);
QColor diagonalBorderColor() const;
void setDiagonalBorderColor(const QColor &color);
FillPattern fillPattern() const;
void setFillPattern(FillPattern pattern);
QColor patternForegroundColor() const;
void setPatternForegroundColor(const QColor &color);
QColor patternBackgroundColor() const;
void setPatternBackgroundColor(const QColor &color);
bool locked() const;
void setLocked(bool locked);
bool hidden() const;
void setHidden(bool hidden);
bool operator == (const Format &format) const;
bool operator != (const Format &format) const;
private:
friend class Styles;
friend class Worksheet;
Format();
struct NumberData
{
int formatIndex;
} m_number;
struct FontData
{
int size;
@ -132,13 +227,16 @@ private:
int extend;
//helper member
bool redundant; //same with the fonts used by some other Formats
int index; //index in the Font list
bool _dirty; //key re-generated is need.
QByteArray _key;
bool _redundant; //same font already used by some other Formats
int _index; //index in the Font list
} m_font;
bool hasFont() const {return !m_font.redundant;}
int fontIndex() const {return m_font.index;}
void setFontIndex(int index) {m_font.index = index;}
bool hasFont() const {return !m_font._redundant;}
void setFontRedundant(bool redundant) {m_font._redundant = redundant;}
int fontIndex() const {return m_font._index;}
void setFontIndex(int index) {m_font._index = index;}
QByteArray fontKey() const;
int fontFamily() const{return m_font.family;}
bool fontShadow() const {return m_font.shadow;}
QString fontScheme() const {return m_font.scheme;}
@ -157,46 +255,75 @@ private:
QString horizontalAlignmentString() const;
QString verticalAlignmentString() const;
bool isDxfFormat() const;
int xfIndex() const {return m_xf_index;}
void setXfIndex(int index) {m_xf_index = index; m_font.index=index;}
struct BorderData
{
BorderStyle left;
BorderStyle right;
BorderStyle top;
BorderStyle bottom;
BorderStyle diagonal;
QColor leftColor;
QColor rightColor;
QColor topColor;
QColor bottomColor;
QColor diagonalColor;
DiagonalBorderType diagonalType;
//num
int numFormatIndex() const {return m_num_format_index;}
//helper member
bool _dirty; //key re-generated is need.
QByteArray _key;
bool _redundant; //same border already used by some other Formats
int _index; //index in the border list
} m_border;
int theme() const {return m_theme;}
int colorIndexed() const {return m_color_indexed;}
QByteArray borderKey() const;
bool hasBorders() const {return !m_border._redundant;}
void setBorderRedundant(bool redundant) {m_border._redundant = redundant;}
int borderIndex() const {return m_border._index;}
void setBorderIndex(int index) {m_border._index = index;}
struct FillData {
FillPattern pattern;
QColor bgColor;
QColor fgColor;
//fills
bool hasFill() const {return m_has_fill;}
int fillIndex() const {return m_fill_index;}
//helper member
bool _dirty; //key re-generated is need.
QByteArray _key;
bool _redundant; //same border already used by some other Formats
int _index; //index in the border list
} m_fill;
//borders
bool hasBorders() const {return m_has_borders;}
void setHasBorder(bool has) {m_has_borders=has;}
int borderIndex() const {return m_border_index;}
QByteArray fillKey() const;
bool hasFill() const {return !m_fill._redundant;}
void setFillRedundant(bool redundant) {m_fill._redundant = redundant;}
int fillIndex() const {return m_fill._index;}
void setFillIndex(int index) {m_fill._index = index;}
bool m_is_dxf_fomat;
struct ProtectionData {
bool locked;
bool hidden;
} m_protection;
bool m_dirty; //The key re-generation is need.
QByteArray m_formatKey;
QByteArray formatKey() const;
static QList<Format *> s_xfFormats;
int m_xf_index;
int m_dxf_index;
int xfIndex(bool generateIfNotValid=true); //Generate index when first called.
void clearExtraInfos();
int m_num_format_index;
bool m_is_dxf_fomat;
int m_dxf_index;
static QList<Format *> s_dxfFormats;
bool isDxfFormat() const;
bool m_has_font;
int m_font_index;
int m_font_family;
QString m_font_scheme;
QColor m_bg_color;
QColor m_fg_color;
int m_theme;
int m_color_indexed;
int theme() const {return m_theme;}
int colorIndexed() const {return m_color_indexed;}
bool m_has_fill;
int m_fill_index;
bool m_has_borders;
int m_border_index;
};
} // namespace QXlsx

2
src/xlsxpackage.cpp

@ -89,6 +89,7 @@ bool Package::createPackage(const QString &packageName)
{
ZipWriter zipWriter(packageName);
m_workbook->styles()->clearExtraFormatInfo(); //These info will be generated when write the worksheet data.
writeWorksheetFiles(zipWriter);
// writeChartsheetFiles(zipWriter);
writeWorkbookFile(zipWriter);
@ -100,6 +101,7 @@ bool Package::createPackage(const QString &packageName)
writeSharedStringsFile(zipWriter);
writeDocPropsFiles(zipWriter);
writeContentTypesFiles(zipWriter);
m_workbook->styles()->prepareStyles();
writeStylesFiles(zipWriter);
writeThemeFile(zipWriter);
writeRootRelsFile(zipWriter);

203
src/xlsxstyles.cpp

@ -26,6 +26,9 @@
#include "xlsxformat.h"
#include "xmlstreamwriter_p.h"
#include <QFile>
#include <QMap>
#include <QDataStream>
#include <QDebug>
namespace QXlsx {
@ -34,29 +37,106 @@ Styles::Styles(QObject *parent) :
QObject(parent)
{
m_fill_count = 2; //Starts from 2
m_borders_count = 1;
m_borders_count = 0;
m_font_count = 0;
}
//Add the default cell format
Format *format = addFormat();
format->setHasBorder(true);
Styles::~Styles()
{
qDeleteAll(m_formats);
}
Format *Styles::addFormat()
{
Format *format = new Format();
format->setXfIndex(m_formats.size());
m_font_count += 1;
m_formats.append(format);
return format;
}
void Styles::saveToXmlFile(QIODevice *device)
/*
* This function should be called after worksheet written finished,
* which means the order of the Formats used have been known to us.
*/
void Styles::prepareStyles()
{
//Todo
m_xf_formats = m_formats;
m_xf_formats = Format::s_xfFormats;
m_dxf_formats = Format::s_dxfFormats;
//fonts
QMap<QByteArray, int> fontsKeyCache;
foreach (Format *format, m_xf_formats) {
const QByteArray &key = format->fontKey();
if (fontsKeyCache.contains(key)) {
//Font has already been used.
format->setFontIndex(fontsKeyCache[key]);
format->setFontRedundant(true);
} else {
int index = fontsKeyCache.size();
fontsKeyCache[key] = index;
format->setFontIndex(index);
format->setFontRedundant(false);
}
}
m_font_count = fontsKeyCache.size();
//borders
QMap<QByteArray, int> bordersKeyCache;
foreach (Format *format, m_xf_formats) {
const QByteArray &key = format->borderKey();
if (bordersKeyCache.contains(key)) {
//Border has already been used.
format->setBorderIndex(bordersKeyCache[key]);
format->setBorderRedundant(true);
} else {
int index = bordersKeyCache.size();
bordersKeyCache[key] = index;
format->setBorderIndex(index);
format->setBorderRedundant(false);
}
}
m_borders_count = bordersKeyCache.size();
//fills
QMap<QByteArray, int> fillsKeyCache;
// The user defined fill properties start from 2 since there are 2
// default fills: patternType="none" and patternType="gray125".
{
QByteArray key;
QDataStream stream(&key, QIODevice::WriteOnly);
stream<<QColor()<<QColor()<<Format::PatternNone;
fillsKeyCache[key] = 0;
}
{
QByteArray key;
QDataStream stream(&key, QIODevice::WriteOnly);
stream<<QColor()<<QColor()<<Format::PatternGray125;
fillsKeyCache[key] = 1;
}
foreach (Format *format, m_xf_formats) {
const QByteArray &key = format->fillKey();
if (fillsKeyCache.contains(key)) {
//Border has already been used.
format->setFillIndex(fillsKeyCache[key]);
format->setFillRedundant(true);
} else {
int index = fillsKeyCache.size();
fillsKeyCache[key] = index;
format->setFillIndex(index);
format->setFillRedundant(false);
}
}
m_fill_count = fillsKeyCache.size() + 2;
}
void Styles::clearExtraFormatInfo()
{
foreach (Format *format, m_formats)
format->clearExtraInfos();
}
void Styles::saveToXmlFile(QIODevice *device)
{
XmlStreamWriter writer(device);
writer.writeStartDocument("1.0", true);
@ -180,6 +260,7 @@ void Styles::writeFills(XmlStreamWriter &writer)
{
writer.writeStartElement("fills");
writer.writeAttribute("count", QString::number(m_fill_count));
//wirte two default fill first
writer.writeStartElement("fill");
writer.writeEmptyElement("patternFill");
writer.writeAttribute("patternType", "none");
@ -190,12 +271,52 @@ void Styles::writeFills(XmlStreamWriter &writer)
writer.writeEndElement();//fill
foreach (Format *format, m_xf_formats) {
if (format->hasFill()) {
//:TODO
writeFill(writer, format);
}
}
writer.writeEndElement(); //fills
}
void Styles::writeFill(XmlStreamWriter &writer, Format *format)
{
static QMap<int, QString> patternStrings;
if (patternStrings.isEmpty()) {
patternStrings[Format::PatternNone] = "none";
patternStrings[Format::PatternSolid] = "solid";
patternStrings[Format::PatternMediumGray] = "mediumGray";
patternStrings[Format::PatternDarkGray] = "darkGray";
patternStrings[Format::PatternLightGray] = "lightGray";
patternStrings[Format::PatternDarkHorizontal] = "darkHorizontal";
patternStrings[Format::PatternDarkVertical] = "darkVertical";
patternStrings[Format::PatternDarkDown] = "darkDown";
patternStrings[Format::PatternDarkUp] = "darkUp";
patternStrings[Format::PatternDarkGrid] = "darkGrid";
patternStrings[Format::PatternDarkTrellis] = "darkTrellis";
patternStrings[Format::PatternLightHorizontal] = "lightHorizontal";
patternStrings[Format::PatternLightVertical] = "lightVertical";
patternStrings[Format::PatternLightDown] = "lightDown";
patternStrings[Format::PatternLightUp] = "lightUp";
patternStrings[Format::PatternLightTrellis] = "lightTrellis";
patternStrings[Format::PatternGray125] = "gray125";
patternStrings[Format::PatternGray0625] = "gray0625";
}
writer.writeStartElement("fill");
writer.writeStartElement("patternFill");
writer.writeAttribute("patternType", patternStrings[format->fillPattern()]);
if (format->patternForegroundColor().isValid()) {
writer.writeEmptyElement("fgColor");
writer.writeAttribute("rgb", "FF"+format->patternForegroundColor().name().mid(1));
}
if (format->patternBackgroundColor().isValid()) {
writer.writeEmptyElement("bgColor");
writer.writeAttribute("rgb", "FF"+format->patternBackgroundColor().name().mid(1));
}
writer.writeEndElement();//patternFill
writer.writeEndElement();//fill
}
void Styles::writeBorders(XmlStreamWriter &writer)
{
writer.writeStartElement("borders");
@ -203,12 +324,21 @@ void Styles::writeBorders(XmlStreamWriter &writer)
foreach (Format *format, m_xf_formats) {
if (format->hasBorders()) {
writer.writeStartElement("border");
writer.writeEmptyElement("left");
writer.writeEmptyElement("right");
writer.writeEmptyElement("top");
writer.writeEmptyElement("bottom");
if (format->diagonalBorderType() == Format::DiagonalBorderUp) {
writer.writeAttribute("diagonalUp", "1");
} else if (format->diagonalBorderType() == Format::DiagonalBorderDown) {
writer.writeAttribute("diagonalDown", "1");
} else if (format->DiagnoalBorderBoth) {
writer.writeAttribute("diagonalUp", "1");
writer.writeAttribute("diagonalDown", "1");
}
writeSubBorder(writer, "left", format->leftBorderStyle(), format->leftBorderColor());
writeSubBorder(writer, "right", format->rightBorderStyle(), format->rightBorderColor());
writeSubBorder(writer, "top", format->topBorderStyle(), format->topBorderColor());
writeSubBorder(writer, "bottom", format->bottomBorderStyle(), format->bottomBorderColor());
if (!format->isDxfFormat()) {
writer.writeEmptyElement("diagonal");
writeSubBorder(writer, "diagonal", format->diagonalBorderStyle(), format->diagonalBorderColor());
}
writer.writeEndElement();//border
}
@ -216,12 +346,47 @@ void Styles::writeBorders(XmlStreamWriter &writer)
writer.writeEndElement();//borders
}
void Styles::writeSubBorder(XmlStreamWriter &writer, const QString &type, int style, const QColor &color)
{
if (style == Format::BorderNone) {
writer.writeEmptyElement(type);
return;
}
static QMap<int, QString> stylesString;
if (stylesString.isEmpty()) {
stylesString[Format::BorderNone] = "none";
stylesString[Format::BorderThin] = "thin";
stylesString[Format::BorderMedium] = "medium";
stylesString[Format::BorderDashed] = "dashed";
stylesString[Format::BorderDotted] = "dotted";
stylesString[Format::BorderThick] = "thick";
stylesString[Format::BorderDouble] = "double";
stylesString[Format::BorderHair] = "hair";
stylesString[Format::BorderMediumDashed] = "mediumDashed";
stylesString[Format::BorderDashDot] = "dashDot";
stylesString[Format::BorderMediumDashDot] = "mediumDashDot";
stylesString[Format::BorderDashDotDot] = "dashDotDot";
stylesString[Format::BorderMediumDashDotDot] = "mediumDashDotDot";
stylesString[Format::BorderSlantDashDot] = "slantDashDot";
}
writer.writeStartElement(type);
writer.writeAttribute("style", stylesString[style]);
writer.writeEmptyElement("color");
if (color.isValid())
writer.writeAttribute("rgb", "FF"+color.name().mid(1)); //remove #
else
writer.writeAttribute("auto", "1");
writer.writeEndElement();//type
}
void Styles::writeCellXfs(XmlStreamWriter &writer)
{
writer.writeStartElement("cellXfs");
writer.writeAttribute("count", QString::number(m_xf_formats.size()));
foreach (Format *format, m_xf_formats) {
int num_fmt_id = format->numFormatIndex();
int num_fmt_id = format->numberFormat();
int font_id = format->fontIndex();
int fill_id = format->fillIndex();
int border_id = format->borderIndex();
@ -232,12 +397,14 @@ void Styles::writeCellXfs(XmlStreamWriter &writer)
writer.writeAttribute("fillId", QString::number(fill_id));
writer.writeAttribute("borderId", QString::number(border_id));
writer.writeAttribute("xfId", QString::number(xf_id));
if (format->numFormatIndex() > 0)
if (format->numberFormat() > 0)
writer.writeAttribute("applyNumberFormat", "1");
if (format->fontIndex() > 0)
writer.writeAttribute("applyFont", "1");
if (format->fillIndex() > 0)
if (format->borderIndex() > 0)
writer.writeAttribute("applyBorder", "1");
if (format->fillIndex() > 0)
writer.writeAttribute("applyFill", "1");
if (format->alignmentChanged())
writer.writeAttribute("applyAlignment", "1");

6
src/xlsxstyles_p.h

@ -38,18 +38,22 @@ class Styles : public QObject
{
public:
explicit Styles(QObject *parent=0);
~Styles();
Format *addFormat();
void prepareStyles();
void clearExtraFormatInfo();
void saveToXmlFile(QIODevice *device);
private:
void writeFonts(XmlStreamWriter &writer);
void writeFills(XmlStreamWriter &writer);
void writeFill(XmlStreamWriter &writer, Format *format);
void writeBorders(XmlStreamWriter &writer);
void writeSubBorder(XmlStreamWriter &writer, const QString &type, int style, const QColor &color);
void writeCellXfs(XmlStreamWriter &writer);
void writeDxfs(XmlStreamWriter &writer);
QList<Format *> m_formats;
QList<Format *> m_xf_formats;
QList<Format *> m_dxf_formats;

Loading…
Cancel
Save