Browse Source

Long live QtXlsxWriter!

master
Debao Zhang 12 years ago
commit
4ec93ecb41
  1. 43
      .gitignore
  2. 3
      examples/examples.pro
  3. 5
      examples/hello/hello.pro
  4. 16
      examples/hello/main.cpp
  5. 0
      qtxlsxwriter.pro
  6. 32
      src/qtxlsxwriter.pri
  7. 6
      src/qxlsxwriter.cpp
  8. 23
      src/qxlsxwriter.h
  9. 144
      src/xlsxcontenttypes.cpp
  10. 68
      src/xlsxcontenttypes_p.h
  11. 129
      src/xlsxdocprops.cpp
  12. 57
      src/xlsxdocprops_p.h
  13. 123
      src/xlsxformat.cpp
  14. 107
      src/xlsxformat.h
  15. 274
      src/xlsxpackage.cpp
  16. 70
      src/xlsxpackage_p.h
  17. 92
      src/xlsxrelationships.cpp
  18. 63
      src/xlsxrelationships_p.h
  19. 102
      src/xlsxsharedstrings.cpp
  20. 58
      src/xlsxsharedstrings_p.h
  21. 240
      src/xlsxstyles.cpp
  22. 63
      src/xlsxstyles_p.h
  23. 43
      src/xlsxtheme.cpp
  24. 42
      src/xlsxtheme_p.h
  25. 111
      src/xlsxutility.cpp
  26. 39
      src/xlsxutility_p.h
  27. 234
      src/xlsxworkbook.cpp
  28. 90
      src/xlsxworkbook.h
  29. 479
      src/xlsxworksheet.cpp
  30. 131
      src/xlsxworksheet.h
  31. 36
      src/xmlstreamwriter.cpp
  32. 41
      src/xmlstreamwriter_p.h
  33. 59
      src/zipwriter.cpp
  34. 51
      src/zipwriter_p.h

43
.gitignore

