Browse Source

Add font format support for cell data

master
Debao Zhang 11 years ago
parent
commit
abb991c212
  1. 9
      README.md
  2. 3
      examples/examples.pro
  3. 2
      examples/hello/main.cpp
  4. 32
      examples/style/main.cpp
  5. 5
      examples/style/style.pro
  6. 120
      src/xlsxformat.cpp
  7. 94
      src/xlsxformat.h
  8. 31
      src/xlsxstyles.cpp
  9. 45
      src/xlsxworksheet.cpp
  10. 18
      src/xlsxworksheet.h
  11. 1
      src/zipwriter.cpp

9
README.md

@ -0,0 +1,9 @@
## References
* https://github.com/jmcnamara/XlsxWriter
* http://officeopenxml.com/anatomyofOOXML-xlsx.php
* http://www.libxl.com
* http://closedxml.codeplex.com/
* http://search.cpan.org/~jmcnamara/Excel-Writer-XLSX-0.71/

3
examples/examples.pro

@ -1,3 +1,6 @@
TEMPLATE = subdirs
SUBDIRS = hello
SUBDIRS += \
style

2
examples/hello/main.cpp

@ -18,6 +18,8 @@ int main()
sheet->write("D7", true);
QXlsx::Worksheet *sheet2 = workbook.addWorksheet();
//Rows and columns are zero indexed.
//The first cell in a worksheet, "A1", is (0, 0).
sheet2->write(0, 0, "First");
sheet2->write(1, 0, "Second");
sheet2->write(2, 0, "Third");

32
examples/style/main.cpp

@ -0,0 +1,32 @@
#include <QtCore>
#include "xlsxworkbook.h"
#include "xlsxworksheet.h"
#include "xlsxformat.h"
#ifdef Q_OS_MAC
# define DATA_PATH "../../../"
#else
# define DATA_PATH "./"
#endif
int main()
{
QXlsx::Workbook workbook;
QXlsx::Worksheet *sheet = workbook.addWorksheet();
QXlsx::Format *format1 = workbook.addFormat();
format1->setFontColor(QColor(Qt::red));
format1->setFontSize(15);
sheet->write("A1", "Hello Qt!", format1);
sheet->write("B3", 12345, format1);
QXlsx::Format *format2 = workbook.addFormat();
format2->setFontBold(true);
format2->setFontUnderline(QXlsx::Format::FontUnderlineDouble);
sheet->write("C5", "=44+33", format2);
sheet->write("D7", true, format2);
workbook.save(DATA_PATH"TestStyle.xlsx");
workbook.save(DATA_PATH"TestStyle.zip");
return 0;
}

5
examples/style/style.pro

@ -0,0 +1,5 @@
TARGET = style
include(../../src/qtxlsxwriter.pri)
SOURCES += main.cpp

120
src/xlsxformat.cpp

