Browse Source

Try add very basic barChart support.

master
Debao Zhang 11 years ago
parent
commit
727b8b609f
  1. 11
      examples/xlsx/chart/main.cpp
  2. 7
      src/xlsx/qtxlsx.pri
  3. 137
      src/xlsx/xlsxabstractchart.cpp
  4. 10
      src/xlsx/xlsxabstractchart.h
  5. 35
      src/xlsx/xlsxabstractchart_p.h
  6. 37
      src/xlsx/xlsxchartfile.cpp
  7. 25
      src/xlsx/xlsxpiechart.cpp
  8. 4
      src/xlsx/xlsxpiechart.h
  9. 2
      src/xlsx/xlsxpiechart_p.h

11
examples/xlsx/chart/main.cpp

@ -1,6 +1,7 @@
#include <QtCore> #include <QtCore>
#include "xlsxdocument.h" #include "xlsxdocument.h"
#include "xlsxpiechart.h" #include "xlsxpiechart.h"
#include "xlsxbarchart.h"
#include "xlsxworksheet.h" #include "xlsxworksheet.h"
using namespace QXlsx; using namespace QXlsx;
@ -16,9 +17,13 @@ int main()
//![0] //![0]
//![1] //![1]
PieChart *chart = new PieChart; PieChart *pieChart = new PieChart;
chart->addSeries(CellRange("A1:A9"), sheet->sheetName()); pieChart->addSeries(CellRange("A1:A9"), sheet->sheetName());
sheet->insertChart(3, 3, chart, QSize(300, 300)); sheet->insertChart(3, 3, pieChart, QSize(300, 300));
BarChart *barChart = new BarChart;
barChart->addSeries(CellRange("A1:A9"), sheet->sheetName());
sheet->insertChart(6, 6, barChart, QSize(300, 300));
//![1] //![1]
//![2] //![2]

7
src/xlsx/qtxlsx.pri

@ -43,7 +43,9 @@ HEADERS += $$PWD/xlsxdocpropscore_p.h \
$$PWD/xlsxabstractchart.h \ $$PWD/xlsxabstractchart.h \
$$PWD/xlsxabstractchart_p.h \ $$PWD/xlsxabstractchart_p.h \
$$PWD/xlsxpiechart.h \ $$PWD/xlsxpiechart.h \
$$PWD/xlsxpiechart_p.h $$PWD/xlsxpiechart_p.h \
$$PWD/xlsxbarchart.h \
$$PWD/xlsxbarchart_p.h
SOURCES += $$PWD/xlsxdocpropscore.cpp \ SOURCES += $$PWD/xlsxdocpropscore.cpp \
$$PWD/xlsxdocpropsapp.cpp \ $$PWD/xlsxdocpropsapp.cpp \
@ -72,4 +74,5 @@ SOURCES += $$PWD/xlsxdocpropscore.cpp \
$$PWD/xlsxooxmlfile.cpp \ $$PWD/xlsxooxmlfile.cpp \
$$PWD/xlsxchartfile.cpp \ $$PWD/xlsxchartfile.cpp \
$$PWD/xlsxabstractchart.cpp \ $$PWD/xlsxabstractchart.cpp \
$$PWD/xlsxpiechart.cpp $$PWD/xlsxpiechart.cpp \
$$PWD/xlsxbarchart.cpp

137
src/xlsx/xlsxabstractchart.cpp