@ -0,0 +1,43 @@
syntax: glob
*.pro.user*
*.autosave
*.app
*.moc
*.prl
Makefile*
doc/html/
*.framework/
*.xcodeproj/
debug/
release/
qtc-gdbmacros/
*.rej
*.orig
*.obj
*.swp
*.dll
*.exp
*.ilk
*.pdb
*.lib
Thumbs.db
moc_*.cpp
qrc_*.cpp
*.o
*.so.*
*.so
*.pdb
ui_*.h
*~
.qmake.cache
lib/*
*.orig
*.exe
*.vcproj
*.vcproj.*.user
*_resource.rc
*.sln
*.idb
*.ncb
*.suo

3
examples/examples.pro

@ -0,0 +1,3 @@
TEMPLATE = subdirs
SUBDIRS = hello

5
examples/hello/hello.pro

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

16
examples/hello/main.cpp

@ -0,0 +1,16 @@
#include <QtCore>
#include "xlsxworkbook.h"
#include "xlsxworksheet.h"
int main(int argc, char* argv[])
{
#ifdef Q_OS_MAC
QXlsx::Workbook workbook("../../../Test.xlsx");
#else
QXlsx::Workbook workbook("Test.xlsx");
#endif
QXlsx::Worksheet *sheet = workbook.addWorksheet();
sheet->write("A1", "Hello Qt!");
workbook.close();
return 0;
}

0
qtxlsxwriter.pro

32
src/qtxlsxwriter.pri

@ -0,0 +1,32 @@
INCLUDEPATH += $$PWD
DEPENDPATH += $$PWD
QT += core gui gui-private
HEADERS += $$PWD/xlsxdocprops_p.h \
$$PWD/xlsxrelationships_p.h \
$$PWD/xlsxutility_p.h \
$$PWD/xlsxsharedstrings_p.h \
$$PWD/xmlstreamwriter_p.h \
$$PWD/xlsxcontenttypes_p.h \
$$PWD/xlsxtheme_p.h \
$$PWD/xlsxformat.h \
$$PWD/xlsxworkbook.h \
$$PWD/xlsxstyles_p.h \
$$PWD/xlsxworksheet.h \
$$PWD/zipwriter_p.h \
$$PWD/xlsxpackage_p.h
SOURCES += $$PWD/xlsxdocprops.cpp \
$$PWD/xlsxrelationships.cpp \
$$PWD/xlsxutility.cpp \
$$PWD/xlsxsharedstrings.cpp \
$$PWD/xmlstreamwriter.cpp \
$$PWD/xlsxcontenttypes.cpp \
$$PWD/xlsxtheme.cpp \
$$PWD/xlsxformat.cpp \
$$PWD/xlsxstyles.cpp \
$$PWD/xlsxworkbook.cpp \
$$PWD/xlsxworksheet.cpp \
$$PWD/zipwriter.cpp \
$$PWD/xlsxpackage.cpp

6
src/qxlsxwriter.cpp

@ -0,0 +1,6 @@
#include "qxlsxwriter.h"
QXlsxWriter::QXlsxWriter(QObject *parent) :
QObject(parent)
{
}

23
src/qxlsxwriter.h

@ -0,0 +1,23 @@
#ifndef QXLSXWRITER_H
#define QXLSXWRITER_H
#include <QObject>
class QXlsxWriter : public QObject
{
Q_OBJECT
public:
explicit QXlsxWriter(QObject *parent = 0);
// void worksheets();
signals:
public slots:
// void addWorksheet(QString name);
// void addFormat();
// void addChart();
// void setProperties();
};
#endif // QXLSXWRITER_H

144
src/xlsxcontenttypes.cpp

@ -0,0 +1,144 @@
/****************************************************************************
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
** All right reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#include "xlsxcontenttypes_p.h"
#include "xmlstreamwriter_p.h"
#include <QFile>
#include <QMapIterator>
namespace QXlsx {
ContentTypes::ContentTypes()
{
m_package_prefix = "application/vnd.openxmlformats-package.";
m_document_prefix = "application/vnd.openxmlformats-officedocument.";
m_defaults.insert("rels", m_package_prefix + "relationships+xml");
m_defaults.insert("xml", "application/xml");
m_overrides.insert("/docProps/app.xml", m_document_prefix + "extended-properties+xml");
m_overrides.insert("/docProps/core.xml", m_package_prefix + "core-properties+xml");
m_overrides.insert("/xl/styles.xml", m_document_prefix + "spreadsheetml.styles+xml");
m_overrides.insert("/xl/theme/theme1.xml", m_document_prefix + "theme+xml");
m_overrides.insert("/xl/workbook.xml", m_document_prefix + "spreadsheetml.sheet.main+xml");
}
void ContentTypes::addDefault(const QString &key, const QString &value)
{
m_defaults.insert(key, value);
}
void ContentTypes::addOverride(const QString &key, const QString &value)
{
m_overrides.insert(key, value);
}
void ContentTypes::addWorksheetName(const QString &name)
{
addOverride(QString("/xl/worksheets/%1.xml").arg(name), m_document_prefix + "spreadsheetml.worksheet+xml");
}
void ContentTypes::addChartsheetName(const QString &name)
{
addOverride(QString("/xl/chartsheets/%1.xml").arg(name), m_document_prefix + "spreadsheetml.chartsheet+xml");
}
void ContentTypes::addChartName(const QString &name)
{
addOverride(QString("/xl/charts/%1.xml").arg(name), m_document_prefix + "drawingml.chart+xml");
}
void ContentTypes::addCommentName(const QString &name)
{
addOverride(QString("/xl/%1.xml").arg(name), m_document_prefix + "spreadsheetml.comments+xml");
}
void ContentTypes::addImageTypes(const QStringList &imageTypes)
{
foreach (QString type, imageTypes)
addOverride(type, "image/" + type);
}
void ContentTypes::addTableName(const QString &name)
{
addOverride(QString("/xl/tables/%1.xml").arg(name), m_document_prefix + "spreadsheetml.table+xml");
}
void ContentTypes::addSharedString()
{
addOverride("/xl/sharedStrings.xml", m_document_prefix + "spreadsheetml.sharedStrings+xml");
}
void ContentTypes::addVmlName()
{
addOverride("vml", m_document_prefix + "vmlDrawing");
}
void ContentTypes::addCalcChain()
{
addOverride("/xl/calcChain.xml", m_document_prefix + "spreadsheetml.calcChain+xml");
}
void ContentTypes::addVbaProject()
{
//:TODO
addOverride("bin", "application/vnd.ms-office.vbaProject");
}
void ContentTypes::saveToXmlFile(QIODevice *device)
{
XmlStreamWriter writer(device);
writer.writeStartDocument("1.0", true);
writer.writeStartElement("Types");
writer.writeAttribute("xmlns", "http://schemas.openxmlformats.org/package/2006/content-types");
{
QMapIterator<QString, QString> it(m_defaults);
while(it.hasNext()) {
it.next();
writer.writeStartElement("Default");
writer.writeAttribute("Extension", it.key());
writer.writeAttribute("ContentType", it.value());
writer.writeEndElement();//Default
}
}
{
QMapIterator<QString, QString> it(m_overrides);
while(it.hasNext()) {
it.next();
writer.writeStartElement("Override");
writer.writeAttribute("PartName", it.key());
writer.writeAttribute("ContentType", it.value());
writer.writeEndElement(); //Override
}
}
writer.writeEndElement();//Types
writer.writeEndDocument();
}
} //namespace QXlsx

68
src/xlsxcontenttypes_p.h

@ -0,0 +1,68 @@
/****************************************************************************
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
** All right reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#ifndef XLSXCONTENTTYPES_H
#define XLSXCONTENTTYPES_H
#include <QString>
#include <QStringList>
#include <QMap>
class QIODevice;
namespace QXlsx {
class ContentTypes
{
public:
ContentTypes();
void addDefault(const QString &key, const QString &value);
void addOverride(const QString &key, const QString &value);
//Convenient funcation for addOverride()
void addWorksheetName(const QString &name);
void addChartsheetName(const QString &name);
void addChartName(const QString &name);
void addDrawingName(const QString &name);
void addCommentName(const QString &name);
void addImageTypes(const QStringList &imageTypes);
void addTableName(const QString &name);
void addSharedString();
void addVmlName();
void addCalcChain();
void addVbaProject();
void saveToXmlFile(QIODevice *device);
private:
QMap<QString, QString> m_defaults;
QMap<QString, QString> m_overrides;
QString m_package_prefix;
QString m_document_prefix;
};
}
#endif // XLSXCONTENTTYPES_H

129
src/xlsxdocprops.cpp

@ -0,0 +1,129 @@
/****************************************************************************
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
** All right reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#include "xlsxdocprops_p.h"
#include "xmlstreamwriter_p.h"
#include <QDir>
#include <QFile>
#include <QDateTime>
namespace QXlsx {
DocProps::DocProps(QObject *parent) :
QObject(parent)
{
}
void DocProps::addPartTitle(const QString &title)
{
m_titlesOfPartsList.append(title);
}
void DocProps::addHeadingPair(const QString &name, int value)
{
m_headingPairsList.append(qMakePair(name, value));
}
void DocProps::saveToXmlFile_App(QIODevice *device)
{
XmlStreamWriter writer(device);
writer.writeStartDocument("1.0", true);
writer.writeStartElement("Properties");
writer.writeAttribute("xmlns", "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties");
writer.writeAttribute("xmlns:vt", "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes");
writer.writeTextElement("Application", "Microsoft Excel");
writer.writeTextElement("DocSecurity", "0");
writer.writeTextElement("ScaleCrop", "false");
writer.writeStartElement("HeadingPairs");
writer.writeStartElement("vt:vector");
writer.writeAttribute("size", QString::number(m_headingPairsList.size()*2));
writer.writeAttribute("baseType", "variant");
typedef QPair<QString,int> PairType; //Make foreach happy
foreach (PairType pair, m_headingPairsList) {
writer.writeStartElement("vt:variant");
writer.writeTextElement("vt:lpstr", pair.first);
writer.writeEndElement(); //vt:variant
writer.writeStartElement("vt:variant");
writer.writeTextElement("vt:i4", QString::number(pair.second));
writer.writeEndElement(); //vt:variant
}
writer.writeEndElement();//vt:vector
writer.writeEndElement();//HeadingPairs
writer.writeStartElement("TitlesOfParts");
writer.writeStartElement("vt:vector");
writer.writeAttribute("size", QString::number(m_titlesOfPartsList.size()));
writer.writeAttribute("baseType", "lpstr");
foreach (QString title, m_titlesOfPartsList)
writer.writeTextElement("vt:lpstr", title);
writer.writeEndElement();//vt:vector
writer.writeEndElement();//TitlesOfParts
writer.writeTextElement("Company", "");
writer.writeTextElement("LinksUpToDate", "false");
writer.writeTextElement("SharedDoc", "false");
writer.writeTextElement("HyperlinksChanged", "false");
writer.writeTextElement("AppVersion", "12.0000");
writer.writeEndElement(); //Properties
writer.writeEndDocument();
}
void DocProps::saveToXmlFile_Core(QIODevice *device)
{
XmlStreamWriter writer(device);
writer.writeStartDocument("1.0", true);
writer.writeStartElement("cp:coreProperties");
writer.writeAttribute("xmlns:cp", "http://schemas.openxmlformats.org/package/2006/metadata/core-properties");
writer.writeAttribute("xmlns:dc", "http://purl.org/dc/elements/1.1/");
writer.writeAttribute("xmlns:dcterms", "http://purl.org/dc/terms/");
writer.writeAttribute("xmlns:dcmitype", "http://purl.org/dc/dcmitype/");
writer.writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
writer.writeTextElement("dc:title", "");
writer.writeTextElement("dc:subject", "");
writer.writeTextElement("dc:creator", "QXlsxWriter");
writer.writeTextElement("cp:keywords", "");
writer.writeTextElement("dc:description", "");
writer.writeTextElement("cp:lastModifiedBy", "");
writer.writeStartElement("dcterms:created");
writer.writeAttribute("xsi:type", "dcterms:W3CDTF");
writer.writeCharacters(QDateTime::currentDateTime().toString(Qt::ISODate));
writer.writeEndElement();//dcterms:created
writer.writeStartElement("dcterms:modified");
writer.writeAttribute("xsi:type", "dcterms:W3CDTF");
writer.writeCharacters(QDateTime::currentDateTime().toString(Qt::ISODate));
writer.writeEndElement();//dcterms:created
writer.writeTextElement("cp", "category", "");
writer.writeTextElement("cp", "contentStatus", "");
writer.writeEndElement(); //cp:coreProperties
writer.writeEndDocument();
}
} //namespace

57
src/xlsxdocprops_p.h

@ -0,0 +1,57 @@
/****************************************************************************
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
** All right reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#ifndef XLSXDOCPROPS_H
#define XLSXDOCPROPS_H
#include <QObject>
#include <QList>
#include <QPair>
#include <QStringList>
class QIODevice;
namespace QXlsx {
class DocProps : public QObject
{
Q_OBJECT
public:
explicit DocProps(QObject *parent = 0);
signals:
public slots:
void addPartTitle(const QString &title);
void addHeadingPair(const QString &name, int value);
void saveToXmlFile_App(QIODevice *device);
void saveToXmlFile_Core(QIODevice *device);
private:
QStringList m_titlesOfPartsList;
QList<QPair<QString, int> > m_headingPairsList;
};
}
#endif // XLSXDOCPROPS_H

123
src/xlsxformat.cpp

@ -0,0 +1,123 @@
/****************************************************************************
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
** All right reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#include "xlsxformat.h"
namespace QXlsx {
Format::Format(QObject *parent) :
QObject(parent)
{
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;
m_has_fill = false;
m_fill_index = 0;
m_has_borders = false;
m_border_index = false;
}
bool Format::isDxfFormat() const
{
return m_is_dxf_fomat;
}
void Format::setFont(const QFont &font)
{
m_font = font;
}
void Format::setForegroundColor(const QColor &color)
{
m_fg_color = color;
}
void Format::setBackgroundColor(const QColor &color)
{
m_bg_color = color;
}
QString Format::fontName() const
{
return m_font.family();
}
bool Format::bold() const
{
return m_font.weight() == QFont::Bold;
}
bool Format::italic() const
{
return m_font.italic();
}
bool Format::fontOutline() const
{
return false;
}
bool Format::fontShadow() const
{
return false;
}
bool Format::fontStrikout() const
{
return m_font.strikeOut();
}
bool Format::fontUnderline() const
{
return m_font.underline();
}
QColor Format::fontColor() const
{
return m_font_color;
}
int Format::fontSize() const
{
return m_font.pointSize();
}
} // namespace QXlsx

107
src/xlsxformat.h

@ -0,0 +1,107 @@
/****************************************************************************
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
** All right reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#ifndef QXLSX_FORMAT_H
#define QXLSX_FORMAT_H
#include <QObject>
#include <QFont>
#include <QColor>
namespace QXlsx {
class Styles;
class Format : public QObject
{
Q_OBJECT
public:
void setFont(const QFont &font);
void setForegroundColor(const QColor &color);
void setBackgroundColor(const QColor &color);
private:
friend class Styles;
explicit Format(QObject *parent = 0);
bool isDxfFormat() const;
//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;}
int fillIndex() const {return m_fill_index;}
//borders
bool hasBorders() const {return m_has_borders;}
void setHasBorder(bool has) {m_has_borders=has;}
int borderIndex() const {return m_border_index;}
bool m_is_dxf_fomat;
int m_xf_index;
int m_dxf_index;
int m_num_format_index;
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;
int m_color_indexed;
bool m_has_fill;
int m_fill_index;
bool m_has_borders;
int m_border_index;
};
} // namespace QXlsx
#endif // QXLSX_FORMAT_H

274
src/xlsxpackage.cpp

@ -0,0 +1,274 @@
/****************************************************************************
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
** All right reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#include "xlsxpackage_p.h"
#include "xlsxworkbook.h"
#include "xlsxworksheet.h"
#include "xlsxcontenttypes_p.h"
#include "xlsxsharedstrings_p.h"
#include "xlsxdocprops_p.h"
#include "xlsxtheme_p.h"
#include "xlsxstyles_p.h"
#include "xlsxrelationships_p.h"
#include "zipwriter_p.h"
#include <QBuffer>
#include <QDebug>
namespace QXlsx {
/*
From Wikipedia: The Open Packaging Conventions (OPC) is a
container-file technology initially created by Microsoft to store
a combination of XML and non-XML files that together form a single
entity such as an Open XML Paper Specification (OpenXPS)
document. http://en.wikipedia.org/wiki/Open_Packaging_Conventions.
At its simplest an Excel XLSX file contains the following elements:
____ [Content_Types].xml
|
|____ docProps
| |____ app.xml
| |____ core.xml
|
|____ xl
| |____ workbook.xml
| |____ worksheets
| | |____ sheet1.xml
| |
| |____ styles.xml
| |
| |____ theme
| | |____ theme1.xml
| |
| |_____rels
| |____ workbook.xml.rels
|
|_____rels
|____ .rels
The Packager class coordinates the classes that represent the
elements of the package and writes them into the XLSX file.
*/
Package::Package(Workbook *workbook) :
m_workbook(workbook)
{
m_worksheet_count = 0;
m_chartsheet_count = 0;
foreach (Worksheet *sheet, m_workbook->worksheets()) {
if (sheet->isChartsheet())
m_chartsheet_count += 1;
else
m_worksheet_count += 1;
}
}
bool Package::createPackage(const QString &packageName)
{
QString fileName = packageName.isEmpty() ? m_workbook->fileName() : packageName;
ZipWriter zipWriter(fileName);
writeWorksheetFiles(zipWriter);
// writeChartsheetFiles(zipWriter);
writeWorkbookFile(zipWriter);
// writeChartFiles(zipWriter);
// writeDrawingFiles(zipWriter);
// writeVmlFiles(zipWriter);
// writeCommentFiles(zipWriter);
// writeTableFiles(zipWriter);
writeSharedStringsFile(zipWriter);
writeDocPropsFiles(zipWriter);
writeContentTypesFiles(zipWriter);
writeStylesFiles(zipWriter);
writeThemeFile(zipWriter);
writeRootRelsFile(zipWriter);
writeWorkbookRelsFile(zipWriter);
writeWorksheetRelsFile(zipWriter);
// writeChartsheetRelsFile(zipWriter);
// writeImageFiles(zipWriter);
// writeVbaProjectFiles(zipWriter);
zipWriter.close();
return true;
}
void Package::writeWorksheetFiles(ZipWriter &zipWriter)
{
int index = 1;
foreach (Worksheet *sheet, m_workbook->worksheets()) {
if (sheet->isChartsheet())
continue;
QByteArray data;
QBuffer buffer(&data);
buffer.open(QIODevice::WriteOnly);
sheet->saveToXmlFile(&buffer);
zipWriter.addFile(QString("xl/worksheets/sheet%1.xml").arg(index), data);
index += 1;
}
}
void Package::writeWorkbookFile(ZipWriter &zipWriter)
{
QByteArray data;
QBuffer buffer(&data);
buffer.open(QIODevice::WriteOnly);
m_workbook->saveToXmlFile(&buffer);
zipWriter.addFile("xl/workbook.xml", data);
}
void Package::writeContentTypesFiles(ZipWriter &zipWriter)
{
ContentTypes content;
int worksheet_index = 1;
foreach (Worksheet *sheet, m_workbook->worksheets()) {
if (sheet->isChartsheet()) {
} else {
content.addWorksheetName(QString("sheet%1").arg(worksheet_index));
worksheet_index += 1;
}
}
if (m_workbook->sharedStrings()->count())
content.addSharedString();
QByteArray data;
QBuffer buffer(&data);
buffer.open(QIODevice::WriteOnly);
content.saveToXmlFile(&buffer);
zipWriter.addFile("[Content_Types].xml", data);
}
void Package::writeDocPropsFiles(ZipWriter &zipWriter)
{
DocProps props;
if (m_worksheet_count)
props.addHeadingPair("Worksheets", m_worksheet_count);
if (m_chartsheet_count)
props.addHeadingPair("Chartsheets", m_chartsheet_count);
//Add worksheet parts
foreach (Worksheet *sheet, m_workbook->worksheets()){
if (!sheet->isChartsheet())
props.addPartTitle(sheet->name());
}
//Add the chartsheet parts
foreach (Worksheet *sheet, m_workbook->worksheets()){
if (sheet->isChartsheet())
props.addPartTitle(sheet->name());
}
QByteArray data1;
QBuffer buffer1(&data1);
buffer1.open(QIODevice::WriteOnly);
props.saveToXmlFile_App(&buffer1);
zipWriter.addFile("docProps/app.xml", data1);
QByteArray data2;
QBuffer buffer2(&data2);
buffer2.open(QIODevice::WriteOnly);
props.saveToXmlFile_Core(&buffer2);
zipWriter.addFile("docProps/core.xml", data2);
}
void Package::writeSharedStringsFile(ZipWriter &zipWriter)
{
QByteArray data;
QBuffer buffer(&data);
buffer.open(QIODevice::WriteOnly);
m_workbook->sharedStrings()->saveToXmlFile(&buffer);
zipWriter.addFile("xl/sharedStrings.xml", data);
}
void Package::writeStylesFiles(ZipWriter &zipWriter)
{
QByteArray data;
QBuffer buffer(&data);
buffer.open(QIODevice::WriteOnly);
m_workbook->styles()->saveToXmlFile(&buffer);
zipWriter.addFile("xl/styles.xml", data);
}
void Package::writeThemeFile(ZipWriter &zipWriter)
{
QByteArray data;
QBuffer buffer(&data);
buffer.open(QIODevice::WriteOnly);
Theme().saveToXmlFile(&buffer);
zipWriter.addFile("xl/theme/theme1.xml", data);
}
void Package::writeRootRelsFile(ZipWriter &zipWriter)
{
Relationships rels;
rels.addDocumentRelationship("/officeDocument", "xl/workbook.xml");
rels.addPackageRelationship("/metadata/core-properties", "docProps/core.xml");
rels.addDocumentRelationship("/extended-properties", "docProps/app.xml");
QByteArray data;
QBuffer buffer(&data);
buffer.open(QIODevice::WriteOnly);
rels.saveToXmlFile(&buffer);
zipWriter.addFile("_rels/.rels", data);
}
void Package::writeWorkbookRelsFile(ZipWriter &zipWriter)
{
Relationships rels;
int worksheet_index = 1;
int chartsheet_index = 1;
foreach (Worksheet *sheet, m_workbook->worksheets()) {
if (sheet->isChartsheet()) {
rels.addDocumentRelationship("/chartsheet", QString("chartsheets/sheet%1.xml").arg(chartsheet_index));
chartsheet_index += 1;
} else {
rels.addDocumentRelationship("/worksheet", QString("worksheets/sheet%1.xml").arg(worksheet_index));
worksheet_index += 1;
}
}
rels.addDocumentRelationship("/theme", "theme/theme1.xml");
rels.addDocumentRelationship("/styles", "styles.xml");
if (m_workbook->sharedStrings()->count())
rels.addDocumentRelationship("/sharedStrings", "sharedStrings.xml");
QByteArray data;
QBuffer buffer(&data);
buffer.open(QIODevice::WriteOnly);
rels.saveToXmlFile(&buffer);
zipWriter.addFile("xl/_rels/workbook.xml.rels", data);
}
void Package::writeWorksheetRelsFile(ZipWriter &zipWriter)
{
}
} // namespace QXlsx