@ -26,24 +26,32 @@
namespace QXlsx {
Format::Format(QObject *parent) :
QObject(parent)
Format::Format()
{
m_font.bold = false;
m_font.color = QColor(Qt::black);
m_font.italic = false;
m_font.name = "Calibri";
m_font.scirpt = FontScriptNormal;
m_font.size = 11;
m_font.strikeOut = false;
m_font.underline = FontUnderlineNone;
m_font.shadow = false;
m_font.outline = false;
m_font.family = 2;
m_font.scheme = "minor";
m_font.charset = 0;
m_font.condense = 0;
m_font.extend = 0;
m_font.redundant = false;
m_font.index = 0;
m_is_dxf_fomat = false;
m_xf_index = 0;
m_dxf_index = 0;
m_num_format_index = 0;
m_has_font = false;
m_font_index = 0;
m_font_family = 2;
m_font_scheme = "minor";
m_font.setFamily("Calibri");
m_font.setPointSize(11);
m_theme = 0;
m_color_indexed = 0;
@ -54,70 +62,110 @@ Format::Format(QObject *parent) :
m_border_index = false;
}
bool Format::isDxfFormat() const
int Format::fontSize() const
{
return m_is_dxf_fomat;
return m_font.size;
}
void Format::setFont(const QFont &font)
void Format::setFontSize(int size)
{
m_font = font;
m_font.size = size;
}
void Format::setForegroundColor(const QColor &color)
bool Format::fontItalic() const
{
m_fg_color = color;
return m_font.italic;
}
void Format::setBackgroundColor(const QColor &color)
void Format::setFontItalic(bool italic)
{
m_bg_color = color;
m_font.italic = italic;
}
QString Format::fontName() const
bool Format::fontStrikeOut() const
{
return m_font.strikeOut;
}
void Format::setFontStricOut(bool stricOut)
{
m_font.strikeOut = stricOut;
}
QColor Format::fontColor() const
{
return m_font.color;
}
void Format::setFontColor(const QColor &color)
{
m_font.color = color;
}
bool Format::fontBold() const
{
return m_font.bold;
}
void Format::setFontBold(bool bold)
{
m_font.bold = bold;
}
Format::FontScript Format::fontScript() const
{
return m_font.scirpt;
}
void Format::setFontScript(FontScript script)
{
return m_font.family();
m_font.scirpt = script;
}
bool Format::bold() const
Format::FontUnderline Format::fontUnderline() const
{
return m_font.weight() == QFont::Bold;
return m_font.underline;
}
bool Format::italic() const
void Format::setFontUnderline(FontUnderline underline)
{
return m_font.italic();
m_font.underline = underline;
}
bool Format::fontOutline() const
{
return false;
return m_font.outline;
}
bool Format::fontShadow() const
void Format::setFontOutline(bool outline)
{
return false;
m_font.outline = outline;
}
bool Format::fontStrikout() const
QString Format::fontName() const
{
return m_font.strikeOut();
return m_font.name;
}
bool Format::fontUnderline() const
void Format::setFontName(const QString &name)
{
return m_font.underline();
m_font.name = name;
}
QColor Format::fontColor() const
bool Format::isDxfFormat() const
{
return m_font_color;
return m_is_dxf_fomat;
}
int Format::fontSize() const
void Format::setForegroundColor(const QColor &color)
{
return m_font.pointSize();
m_fg_color = color;
}
void Format::setBackgroundColor(const QColor &color)
{
m_bg_color = color;
}
} // namespace QXlsx

94
src/xlsxformat.h