@ -28,6 +28,8 @@
#include "xlsxchartfile_p.h" #include "xlsxchartfile_p.h"
#include "xlsxcellrange.h" #include "xlsxcellrange.h"
#include "xlsxutility_p.h" #include "xlsxutility_p.h"
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
QT_BEGIN_NAMESPACE_XLSX QT_BEGIN_NAMESPACE_XLSX
@ -42,6 +44,27 @@ AbstractChartPrivate::~AbstractChartPrivate()
} }
bool AbstractChartPrivate::loadXmlSer(QXmlStreamReader &reader)
{
Q_ASSERT(reader.name() == QLatin1String("ser"));
while (!reader.atEnd()) {
reader.readNextStartElement();
if (reader.tokenType() == QXmlStreamReader::StartElement) {
if (reader.name() == QLatin1String("f")) {
XlsxSeries *series = new XlsxSeries;
series->numRef = reader.readElementText();
seriesList.append(QSharedPointer<XlsxSeries>(series));
}
} else if (reader.tokenType() == QXmlStreamReader::EndElement
&& reader.name() == QLatin1String("ser")) {
break;
}
}
return true;
}
/*! /*!
* \class AbstractChart * \class AbstractChart
* *
@ -83,4 +106,118 @@ void AbstractChart::addSeries(const CellRange &range, const QString &sheet)
d->seriesList.append(QSharedPointer<XlsxSeries>(series)); d->seriesList.append(QSharedPointer<XlsxSeries>(series));
} }
bool AbstractChart::loadAxisFromXml(QXmlStreamReader &reader)
{
Q_D(AbstractChart);
Q_ASSERT(reader.name().endsWith(QLatin1String("Ax")));
QString name = reader.name().toString();
XlsxAxis *axis = new XlsxAxis;
if (name == QLatin1String("valAx"))
axis->type = XlsxAxis::T_Val;
else if (name == QLatin1String("catAx"))
axis->type = XlsxAxis::T_Cat;
else if (name == QLatin1String("serAx"))
axis->type = XlsxAxis::T_Ser;
else
axis->type = XlsxAxis::T_Date;
d->axisList.append(QSharedPointer<XlsxAxis>(axis));
while (!reader.atEnd()) {
reader.readNextStartElement();
if (reader.tokenType() == QXmlStreamReader::StartElement) {
if (reader.name() == QLatin1String("axPos")) {
QXmlStreamAttributes attrs = reader.attributes();
QStringRef pos = attrs.value(QLatin1String("val"));
if (pos==QLatin1String("l"))
axis->axisPos = XlsxAxis::Left;
else if (pos==QLatin1String("r"))
axis->axisPos = XlsxAxis::Right;
else if (pos==QLatin1String("b"))
axis->axisPos = XlsxAxis::Bottom;
else
axis->axisPos = XlsxAxis::Top;
}
} else if (reader.tokenType() == QXmlStreamReader::EndElement
&& reader.name() == name) {
break;
}
}
return true;
}
void AbstractChart::saveAxisToXml(QXmlStreamWriter &writer) const
{
Q_D(const AbstractChart);
for (int i=0; i<d->axisList.size(); ++i) {
XlsxAxis *axis = d->axisList[i].data();
QString name;
switch (axis->type) {
case XlsxAxis::T_Cat:
name = QStringLiteral("c:catAx");
break;
case XlsxAxis::T_Val:
name = QStringLiteral("c:valAx");
break;
case XlsxAxis::T_Ser:
name = QStringLiteral("c:serAx");
break;
case XlsxAxis::T_Date:
name = QStringLiteral("c:dateAx");
break;
default:
break;
}
QString pos;
switch (axis->axisPos) {
case XlsxAxis::Top:
pos = QStringLiteral("t");
break;
case XlsxAxis::Bottom:
pos = QStringLiteral("b");
break;
case XlsxAxis::Left:
pos = QStringLiteral("l");
break;
case XlsxAxis::Right:
pos = QStringLiteral("r");
break;
default:
break;
}
writer.writeStartElement(name);
writer.writeEmptyElement(QStringLiteral("c:axId"));
writer.writeAttribute(QStringLiteral("val"), QString::number(i+1));
writer.writeStartElement(QStringLiteral("c:scaling"));
writer.writeEmptyElement(QStringLiteral("c:orientation"));
writer.writeAttribute(QStringLiteral("val"), QStringLiteral("minMax"));
writer.writeEndElement();//c:scaling
writer.writeEmptyElement(QStringLiteral("c:axPos"));
writer.writeAttribute(QStringLiteral("val"), pos);
writer.writeEmptyElement(QStringLiteral("c:crossAx"));
writer.writeAttribute(QStringLiteral("val"), QString::number(i%2==0 ? i+2 : i));
writer.writeEndElement();//name
}
}
bool AbstractChart::loadLegendFromXml(QXmlStreamReader &reader)
{
return false;
}
void AbstractChart::saveLegendToXml(QXmlStreamWriter &writer) const
{
}
QT_END_NAMESPACE_XLSX QT_END_NAMESPACE_XLSX

10
src/xlsx/xlsxabstractchart.h

@ -52,8 +52,14 @@ public:
protected: protected:
friend class ChartFile; friend class ChartFile;
AbstractChart(AbstractChartPrivate *d); AbstractChart(AbstractChartPrivate *d);
virtual bool loadFromXml(QXmlStreamReader &reader) = 0; virtual bool loadXxxChartFromXml(QXmlStreamReader &reader) = 0;
virtual void saveToXml(QXmlStreamWriter &writer) const = 0; virtual void saveXxxChartToXml(QXmlStreamWriter &writer) const = 0;
bool loadAxisFromXml(QXmlStreamReader &reader);
void saveAxisToXml(QXmlStreamWriter &writer) const;
bool loadLegendFromXml(QXmlStreamReader &reader);
void saveLegendToXml(QXmlStreamWriter &writer) const;
AbstractChartPrivate * d_ptr; AbstractChartPrivate * d_ptr;
}; };

35
src/xlsx/xlsxabstractchart_p.h

@ -50,6 +50,38 @@ public:
QString numRef; QString numRef;
}; };
class XlsxAxis
{
public:
enum Type
{
T_Cat,
T_Val,
T_Date,
T_Ser
};
enum Pos
{
Left,
Right,
Top,
Bottom
};
XlsxAxis(){}
XlsxAxis(Type t, Pos p)
:type(t), axisPos(p)
{
axisId = -1;
}
int axisId;
Type type;
Pos axisPos; //l,r,b,t
};
class AbstractChartPrivate class AbstractChartPrivate
{ {
Q_DECLARE_PUBLIC(AbstractChart) Q_DECLARE_PUBLIC(AbstractChart)
@ -57,7 +89,10 @@ public:
AbstractChartPrivate(AbstractChart *chart); AbstractChartPrivate(AbstractChart *chart);
virtual ~AbstractChartPrivate(); virtual ~AbstractChartPrivate();
bool loadXmlSer(QXmlStreamReader &reader);
QList<QSharedPointer<XlsxSeries> > seriesList; QList<QSharedPointer<XlsxSeries> > seriesList;
QList<QSharedPointer<XlsxAxis>> axisList;
ChartFile *cf; ChartFile *cf;
AbstractChart *q_ptr; AbstractChart *q_ptr;
}; };

37
src/xlsx/xlsxchartfile.cpp

@ -27,6 +27,7 @@
#include "xlsxabstractchart.h" #include "xlsxabstractchart.h"
#include "xlsxabstractchart_p.h" #include "xlsxabstractchart_p.h"
#include "xlsxpiechart.h" #include "xlsxpiechart.h"
#include "xlsxbarchart.h"
#include <QIODevice> #include <QIODevice>
#include <QXmlStreamReader> #include <QXmlStreamReader>
#include <QXmlStreamWriter> #include <QXmlStreamWriter>
@ -77,7 +78,8 @@ bool ChartFile::loadFromXmlFile(QIODevice *device)
reader.readNextStartElement(); reader.readNextStartElement();
if (reader.tokenType() == QXmlStreamReader::StartElement) { if (reader.tokenType() == QXmlStreamReader::StartElement) {
if (reader.name() == QLatin1String("chart")) { if (reader.name() == QLatin1String("chart")) {
loadXmlChart(reader); if (!loadXmlChart(reader))
return false;
} }
} }
} }
@ -92,7 +94,10 @@ bool ChartFile::loadXmlChart(QXmlStreamReader &reader)
reader.readNextStartElement(); reader.readNextStartElement();
if (reader.tokenType() == QXmlStreamReader::StartElement) { if (reader.tokenType() == QXmlStreamReader::StartElement) {
if (reader.name() == QLatin1String("plotArea")) { if (reader.name() == QLatin1String("plotArea")) {
loadXmlPlotArea(reader); if (!loadXmlPlotArea(reader))
return false;
} else if (reader.name() == QLatin1String("legend")) {
m_chart->loadLegendFromXml(reader);
} }
} else if (reader.tokenType() == QXmlStreamReader::EndElement && } else if (reader.tokenType() == QXmlStreamReader::EndElement &&
reader.name() == QLatin1String("chart")) { reader.name() == QLatin1String("chart")) {
@ -109,20 +114,28 @@ bool ChartFile::loadXmlPlotArea(QXmlStreamReader &reader)
while (!reader.atEnd()) { while (!reader.atEnd()) {
reader.readNextStartElement(); reader.readNextStartElement();
if (reader.tokenType() == QXmlStreamReader::StartElement) { if (reader.tokenType() == QXmlStreamReader::StartElement) {
AbstractChart *chart = 0;
if (reader.name() == QLatin1String("layout")) { if (reader.name() == QLatin1String("layout")) {
//... //...
} else if (reader.name() == QLatin1String("pieChart")) { } else if (reader.name().endsWith(QLatin1String("Chart"))) {
//!Todo: each plotArea can have more than one xxxChart
AbstractChart *chart = 0;
if (reader.name() == QLatin1String("pieChart")) {
chart = new PieChart; chart = new PieChart;
chart->loadFromXml(reader); } else if (reader.name() == QLatin1String("barChart")) {
} else if (reader.name() == QLatin1String("")) { chart = new BarChart;
} else {
//Not support
return false;
} }
if (chart) { if (chart) {
chart->loadFromXml(reader); chart->loadXxxChartFromXml(reader);
setChart(chart); setChart(chart);
} }
} else if (reader.name().endsWith(QLatin1String("Ax"))) {
//For valAx, catAx, serAx, dateAx
m_chart->loadAxisFromXml(reader);
}
} else if (reader.tokenType() == QXmlStreamReader::EndElement && } else if (reader.tokenType() == QXmlStreamReader::EndElement &&
reader.name() == QLatin1String("plotArea")) { reader.name() == QLatin1String("plotArea")) {
break; break;
@ -135,11 +148,11 @@ bool ChartFile::saveXmlChart(QXmlStreamWriter &writer) const
{ {
writer.writeStartElement(QStringLiteral("c:chart")); writer.writeStartElement(QStringLiteral("c:chart"));
writer.writeStartElement(QStringLiteral("c:plotArea")); writer.writeStartElement(QStringLiteral("c:plotArea"));
m_chart->saveToXml(writer); m_chart->saveXxxChartToXml(writer);
m_chart->saveAxisToXml(writer);
writer.writeEndElement(); //plotArea writer.writeEndElement(); //plotArea
// writer.writeStartElement(QStringLiteral("c:legend")); m_chart->saveLegendToXml(writer);
// writer.writeEndElement(); //legend
writer.writeEndElement(); //chart writer.writeEndElement(); //chart
return true; return true;

25
src/xlsx/xlsxpiechart.cpp

@ -46,7 +46,7 @@ PieChart::PieChart()
{ {
} }
bool PieChart::loadFromXml(QXmlStreamReader &reader) bool PieChart::loadXxxChartFromXml(QXmlStreamReader &reader)
{ {
Q_ASSERT(reader.name() == QLatin1String("pieChart")); Q_ASSERT(reader.name() == QLatin1String("pieChart"));
@ -66,28 +66,7 @@ bool PieChart::loadFromXml(QXmlStreamReader &reader)
return true; return true;
} }
bool PieChartPrivate::loadXmlSer(QXmlStreamReader &reader) void PieChart::saveXxxChartToXml(QXmlStreamWriter &writer) const
{
Q_ASSERT(reader.name() == QLatin1String("ser"));
while (!reader.atEnd()) {
reader.readNextStartElement();
if (reader.tokenType() == QXmlStreamReader::StartElement) {
if (reader.name() == QLatin1String("f")) {
XlsxSeries *series = new XlsxSeries;
series->numRef = reader.readElementText();
seriesList.append(QSharedPointer<XlsxSeries>(series));
}
} else if (reader.tokenType() == QXmlStreamReader::EndElement
&& reader.name() == QLatin1String("ser")) {
break;
}
}
return true;
}
void PieChart::saveToXml(QXmlStreamWriter &writer) const
{ {
Q_D(const PieChart); Q_D(const PieChart);

4
src/xlsx/xlsxpiechart.h

@ -40,8 +40,8 @@ public:
PieChart(); PieChart();
protected: protected:
bool loadFromXml(QXmlStreamReader &reader); bool loadXxxChartFromXml(QXmlStreamReader &reader);
void saveToXml(QXmlStreamWriter &writer) const; void saveXxxChartToXml(QXmlStreamWriter &writer) const;
}; };
QT_END_NAMESPACE_XLSX QT_END_NAMESPACE_XLSX

2
src/xlsx/xlsxpiechart_p.h

@ -48,8 +48,6 @@ class PieChartPrivate : public AbstractChartPrivate
public: public:
PieChartPrivate(PieChart *chart); PieChartPrivate(PieChart *chart);
bool loadXmlSer(QXmlStreamReader &reader);
}; };
QT_END_NAMESPACE_XLSX QT_END_NAMESPACE_XLSX

Loading…
Cancel
Save