70
src/xlsxpackage_p.h

@ -0,0 +1,70 @@
/****************************************************************************
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
** All right reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#ifndef QXLSX_PACKAGE_H
#define QXLSX_PACKAGE_H
#include <QString>
namespace QXlsx {
class Workbook;
class ZipWriter;
class Package
{
public:
Package(Workbook *workbook);
bool createPackage(const QString &packageName=QString());
private:
void writeWorksheetFiles(ZipWriter &zipWriter);
// void writeChartsheetFiles(ZipWriter &zipWriter);
void writeWorkbookFile(ZipWriter &zipWriter);
// void writeChartFiles(ZipWriter &zipWriter);
// void writeDrawingFiles(ZipWriter &zipWriter);
// void writeVmlFiles(ZipWriter &zipWriter);
// void writeCommentFiles(ZipWriter &zipWriter);
// void writeTableFiles(ZipWriter &zipWriter);
void writeSharedStringsFile(ZipWriter &zipWriter);
void writeDocPropsFiles(ZipWriter &zipWriter);
void writeContentTypesFiles(ZipWriter &zipWriter);
void writeStylesFiles(ZipWriter &zipWriter);
void writeThemeFile(ZipWriter &zipWriter);
void writeRootRelsFile(ZipWriter &zipWriter);
void writeWorkbookRelsFile(ZipWriter &zipWriter);
void writeWorksheetRelsFile(ZipWriter &zipWriter);
// void writeChartsheetRelsFile(ZipWriter &zipWriter);
// void writeImageFiles(ZipWriter &zipWriter);
// void writeVbaProjectFiles(ZipWriter &zipWriter);
Workbook * m_workbook;
int m_worksheet_count;
int m_chartsheet_count;
};
} // namespace QXlsx
#endif // QXLSX_PACKAGE_H

92
src/xlsxrelationships.cpp

@ -0,0 +1,92 @@
/****************************************************************************
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
** All right reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#include "xlsxrelationships_p.h"
#include "xmlstreamwriter_p.h"
#include <QDir>
#include <QFile>
namespace QXlsx {
Relationships::Relationships(QObject *parent) :
QObject(parent)
{
}
void Relationships::addDocumentRelationship(const QString &relativeType, const QString &target)
{
QString type = "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + relativeType;
addRelationship(type, target);
}
void Relationships::addMsPackageRelationship(const QString &relativeType, const QString &target)
{
QString type = "http://schemas.microsoft.com/office/2006/relationships" + relativeType;
addRelationship(type, target);
}
void Relationships::addPackageRelationship(const QString &relativeType, const QString &target)
{
QString type = "http://schemas.openxmlformats.org/package/2006/relationships" + relativeType;
addRelationship(type, target);
}
void Relationships::addWorksheetRelationship(const QString &relativeType, const QString &target, const QString &targetMode)
{
QString type = "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + relativeType;
addRelationship(type, target, targetMode);
}
void Relationships::addRelationship(const QString &type, const QString &target, const QString &targetMode)
{
XlsxRelationship relation;
relation.id = QString("rId%1").arg(m_relationships.size()+1);
relation.type = type;
relation.target = target;
relation.targetMode = targetMode;
m_relationships.append(relation);
}
void Relationships::saveToXmlFile(QIODevice *device)
{
XmlStreamWriter writer(device);
writer.writeStartDocument("1.0", true);
writer.writeStartElement("Relationships");
writer.writeAttribute("xmlns", "http://schemas.openxmlformats.org/package/2006/relationships");
foreach (XlsxRelationship relation, m_relationships) {
writer.writeStartElement("Relationship");
writer.writeAttribute("Id", relation.id);
writer.writeAttribute("Type", relation.type);
writer.writeAttribute("Target", relation.target);
if (!relation.targetMode.isNull())
writer.writeAttribute("TargetMode", relation.targetMode);
writer.writeEndElement();
}
writer.writeEndElement();//Relationships
writer.writeEndDocument();
}
} //namespace

63
src/xlsxrelationships_p.h

@ -0,0 +1,63 @@
/****************************************************************************
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
** All right reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#ifndef XLSXRELATIONSHIPS_H
#define XLSXRELATIONSHIPS_H
#include <QObject>
#include <QList>
class QIODevice;
namespace QXlsx {
struct XlsxRelationship
{
QString id;
QString type;
QString target;
QString targetMode;
};
class Relationships : public QObject
{
Q_OBJECT
public:
explicit Relationships(QObject *parent = 0);
signals:
public slots:
void addDocumentRelationship(const QString &relativeType, const QString &target);
void addPackageRelationship(const QString &relativeType, const QString &target);
void addMsPackageRelationship(const QString &relativeType, const QString &target);
void addWorksheetRelationship(const QString &relativeType, const QString &target, const QString &targetMode=QString());
void saveToXmlFile(QIODevice *device);
private:
void addRelationship(const QString &type, const QString &target, const QString &targetMode=QString());
QList<XlsxRelationship> m_relationships;
};
}
#endif // XLSXRELATIONSHIPS_H

102
src/xlsxsharedstrings.cpp

@ -0,0 +1,102 @@
/****************************************************************************
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
** All right reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#include "xlsxsharedstrings_p.h"
#include "xmlstreamwriter_p.h"
#include <QDir>
#include <QFile>
#include <QRegularExpression>
#include <QDebug>
namespace QXlsx {
SharedStrings::SharedStrings(QObject *parent) :
QObject(parent)
{
m_stringCount = 0;
}
int SharedStrings::count() const
{
return m_stringCount;
}
int SharedStrings::addSharedString(const QString &string)
{
m_stringCount += 1;
if (m_stringTable.contains(string))
return m_stringTable[string];
int index = m_stringTable.size();
m_stringTable[string] = index;
m_stringList.append(string);
return index;
}
int SharedStrings::getSharedStringIndex(const QString &string) const
{
return m_stringTable[string];
}
QString SharedStrings::getSharedString(int index) const
{
return m_stringList[index];
}
QStringList SharedStrings::getSharedStrings() const
{
return m_stringList;
}
void SharedStrings::saveToXmlFile(QIODevice *device) const
{
XmlStreamWriter writer(device);
writer.writeStartDocument("1.0", true);
writer.writeStartElement("sst");
writer.writeAttribute("xmlns", "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
writer.writeAttribute("count", QString::number(m_stringCount));
writer.writeAttribute("uniqueCount", QString::number(m_stringTable.size()));
foreach (QString string, m_stringList) {
writer.writeStartElement("si");
if (string.contains(QRegularExpression("^<r>")) || string.contains(QRegularExpression("</r>$"))) {
//Rich text string,
// writer.writeCharacters(string);
} else {
writer.writeStartElement("t");
if (string.contains(QRegularExpression("^\\s")) || string.contains(QRegularExpression("\\s$")))
writer.writeAttribute("xml:space", "preserve");
writer.writeCharacters(string);
writer.writeEndElement();//t
}
writer.writeEndElement();//si
}
writer.writeEndElement(); //sst
writer.writeEndDocument();
}
} //namespace

58
src/xlsxsharedstrings_p.h

@ -0,0 +1,58 @@
/****************************************************************************
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
** All right reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#ifndef XLSXSHAREDSTRINGS_H
#define XLSXSHAREDSTRINGS_H
#include <QObject>
#include <QHash>
#include <QStringList>
class QIODevice;
namespace QXlsx {
class SharedStrings : public QObject
{
Q_OBJECT
public:
explicit SharedStrings(QObject *parent = 0);
int count() const;
public slots:
int addSharedString(const QString &string);
int getSharedStringIndex(const QString &string) const;
QString getSharedString(int index) const;
QStringList getSharedStrings() const;
void saveToXmlFile(QIODevice *device) const;
private:
QHash<QString, int> m_stringTable; //for fast lookup
QStringList m_stringList;
int m_stringCount;
};
}
#endif // XLSXSHAREDSTRINGS_H

240
src/xlsxstyles.cpp

@ -0,0 +1,240 @@
/****************************************************************************
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
** All right reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#include "xlsxstyles_p.h"
#include "xlsxformat.h"
#include "xmlstreamwriter_p.h"
#include <QFile>
namespace QXlsx {
Styles::Styles(QObject *parent) :
QObject(parent)
{
m_fill_count = 2; //Starts from 2
m_borders_count = 1;
m_font_count = 1;
//Add the default cell format
Format *format = addFormat();
format->setHasFont(true);
format->setHasBorder(true);
}
Format *Styles::addFormat()
{
Format *format = new Format(this);
m_formats.append(format);
return format;
}
void Styles::saveToXmlFile(QIODevice *device)
{
//Todo
m_xf_formats = m_formats;
XmlStreamWriter writer(device);
writer.writeStartDocument("1.0", true);
writer.writeStartElement("styleSheet");
writer.writeAttribute("xmlns", "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
// writer.writeStartElement("numFmts");
// writer.writeEndElement();//numFmts
writeFonts(writer);
writeFills(writer);
writeBorders(writer);
writer.writeStartElement("cellStyleXfs");
writer.writeAttribute("count", "1");
writer.writeStartElement("xf");
writer.writeAttribute("numFmtId", "0");
writer.writeAttribute("fontId", "0");
writer.writeAttribute("fillId", "0");
writer.writeAttribute("borderId", "0");
writer.writeEndElement();//xf
writer.writeEndElement();//cellStyleXfs
writeCellXfs(writer);
writer.writeStartElement("cellStyles");
writer.writeAttribute("count", "1");
writer.writeStartElement("cellStyle");
writer.writeAttribute("name", "Normal");
writer.writeAttribute("xfId", "0");
writer.writeAttribute("builtinId", "0");
writer.writeEndElement();//cellStyle
writer.writeEndElement();//cellStyles
writeDxfs(writer);
writer.writeStartElement("tableStyles");
writer.writeAttribute("count", "0");
writer.writeAttribute("defaultTableStyle", "TableStyleMedium9");
writer.writeAttribute("defaultPivotStyle", "PivotStyleLight16");
writer.writeEndElement();//tableStyles
writer.writeEndElement();//styleSheet
writer.writeEndDocument();
}
void Styles::writeFonts(XmlStreamWriter &writer)
{
writer.writeStartElement("fonts");
writer.writeAttribute("count", QString::number(m_font_count));
foreach (Format *format, m_xf_formats) {
if (format->hasFont()) {
writer.writeStartElement("font");
if (format->bold())
writer.writeEmptyElement("b");
if (format->italic())
writer.writeEmptyElement("i");
if (format->fontStrikout())
writer.writeEmptyElement("strike");
if (format->fontOutline())
writer.writeEmptyElement("outline");
if (format->fontShadow())
writer.writeEmptyElement("shadow");
if (format->fontUnderline()) //More option
writer.writeEmptyElement("u");
if (!format->isDxfFormat()) {
writer.writeEmptyElement("sz");
writer.writeAttribute("val", QString::number(format->fontSize()));
}
//font color
if (format->theme()) {
writer.writeEmptyElement("color");
writer.writeAttribute("theme", QString::number(format->theme()));
} else if (format->colorIndexed()) {
writer.writeEmptyElement("color");
writer.writeAttribute("indexed", QString::number(format->colorIndexed()));
} else if (format->fontColor().isValid()) {
writer.writeEmptyElement("color");
QString color = format->fontColor().name();
writer.writeAttribute("rgb", "FF"+color.mid(1));//remove #
} else if (!format->isDxfFormat()) {
writer.writeEmptyElement("color");
writer.writeAttribute("theme", "1");
}
if (!format->isDxfFormat()) {
writer.writeEmptyElement("name");
writer.writeAttribute("val", format->fontName());
writer.writeEmptyElement("family");
writer.writeAttribute("val", QString::number(format->fontFamily()));
if (format->fontName() == "Calibri") {
writer.writeEmptyElement("scheme");
writer.writeAttribute("val", format->fontScheme());
}
}
writer.writeEndElement(); //font
}
}
writer.writeEndElement();//fonts
}
void Styles::writeFills(XmlStreamWriter &writer)
{
writer.writeStartElement("fills");
writer.writeAttribute("count", QString::number(m_fill_count));
writer.writeStartElement("fill");
writer.writeEmptyElement("patternFill");
writer.writeAttribute("patternType", "none");
writer.writeEndElement();//fill
writer.writeStartElement("fill");
writer.writeEmptyElement("patternFill");
writer.writeAttribute("patternType", "gray125");
writer.writeEndElement();//fill
foreach (Format *format, m_xf_formats) {
if (format->hasFill()) {
//:TODO
}
}
writer.writeEndElement(); //fills
}
void Styles::writeBorders(XmlStreamWriter &writer)
{
writer.writeStartElement("borders");
writer.writeAttribute("count", QString::number(m_borders_count));
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->isDxfFormat()) {
writer.writeEmptyElement("diagonal");
}
writer.writeEndElement();//border
}
}
writer.writeEndElement();//borders
}
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 font_id = format->fontIndex();
int fill_id = format->fillIndex();
int border_id = format->borderIndex();
int xf_id = 0;
writer.writeStartElement("xf");
writer.writeAttribute("numFmtId", QString::number(num_fmt_id));
writer.writeAttribute("fontId", QString::number(font_id));
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)
writer.writeAttribute("applyNumberFormat", "1");
if (format->fontIndex() > 0)
writer.writeAttribute("applyFont", "1");
if (format->fillIndex() > 0)
writer.writeAttribute("applyBorder", "1");
writer.writeEndElement();//xf
}
writer.writeEndElement();//cellXfs
}
void Styles::writeDxfs(XmlStreamWriter &writer)
{
writer.writeStartElement("dxfs");
writer.writeAttribute("count", QString::number(m_dxf_formats.size()));
foreach (Format *format, m_dxf_formats) {
writer.writeStartElement("dxf");
writer.writeEndElement();//dxf
}
writer.writeEndElement(); //dxfs
}
} //namespace QXlsx

63
src/xlsxstyles_p.h

@ -0,0 +1,63 @@
/****************************************************************************
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
** All right reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#ifndef XLSXSTYLES_H
#define XLSXSTYLES_H
#include <QObject>
class QIODevice;
namespace QXlsx {
class Format;
class XmlStreamWriter;
class Styles : public QObject
{
public:
explicit Styles(QObject *parent=0);
Format *addFormat();
void saveToXmlFile(QIODevice *device);
private:
void writeFonts(XmlStreamWriter &writer);
void writeFills(XmlStreamWriter &writer);
void writeBorders(XmlStreamWriter &writer);
void writeCellXfs(XmlStreamWriter &writer);
void writeDxfs(XmlStreamWriter &writer);
QList<Format *> m_formats;
QList<Format *> m_xf_formats;
QList<Format *> m_dxf_formats;
int m_font_count;
int m_fill_count;
int m_borders_count;
};
}
#endif // XLSXSTYLES_H

43
src/xlsxtheme.cpp

File diff suppressed because one or more lines are too long

42
src/xlsxtheme_p.h

@ -0,0 +1,42 @@
/****************************************************************************
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
** All right reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#ifndef XLSXTHEME_H
#define XLSXTHEME_H
#include <QString>
class QIODevice;
namespace QXlsx {
class Theme
{
public:
Theme();
void saveToXmlFile(QIODevice *device);
};
}
#endif // XLSXTHEME_H

111
src/xlsxutility.cpp

@ -0,0 +1,111 @@
/****************************************************************************
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
** All right reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#include "xlsxutility_p.h"
#include <QString>
#include <QPoint>
#include <QRegularExpression>
#include <QMap>
namespace QXlsx {
int intPow(int x, int p)
{
if (p == 0) return 1;
if (p == 1) return x;
int tmp = intPow(x, p/2);
if (p%2 == 0) return tmp * tmp;
else return x * tmp * tmp;
}
QPoint xl_cell_to_rowcol(const QString &cell_str)
{
if (cell_str.isEmpty())
return QPoint(0, 0);
QRegularExpression re("^([A-Z]{1,3})(\\d+)$");
QRegularExpressionMatch match = re.match(cell_str);
if (match.hasMatch()) {
QString col_str = match.captured(1);
QString row_str = match.captured(2);
int col = 0;
int expn = 0;
for (int i=col_str.size()-1; i>-1; --i) {
col += (col_str[i].unicode() - 'A' + 1) * intPow(26, expn);
expn++;
}
col--;
int row = row_str.toInt() - 1;
return QPoint(row, col);
} else {
return QPoint(-1, -1); //...
}
}
QString xl_col_to_name(int col_num)
{
col_num += 1; //Change to 1-index
QString col_str;
int remainder;
while (col_num) {
remainder = col_num % 26;
if (remainder == 0)
remainder = 26;
col_str.prepend(QChar('A'+remainder-1));
col_num = (col_num - 1) / 26;
}
return col_str;
}
QString xl_rowcol_to_cell(int row, int col, bool row_abs, bool col_abs)
{
row += 1; //Change to 1-index
QString cell_str;
if (col_abs)
cell_str.append("$");
cell_str.append(xl_col_to_name(col));
if (row_abs)
cell_str.append("$");
cell_str.append(QString::number(row));
return cell_str;
}
QString xl_rowcol_to_cell_fast(int row, int col)
{
static QMap<int, QString> col_cache;
QString col_str;
if (col_cache.contains(col)) {
col_str = col_cache[col];
} else {
col_str = xl_col_to_name(col);
col_cache[col] = col_str;
}
return col_str + QString::number(row+1);
}
} //namespace QXlsx

39
src/xlsxutility_p.h

@ -0,0 +1,39 @@
/****************************************************************************
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
** All right reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#ifndef XLSXUTILITY_H
#define XLSXUTILITY_H
class QPoint;
class QString;
namespace QXlsx {
int intPow(int x, int p);
QPoint xl_cell_to_rowcol(const QString &cell_str);
QString xl_col_to_name(int col_num);
QString xl_rowcol_to_cell(int row, int col, bool row_abs=false, bool col_abs=false);
QString xl_rowcol_to_cell_fast(int row, int col);
} //QXlsx
#endif // XLSXUTILITY_H

234
src/xlsxworkbook.cpp

@ -0,0 +1,234 @@
/****************************************************************************
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
** All right reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#include "xlsxworkbook.h"
#include "xlsxsharedstrings_p.h"
#include "xlsxworksheet.h"
#include "xlsxstyles_p.h"
#include "xlsxformat.h"
#include "xlsxpackage_p.h"
#include "xmlstreamwriter_p.h"
namespace QXlsx {
Workbook::Workbook(const QString &name, QObject *parent) :
QObject(parent), m_fileName(name)
{
m_sharedStrings = new SharedStrings(this);
m_styles = new Styles(this);
m_x_window = 240;
m_y_window = 15;
m_window_width = 16095;
m_window_height = 9660;
m_optimization_enabled = false;
m_strings_to_numbers_enabled = false;
m_activesheet = 0;
m_firstsheet = 0;
m_table_count = 0;
m_closed = false;
}
Workbook::~Workbook()
{
close();
}
void Workbook::close()
{
if (m_closed)
return;
m_closed = true;
saveWorkbook();
}
void Workbook::saveWorkbook()
{
//Add a default worksheet if non have been added.
if (m_worksheets.size() == 0)
addWorksheet();
//Ensure that at least one worksheet has been selected.
if (m_activesheet == 0) {
m_worksheets[0]->setHidden(false);
m_worksheets[0]->setSelected(true);
}
//Set the active sheet
foreach (Worksheet *sheet, m_worksheets) {
if (sheet->index() == m_activesheet)
sheet->setActived(true);
}
//Create the package based on current workbook
Package package(this);
package.createPackage();
}
QString Workbook::fileName() const
{
return m_fileName;
}
/*!
Reduces the amount of data stored in memory so
that large files can be written efficiently
Note, in this mode a row of data is written and
then discarded when a cell in a new row is added
via one of the worksheet write_() methods. As such
data should be written in sequential row order once
this mode is on.
It is used to optimise speed and reduce memory usage.
However, these design goals meant that it wasnt easy
to implement features that many users requested such as
writing formatting and data separately.
This feature is disabled by default.
*/
void Workbook::setOptimizationEnabled(bool enable)
{
m_optimization_enabled = enable;
}
bool Workbook::isOptimizationEnabled() const
{
return m_optimization_enabled;
}
/*
Enable the worksheet.write() method to convert strings
to numbers, where possible, using float() in order to avoid
an Excel warning about Numbers Stored as Text.
The default is false
*/
void Workbook::setStringsToNumbersEnabled(bool enable)
{
m_strings_to_numbers_enabled = enable;
}
bool Workbook::isStringsToNumbersEnabled() const
{
return m_strings_to_numbers_enabled;
}
void Workbook::defineName(const QString &name, const QString &formula)
{
}
Worksheet *Workbook::addWorksheet(const QString &name)
{
QString worksheetName = name;
int index = m_worksheets.size()+1;
if (name.isEmpty())
worksheetName = QString("Sheet%1").arg(index);
Worksheet *sheet = new Worksheet(worksheetName, index, this);
m_worksheets.append(sheet);
return sheet;
}
Format *Workbook::addFormat()
{
return m_styles->addFormat();
}
QList<Worksheet *> Workbook::worksheets() const
{
return m_worksheets;
}
SharedStrings *Workbook::sharedStrings()
{
return m_sharedStrings;
}
Styles *Workbook::styles()
{
return m_styles;
}
void Workbook::saveToXmlFile(QIODevice *device)
{
XmlStreamWriter writer(device);
writer.writeStartDocument("1.0", true);
writer.writeStartElement("workbook");
writer.writeAttribute("xmlns", "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
writer.writeAttribute("xmlns:r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
writer.writeEmptyElement("fileVersion");
writer.writeAttribute("appName", "xl");
writer.writeAttribute("lastEdited", "4");
writer.writeAttribute("lowestEdited", "4");
writer.writeAttribute("rupBuild", "4505");
// writer.writeAttribute("codeName", "{37E998C4-C9E5-D4B9-71C8-EB1FF731991C}");
writer.writeEmptyElement("workbookPr");
writer.writeAttribute("defaultThemeVersion", "124226");
writer.writeStartElement("bookViews");
writer.writeEmptyElement("workbookView");
writer.writeAttribute("xWindow", QString::number(m_x_window));
writer.writeAttribute("yWindow", QString::number(m_y_window));
writer.writeAttribute("windowWidth", QString::number(m_window_width));
writer.writeAttribute("windowHeight", QString::number(m_window_height));
//Store the firstSheet when it isn't the default
if (m_firstsheet > 0)
writer.writeAttribute("firstSheet", QString::number(m_firstsheet + 1));
//Store the activeTab when it isn't the first sheet
if (m_activesheet > 0)
writer.writeAttribute("activeTab", QString::number(m_activesheet));
writer.writeEndElement();//bookviews
writer.writeStartElement("sheets");
foreach (Worksheet *sheet, m_worksheets) {
writer.writeEmptyElement("sheet");
writer.writeAttribute("name", sheet->name());
writer.writeAttribute("sheetId", QString::number(sheet->index()));
if (sheet->isHidden())
writer.writeAttribute("state", "hidden");
writer.writeAttribute("r:id", QString("rId%1").arg(sheet->index()));
}
writer.writeEndElement();//sheets
// writer.writeStartElement("definedNames");
// writer.writeEndElement();//definedNames
writer.writeStartElement("calcPr");
writer.writeAttribute("calcId", "124519");
writer.writeEndElement(); //calcPr
writer.writeEndElement();//workbook
writer.writeEndDocument();
}
} //namespace

90
src/xlsxworkbook.h

@ -0,0 +1,90 @@
/****************************************************************************
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
** All right reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#ifndef XLSXWORKBOOK_H
#define XLSXWORKBOOK_H
#include <QObject>
#include <QList>
class QIODevice;
namespace QXlsx {
class Worksheet;
class Format;
class SharedStrings;
class Styles;
class Package;
class Workbook : public QObject
{
Q_OBJECT
public:
Workbook(const QString &name, QObject *parent=0);
~Workbook();
Worksheet *addWorksheet(const QString &name = QString());
Format *addFormat();
// void addChart();
void defineName(const QString &name, const QString &formula);
void setOptimizationEnabled(bool enable=true);
void setStringsToNumbersEnabled(bool enable=true);
void close();
private:
friend class Package;
friend class Worksheet;
QList<Worksheet *> worksheets() const;
SharedStrings *sharedStrings();
Styles *styles();
QString fileName() const;
bool isOptimizationEnabled() const;
bool isStringsToNumbersEnabled() const;
void saveToXmlFile(QIODevice *device);
void saveWorkbook();
QString m_fileName;
bool m_closed;
SharedStrings *m_sharedStrings;
QList<Worksheet *> m_worksheets;
Styles *m_styles;
bool m_optimization_enabled; //constant_memory
bool m_strings_to_numbers_enabled;
int m_x_window;
int m_y_window;
int m_window_width;
int m_window_height;
int m_activesheet;
int m_firstsheet;
int m_table_count;
};
} //QXlsx
#endif // XLSXWORKBOOK_H

479
src/xlsxworksheet.cpp

@ -0,0 +1,479 @@
/****************************************************************************
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
** All right reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#include "xlsxworksheet.h"
#include "xlsxworkbook.h"
#include "xlsxutility_p.h"
#include "xlsxsharedstrings_p.h"
#include "xmlstreamwriter_p.h"
#include <QVariant>
#include <QDateTime>
#include <QPoint>
#include <QFile>
#include <stdint.h>
namespace QXlsx {
/*!
* \brief Worksheet::Worksheet
* \param name Name of the worksheet
* \param index Index of the worksheet in the workbook
* \param parent
*/
Worksheet::Worksheet(const QString &name, int index, Workbook *parent) :
QObject(parent), m_workbook(parent), m_name(name), m_index(index)
{
m_xls_rowmax = 1048576;
m_xls_colmax = 16384;
m_xls_strmax = 32767;
m_dim_rowmin = INT32_MAX;
m_dim_rowmax = INT32_MIN;
m_dim_colmin = INT32_MAX;
m_dim_colmax = INT32_MIN;
m_previous_row = 0;
m_outline_row_level = 0;
m_outline_col_level = 0;
m_default_row_height = 15;
m_default_row_zeroed = false;
m_hidden = false;
m_selected = false;
m_actived = false;
m_right_to_left = false;
m_show_zeros = true;
}
bool Worksheet::isChartsheet() const
{
return false;
}
QString Worksheet::name() const
{
return m_name;
}
int Worksheet::index() const
{
return m_index;
}
bool Worksheet::isHidden() const
{
return m_hidden;
}
bool Worksheet::isSelected() const
{
return m_selected;
}
bool Worksheet::isActived() const
{
return m_actived;
}
void Worksheet::setHidden(bool hidden)
{
m_hidden = hidden;
}
void Worksheet::setSelected(bool select)
{
m_selected = select;
}
void Worksheet::setActived(bool act)
{
m_actived = act;
}
void Worksheet::setRightToLeft(bool enable)
{
m_right_to_left = enable;
}
void Worksheet::setZeroValuesHidden(bool enable)
{
m_show_zeros = !enable;
}
int Worksheet::write(int row, int column, const QVariant &value)
{
bool ok;
int ret = 0;
if (value.isNull()) { //blank
ret = writeBlank(row, column);
} else if (value.type() == QMetaType::Bool) { //Bool
ret = writeBool(row,column, value.toBool());
} 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());
} else {
ret = writeNumber(row, column, value.toDouble());
}
} 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);
} else if (token.startsWith("{") && token.endsWith("}")) {
} else {
ret = writeString(row, column, token);
}
} else { //Wrong type
return -1;
}
return ret;
}
//convert the "A1" notation to row/column notation
int Worksheet::write(const QString row_column, const QVariant &value)
{
QPoint pos = xl_cell_to_rowcol(row_column);
if (pos == QPoint(-1, -1)) {
return -1;
}
return write(pos.x(), pos.y(), value);
}
int Worksheet::writeString(int row, int column, const QString &value)
{
int error = 0;
QString content = value;
if (checkDimensions(row, column))
return -1;
if (value.size() > m_xls_strmax) {
content = value.left(m_xls_strmax);
error = -2;
}
SharedStrings *sharedStrings = m_workbook->sharedStrings();
int index = sharedStrings->addSharedString(content);
m_table[row][column] = XlsxCellData(index, XlsxCellData::String);
return error;
}
int Worksheet::writeNumber(int row, int column, double value)
{
if (checkDimensions(row, column))
return -1;
m_table[row][column] = XlsxCellData(value, XlsxCellData::Number);
return 0;
}
int Worksheet::writeFormula(int row, int column, const QString &content, double result)
{
int error = 0;
QString formula = content;
if (checkDimensions(row, column))
return -1;
//Remove the formula '=' sign if exists
if (formula.startsWith("="))
formula.remove(0,1);
XlsxCellData data(result, XlsxCellData::Formula);
data.formula = formula;
m_table[row][column] = data;
return error;
}
int Worksheet::writeBlank(int row, int column)
{
if (checkDimensions(row, column))
return -1;
m_table[row][column] = XlsxCellData(QVariant(), XlsxCellData::Blank);
return 0;
}
int Worksheet::writeBool(int row, int column, bool value)
{
if (checkDimensions(row, column))
return -1;
m_table[row][column] = XlsxCellData(value, XlsxCellData::Boolean);
return 0;
}
/*
Check that row and col are valid and store the max and min
values for use in other methods/elements. The ignore_row /
ignore_col flags is used to indicate that we wish to perform
the dimension check without storing the value. The ignore
flags are use by setRow() and dataValidate.
*/
int Worksheet::checkDimensions(int row, int col, bool ignore_row, bool ignore_col)
{
if (row >= m_xls_rowmax || col >= m_xls_colmax)
return -1;
// // In optimization mode we don't change dimensions for rows
// // that are already written.
// if (!ignore_row && !ignore_col && m_optimization == 1) {
// if (row < m_previous_row)
// return -1;
// }
if (!ignore_row) {
if (row < m_dim_rowmin) m_dim_rowmin = row;
if (row > m_dim_rowmax) m_dim_rowmax = row;
}
if (!ignore_col) {
if (col < m_dim_colmin) m_dim_colmin = col;
if (col > m_dim_colmax) m_dim_colmax = col;
}
return 0;
}
void Worksheet::saveToXmlFile(QIODevice *device)
{
XmlStreamWriter writer(device);
writer.writeStartDocument("1.0", true);
writer.writeStartElement("worksheet");
writer.writeAttribute("xmlns", "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
writer.writeAttribute("xmlns:r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
//for Excel 2010
// writer.writeAttribute("xmlns:mc", "http://schemas.openxmlformats.org/markup-compatibility/2006");
// writer.writeAttribute("xmlns:x14ac", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac");
// writer.writeAttribute("mc:Ignorable", "x14ac");
writer.writeStartElement("dimension");
writer.writeAttribute("ref", generateDimensionString());
writer.writeEndElement();//dimension
writer.writeStartElement("sheetViews");
writer.writeStartElement("sheetView");
if (!m_show_zeros)
writer.writeAttribute("showZeros", "0");
if (m_right_to_left)
writer.writeAttribute("rightToLeft", "1");
if (m_selected)
writer.writeAttribute("tabSelected", "1");
writer.writeAttribute("workbookViewId", "0");
writer.writeEndElement();//sheetView
writer.writeEndElement();//sheetViews
writer.writeStartElement("sheetFormatPr");
writer.writeAttribute("defaultRowHeight", QString::number(m_default_row_height));
if (m_default_row_height != 15)
writer.writeAttribute("customHeight", "1");
if (m_default_row_zeroed)
writer.writeAttribute("zeroHeight", "1");
if (m_outline_row_level)
writer.writeAttribute("outlineLevelRow", QString::number(m_outline_row_level));
if (m_outline_col_level)
writer.writeAttribute("outlineLevelCol", QString::number(m_outline_col_level));
//for Excel 2010
// writer.writeAttribute("x14ac:dyDescent", "0.25");
writer.writeEndElement();//sheetFormatPr
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
} else {
writeSheetData(writer);
}
writer.writeEndElement();//sheetData
writer.writeEndElement();//worksheet
writer.writeEndDocument();
}
QString Worksheet::generateDimensionString()
{
if (m_dim_rowmax == INT32_MIN && m_dim_colmax == INT32_MIN) {
//If the max dimensions are equal to INT32_MIN, then no dimension have been set
//and we use the default "A1"
return "A1";
}
if (m_dim_rowmax == INT32_MIN) {
//row dimensions aren't set but the column dimensions are set
if (m_dim_colmin == m_dim_colmax) {
//The dimensions are a single cell and not a range
return xl_rowcol_to_cell(0, m_dim_colmin);
} else {
const QString cell_1 = xl_rowcol_to_cell(0, m_dim_colmin);
const QString cell_2 = xl_rowcol_to_cell(0, m_dim_colmax);
return cell_1 + ":" + cell_2;
}
}
if (m_dim_rowmin == m_dim_rowmax && m_dim_colmin == m_dim_colmax) {
//Single cell
return xl_rowcol_to_cell(m_dim_rowmin, m_dim_rowmin);
}
QString cell_1 = xl_rowcol_to_cell(m_dim_rowmin, m_dim_colmin);
QString cell_2 = xl_rowcol_to_cell(m_dim_rowmax, m_dim_colmax);
return cell_1 + ":" + cell_2;
}
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))) {
//Only process rows with cell data / comments / formatting
continue;
}
int span_index = row_num / 16;
QString span;
if (m_row_spans.contains(span_index))
span = m_row_spans[span_index];
if (m_table.contains(row_num)) {
writer.writeStartElement("row");
writer.writeAttribute("r", QString::number(row_num + 1));
if (!span.isEmpty())
writer.writeAttribute("spans", span);
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]);
}
}
writer.writeEndElement(); //row
} else if (m_comments.contains(row_num)){
} else {
}
}
}
void Worksheet::writeCellData(XmlStreamWriter &writer, int row, int col, const XlsxCellData &data)
{
//This is the innermost loop so efficiency is important.
QString cell_range = xl_rowcol_to_cell_fast(row, col);
writer.writeStartElement("c");
writer.writeAttribute("r", cell_range);
//Style used by the cell, row /col
// writer.writeAttribute("s", QString::number(""));
if (data.dataType == XlsxCellData::String) {
//data.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) {
bool ok = true;
data.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) {
} else if (data.dataType == XlsxCellData::Boolean) {
writer.writeAttribute("t", "b");
writer.writeTextElement("v", data.value.toBool() ? "True" : "False");
} else if (data.dataType == XlsxCellData::Blank) {
//Ok, empty here.
}
writer.writeEndElement(); //c
}
/*
Calculate the "spans" attribute of the <row> tag. This is an
XLSX optimisation and isn't strictly required. However, it
makes comparing files easier. The span is the same for each
block of 16 rows.
*/
void Worksheet::calculateSpans()
{
m_row_spans.clear();
int span_min = INT32_MAX;
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)) {
for (int col_num = m_dim_colmin; col_num <= m_dim_colmax; col_num++) {
if (m_table[row_num].contains(col_num)) {
if (span_max == INT32_MIN) {
span_min = col_num;
span_max = col_num;
} else {
if (col_num < span_min)
span_min = col_num;
if (col_num > span_max)
span_max = col_num;
}
}
}
}
if (m_comments.contains(row_num)) {
for (int col_num = m_dim_colmin; col_num <= m_dim_colmax; col_num++) {
if (m_comments[row_num].contains(col_num)) {
if (span_max == INT32_MIN) {
span_min = col_num;
span_max = col_num;
} else {
if (col_num < span_min)
span_min = col_num;
if (col_num > span_max)
span_max = col_num;
}
}
}
}
if ((row_num + 1)%16 == 0 || row_num == m_dim_rowmax) {
int span_index = row_num / 16;
if (span_max != INT32_MIN) {
span_min += 1;
span_max += 1;
m_row_spans[span_index] = QString("%1:%2").arg(span_min).arg(span_max);
span_max = INT32_MIN;
}
}
}
}
} //namespace