@ -25,48 +25,100 @@
#ifndef QXLSX_FORMAT_H
#define QXLSX_FORMAT_H
#include <QObject>
#include <QFont>
#include <QColor>
namespace QXlsx {
class Styles;
class Worksheet;
class Format : public QObject
class Format
{
Q_OBJECT
public:
void setFont(const QFont &font);
enum FontScript
{
FontScriptNormal,
FontScriptSuper,
FontScriptSub
};
enum FontUnderline
{
FontUnderlineNone,
FontUnderlineSingle,
FontUnderlineDouble,
FontUnderlineSingleAccounting,
FontUnderlineDoubleAccounting
};
int fontSize() const;
void setFontSize(int size);
bool fontItalic() const;
void setFontItalic(bool italic);
bool fontStrikeOut() const;
void setFontStricOut(bool);
QColor fontColor() const;
void setFontColor(const QColor &);
bool fontBold() const;
void setFontBold(bool bold);
FontScript fontScript() const;
void setFontScript(FontScript);
FontUnderline fontUnderline() const;
void setFontUnderline(FontUnderline);
bool fontOutline() const;
void setFontOutline(bool outline);
QString fontName() const;
void setFontName(const QString &);
void setForegroundColor(const QColor &color);
void setBackgroundColor(const QColor &color);
private:
friend class Styles;
explicit Format(QObject *parent = 0);
friend class Worksheet;
explicit Format();
struct Font
{
int size;
bool italic;
bool strikeOut;
QColor color;
bool bold;
FontScript scirpt;
FontUnderline underline;
bool outline;
bool shadow;
QString name;
int family;
int charset;
QString scheme;
int condense;
int extend;
//helper member
bool redundant; //same with the fonts 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;}
int fontFamily() const{return m_font.family;}
bool fontShadow() const {return m_font.shadow;}
QString fontScheme() const {return m_font.scheme;}
bool isDxfFormat() const;
int xfIndex() const {return m_xf_index;}
void setXfIndex(int index) {m_xf_index = index; m_font.index=index;}
//num
int numFormatIndex() const {return m_num_format_index;}
//fonts
bool hasFont() const {return m_has_font;}
int fontIndex() const {return m_font_index;}
QString fontName() const;
bool bold() const;
bool italic() const;
bool fontStrikout() const;
bool fontOutline() const;
bool fontShadow() const;
bool fontUnderline() const;
QColor fontColor() const;
int fontSize() const;
int fontFamily() const{return m_font_family;}
int theme() const {return m_theme;}
int colorIndexed() const {return m_color_indexed;}
QString fontScheme() const {return m_font_scheme;}
void setHasFont(bool has) {m_has_font=has;}
//fills
bool hasFill() const {return m_has_fill;}
@ -86,10 +138,8 @@ private:
bool m_has_font;
int m_font_index;
QFont m_font;
int m_font_family;
QString m_font_scheme;
QColor m_font_color;
QColor m_bg_color;
QColor m_fg_color;
int m_theme;

31
src/xlsxstyles.cpp

@ -35,17 +35,19 @@ Styles::Styles(QObject *parent) :
{
m_fill_count = 2; //Starts from 2
m_borders_count = 1;
m_font_count = 1;
m_font_count = 0;
//Add the default cell format
Format *format = addFormat();
format->setHasFont(true);
format->setHasBorder(true);
}
Format *Styles::addFormat()
{
Format *format = new Format(this);
Format *format = new Format();
format->setXfIndex(m_formats.size());
m_font_count += 1;
m_formats.append(format);
return format;
}
@ -109,18 +111,33 @@ void Styles::writeFonts(XmlStreamWriter &writer)
foreach (Format *format, m_xf_formats) {
if (format->hasFont()) {
writer.writeStartElement("font");
if (format->bold())
if (format->fontBold())
writer.writeEmptyElement("b");
if (format->italic())
if (format->fontItalic())
writer.writeEmptyElement("i");
if (format->fontStrikout())
if (format->fontStrikeOut())
writer.writeEmptyElement("strike");
if (format->fontOutline())
writer.writeEmptyElement("outline");
if (format->fontShadow())
writer.writeEmptyElement("shadow");
if (format->fontUnderline()) //More option
if (format->fontUnderline() != Format::FontUnderlineNone) {
writer.writeEmptyElement("u");
if (format->fontUnderline() == Format::FontUnderlineDouble)
writer.writeAttribute("val", "double");
else if (format->fontUnderline() == Format::FontUnderlineSingleAccounting)
writer.writeAttribute("val", "singleAccounting");
else if (format->fontUnderline() == Format::FontUnderlineDoubleAccounting)
writer.writeAttribute("val", "doubleAccounting");
}
if (format->fontScript() != Format::FontScriptNormal) {
writer.writeEmptyElement("vertAligh");
if (format->fontScript() == Format::FontScriptSuper)
writer.writeAttribute("val", "superscript");
else
writer.writeAttribute("val", "subscript");
}
if (!format->isDxfFormat()) {
writer.writeEmptyElement("sz");
writer.writeAttribute("val", QString::number(format->fontSize()));

45
src/xlsxworksheet.cpp

@ -24,6 +24,7 @@
****************************************************************************/
#include "xlsxworksheet.h"
#include "xlsxworkbook.h"
#include "xlsxformat.h"
#include "xlsxutility_p.h"
#include "xlsxsharedstrings_p.h"
#include "xmlstreamwriter_p.h"
@ -124,34 +125,34 @@ void Worksheet::setZeroValuesHidden(bool enable)
m_show_zeros = !enable;
}
int Worksheet::write(int row, int column, const QVariant &value)
int Worksheet::write(int row, int column, const QVariant &value, Format *format)
{
bool ok;
int ret = 0;
if (value.isNull()) { //blank
ret = writeBlank(row, column);
ret = writeBlank(row, column, format);
} else if (value.type() == QMetaType::Bool) { //Bool
ret = writeBool(row,column, value.toBool());
ret = writeBool(row,column, value.toBool(), format);
} else if (value.toDateTime().isValid()) { //DateTime
} else if (value.toDouble(&ok), ok) { //Number
if (!m_workbook->isStringsToNumbersEnabled() && value.type() == QMetaType::QString) {
//Don't convert string to number if the flag not enabled.
ret = writeString(row, column, value.toString());
ret = writeString(row, column, value.toString(), format);
} else {
ret = writeNumber(row, column, value.toDouble());
ret = writeNumber(row, column, value.toDouble(), format);
}
} else if (value.type() == QMetaType::QUrl) { //url
} else if (value.type() == QMetaType::QString) { //string
QString token = value.toString();
if (token.startsWith("=")) {
ret = writeFormula(row, column, token);
ret = writeFormula(row, column, token, format);
} else if (token.startsWith("{") && token.endsWith("}")) {
} else {
ret = writeString(row, column, token);
ret = writeString(row, column, token, format);
}
} else { //Wrong type
@ -162,16 +163,16 @@ int Worksheet::write(int row, int column, const QVariant &value)
}
//convert the "A1" notation to row/column notation
int Worksheet::write(const QString row_column, const QVariant &value)
int Worksheet::write(const QString row_column, const QVariant &value, Format *format)
{
QPoint pos = xl_cell_to_rowcol(row_column);
if (pos == QPoint(-1, -1)) {
return -1;
}
return write(pos.x(), pos.y(), value);
return write(pos.x(), pos.y(), value, format);
}
int Worksheet::writeString(int row, int column, const QString &value)
int Worksheet::writeString(int row, int column, const QString &value, Format *format)
{
int error = 0;
QString content = value;
@ -186,20 +187,20 @@ int Worksheet::writeString(int row, int column, const QString &value)
SharedStrings *sharedStrings = m_workbook->sharedStrings();
int index = sharedStrings->addSharedString(content);
m_table[row][column] = XlsxCellData(index, XlsxCellData::String);
m_table[row][column] = XlsxCellData(index, XlsxCellData::String, format);
return error;
}
int Worksheet::writeNumber(int row, int column, double value)
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);
m_table[row][column] = XlsxCellData(value, XlsxCellData::Number, format);
return 0;
}
int Worksheet::writeFormula(int row, int column, const QString &content, double result)
int Worksheet::writeFormula(int row, int column, const QString &content, Format *format, double result)
{
int error = 0;
QString formula = content;
@ -210,28 +211,28 @@ int Worksheet::writeFormula(int row, int column, const QString &content, double
if (formula.startsWith("="))
formula.remove(0,1);
XlsxCellData data(result, XlsxCellData::Formula);
XlsxCellData data(result, XlsxCellData::Formula, format);
data.formula = formula;
m_table[row][column] = data;
return error;
}
int Worksheet::writeBlank(int row, int column)
int Worksheet::writeBlank(int row, int column, Format *format)
{
if (checkDimensions(row, column))
return -1;
m_table[row][column] = XlsxCellData(QVariant(), XlsxCellData::Blank);
m_table[row][column] = XlsxCellData(QVariant(), XlsxCellData::Blank, format);
return 0;
}
int Worksheet::writeBool(int row, int column, bool value)
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);
m_table[row][column] = XlsxCellData(value, XlsxCellData::Boolean, format);
return 0;
}
@ -386,8 +387,10 @@ void Worksheet::writeCellData(XmlStreamWriter &writer, int row, int col, const X
writer.writeStartElement("c");
writer.writeAttribute("r", cell_range);
//Style used by the cell, row /col
// writer.writeAttribute("s", QString::number(""));
//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

18
src/xlsxworksheet.h

@ -47,8 +47,8 @@ struct XlsxCellData
ArrayFormula,
Boolean
};
XlsxCellData(const QVariant &data=QVariant(), CellDataType type=Blank) :
value(data), dataType(type), format(0)
XlsxCellData(const QVariant &data=QVariant(), CellDataType type=Blank, Format *format=0) :
value(data), dataType(type), format(format)
{
}
@ -63,13 +63,13 @@ class Worksheet : public QObject
{
Q_OBJECT
public:
int write(const QString row_column, const QVariant &value);
int write(int row, int column, const QVariant &value);
int writeString(int row, int column, const QString &value);
int writeNumber(int row, int column, double value);
int writeFormula(int row, int column, const QString &formula, double result=0);
int writeBlank(int row, int column);
int writeBool(int row, int column, bool value);
int write(const QString row_column, const QVariant &value, Format *format=0);
int write(int row, int column, const QVariant &value, Format *format=0);
int writeString(int row, int column, const QString &value, Format *format=0);
int writeNumber(int row, int column, double value, Format *format=0);
int writeFormula(int row, int column, const QString &formula, Format *format=0, double result=0);
int writeBlank(int row, int column, Format *format=0);
int writeBool(int row, int column, bool value, Format *format=0);
void setRightToLeft(bool enable);
void setZeroValuesHidden(bool enable);

1
src/zipwriter.cpp

@ -47,7 +47,6 @@ void ZipWriter::addFile(const QString &filePath, QIODevice *device)
void ZipWriter::addFile(const QString &filePath, const QByteArray &data)
{
qDebug()<<filePath<<data.size();
m_writer->addFile(filePath, data);
}

Loading…
Cancel
Save