131
src/xlsxworksheet.h

@ -0,0 +1,131 @@
/****************************************************************************
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
** All right reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#ifndef XLSXWORKSHEET_H
#define XLSXWORKSHEET_H
#include <QObject>
#include <QStringList>
#include <QMap>
#include <QVariant>
class QIODevice;
namespace QXlsx {
class Package;
class Workbook;
class XmlStreamWriter;
class Format;
struct XlsxCellData
{
enum CellDataType {
Blank,
String,
Number,
Formula,
ArrayFormula,
Boolean
};
XlsxCellData(const QVariant &data=QVariant(), CellDataType type=Blank) :
value(data), dataType(type), format(0)
{
}
QVariant value;
QString formula;
CellDataType dataType;
Format *format;
};
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);
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);
virtual bool isChartsheet() const;
QString name() const;
int index() const;
bool isHidden() const;
bool isSelected() const;
bool isActived() const;
void setHidden(bool hidden);
void setSelected(bool select);
void setActived(bool act);
void saveToXmlFile(QIODevice *device);
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 calculateSpans();
Workbook *m_workbook;
QMap<int, QMap<int, XlsxCellData> > m_table;
QMap<int, QMap<int, QString> > m_comments;
int m_xls_rowmax;
int m_xls_colmax;
int m_xls_strmax;
int m_dim_rowmin;
int m_dim_rowmax;
int m_dim_colmin;
int m_dim_colmax;
int m_previous_row;
QMap<int, QString> m_row_spans;
int m_outline_row_level;
int m_outline_col_level;
int m_default_row_height;
bool m_default_row_zeroed;
QString m_name;
int m_index;
bool m_hidden;
bool m_selected;
bool m_actived;
bool m_right_to_left;
bool m_show_zeros;
};
} //QXlsx
Q_DECLARE_TYPEINFO(QXlsx::XlsxCellData, Q_MOVABLE_TYPE);
#endif // XLSXWORKSHEET_H

36
src/xmlstreamwriter.cpp

@ -0,0 +1,36 @@
/****************************************************************************
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
** All right reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#include "xmlstreamwriter_p.h"
#include <QIODevice>
namespace QXlsx {
XmlStreamWriter::XmlStreamWriter(QIODevice *device) :
QXmlStreamWriter(device)
{
}
}

41
src/xmlstreamwriter_p.h

@ -0,0 +1,41 @@
/****************************************************************************
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
** All right reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#ifndef XMLSTEAMWRITER_H
#define XMLSTEAMWRITER_H
#include <QXmlStreamWriter>
class QIODevice;
namespace QXlsx {
class XmlStreamWriter : public QXmlStreamWriter
{
public:
explicit XmlStreamWriter(QIODevice *device);
};
}
#endif // XMLSTEAMWRITER_H

59
src/zipwriter.cpp

@ -0,0 +1,59 @@
/****************************************************************************
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
** All right reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#include "zipwriter_p.h"
#include <QDebug>
#include <private/qzipwriter_p.h>
namespace QXlsx {
ZipWriter::ZipWriter(const QString &filePath, QObject *parent) :
QObject(parent)
{
m_writer = new QZipWriter(filePath, QIODevice::WriteOnly);
m_writer->setCompressionPolicy(QZipWriter::NeverCompress);
}
ZipWriter::~ZipWriter()
{
delete m_writer;
}
void ZipWriter::addFile(const QString &filePath, QIODevice *device)
{
m_writer->addFile(filePath, device);
}
void ZipWriter::addFile(const QString &filePath, const QByteArray &data)
{
qDebug()<<filePath<<data.size();
m_writer->addFile(filePath, data);
}
void ZipWriter::close()
{
m_writer->close();
}
} // namespace QXlsx

51
src/zipwriter_p.h

@ -0,0 +1,51 @@
/****************************************************************************
** Copyright (c) 2013 Debao Zhang <hello@debao.me>
** All right reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#ifndef QXLSX_ZIPWRITER_H
#define QXLSX_ZIPWRITER_H
#include <QObject>
class QIODevice;
class QZipWriter;
namespace QXlsx {
class ZipWriter : public QObject
{
Q_OBJECT
public:
explicit ZipWriter(const QString &filePath, QObject *parent = 0);
~ZipWriter();
void addFile(const QString &filePath, QIODevice *device);
void addFile(const QString &filePath, const QByteArray &data);
void close();
private:
QZipWriter *m_writer;
};
} // namespace QXlsx
#endif // QXLSX_ZIPWRITER_H
Loading…
Cancel
Save