Can read .xlsx files with border styles now
This commit is contained in:
@@ -12,6 +12,7 @@ int main()
|
|||||||
QXlsx::Format *format = xlsx.createFormat();
|
QXlsx::Format *format = xlsx.createFormat();
|
||||||
format->setFontColor(QColor(Qt::blue));
|
format->setFontColor(QColor(Qt::blue));
|
||||||
format->setFontSize(15);
|
format->setFontSize(15);
|
||||||
|
format->setBorderStyle(QXlsx::Format::BorderDashDotDot);
|
||||||
format->setPatternBackgroundColor(QColor(Qt::gray));
|
format->setPatternBackgroundColor(QColor(Qt::gray));
|
||||||
xlsx.write("A1", "Hello Qt!", format);
|
xlsx.write("A1", "Hello Qt!", format);
|
||||||
xlsx.write("A2", 500);
|
xlsx.write("A2", 500);
|
||||||
|
|||||||
@@ -704,7 +704,107 @@ bool Styles::readFill(XmlStreamReader &reader)
|
|||||||
|
|
||||||
bool Styles::readBorders(XmlStreamReader &reader)
|
bool Styles::readBorders(XmlStreamReader &reader)
|
||||||
{
|
{
|
||||||
|
Q_ASSERT(reader.name() == QLatin1String("borders"));
|
||||||
|
|
||||||
|
QXmlStreamAttributes attributes = reader.attributes();
|
||||||
|
int count = attributes.value(QLatin1String("count")).toInt();
|
||||||
|
for (int i=0; i<count; ++i) {
|
||||||
|
reader.readNextStartElement();
|
||||||
|
if (reader.name() != QLatin1String("border") || reader.tokenType() != QXmlStreamReader::StartElement)
|
||||||
return false;
|
return false;
|
||||||
|
readBorder(reader);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Styles::readBorder(XmlStreamReader &reader)
|
||||||
|
{
|
||||||
|
Q_ASSERT(reader.name() == QLatin1String("border"));
|
||||||
|
QSharedPointer<BorderData> border(new BorderData);
|
||||||
|
|
||||||
|
QXmlStreamAttributes attributes = reader.attributes();
|
||||||
|
bool isUp = attributes.hasAttribute(QLatin1String("diagonalUp"));
|
||||||
|
bool isDown = attributes.hasAttribute(QLatin1String("diagonalUp"));
|
||||||
|
if (isUp && isDown)
|
||||||
|
border->diagonalType = Format::DiagnoalBorderBoth;
|
||||||
|
else if (isUp)
|
||||||
|
border->diagonalType = Format::DiagonalBorderUp;
|
||||||
|
else if (isDown)
|
||||||
|
border->diagonalType = Format::DiagonalBorderDown;
|
||||||
|
|
||||||
|
while((reader.readNextStartElement(), true)) { //read until border endelement
|
||||||
|
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||||
|
if (reader.name() == QLatin1String("left"))
|
||||||
|
readSubBorder(reader, reader.name().toString(), border->left, border->leftColor);
|
||||||
|
else if (reader.name() == QLatin1String("right"))
|
||||||
|
readSubBorder(reader, reader.name().toString(), border->right, border->rightColor);
|
||||||
|
else if (reader.name() == QLatin1String("top"))
|
||||||
|
readSubBorder(reader, reader.name().toString(), border->top, border->topColor);
|
||||||
|
else if (reader.name() == QLatin1String("bottom"))
|
||||||
|
readSubBorder(reader, reader.name().toString(), border->bottom, border->bottomColor);
|
||||||
|
else if (reader.name() == QLatin1String("diagonal"))
|
||||||
|
readSubBorder(reader, reader.name().toString(), border->diagonal, border->diagonalColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reader.tokenType() == QXmlStreamReader::EndElement && reader.name() == QLatin1String("border"))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_bordersList.append(border);
|
||||||
|
m_bordersHash.insert(border->key(), border);
|
||||||
|
border->setIndex(m_bordersList.size()-1);//first call key(), then setIndex()
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Styles::readSubBorder(XmlStreamReader &reader, const QString &name, Format::BorderStyle &style, QColor &color)
|
||||||
|
{
|
||||||
|
Q_ASSERT(reader.name() == name);
|
||||||
|
|
||||||
|
static QMap<QString, Format::BorderStyle> stylesStringsMap;
|
||||||
|
if (stylesStringsMap.isEmpty()) {
|
||||||
|
stylesStringsMap[QStringLiteral("none")] = Format::BorderNone;
|
||||||
|
stylesStringsMap[QStringLiteral("thin")] = Format::BorderThin;
|
||||||
|
stylesStringsMap[QStringLiteral("medium")] = Format::BorderMedium;
|
||||||
|
stylesStringsMap[QStringLiteral("dashed")] = Format::BorderDashed;
|
||||||
|
stylesStringsMap[QStringLiteral("dotted")] = Format::BorderDotted;
|
||||||
|
stylesStringsMap[QStringLiteral("thick")] = Format::BorderThick;
|
||||||
|
stylesStringsMap[QStringLiteral("double")] = Format::BorderDouble;
|
||||||
|
stylesStringsMap[QStringLiteral("hair")] = Format::BorderHair;
|
||||||
|
stylesStringsMap[QStringLiteral("mediumDashed")] = Format::BorderMediumDashed;
|
||||||
|
stylesStringsMap[QStringLiteral("dashDot")] = Format::BorderDashDot;
|
||||||
|
stylesStringsMap[QStringLiteral("mediumDashDot")] = Format::BorderMediumDashDot;
|
||||||
|
stylesStringsMap[QStringLiteral("dashDotDot")] = Format::BorderDashDotDot;
|
||||||
|
stylesStringsMap[QStringLiteral("mediumDashDotDot")] = Format::BorderMediumDashDotDot;
|
||||||
|
stylesStringsMap[QStringLiteral("slantDashDot")] = Format::BorderSlantDashDot;
|
||||||
|
}
|
||||||
|
|
||||||
|
QXmlStreamAttributes attributes = reader.attributes();
|
||||||
|
if (attributes.hasAttribute(QLatin1String("style"))) {
|
||||||
|
QString styleString = attributes.value(QLatin1String("style")).toString();
|
||||||
|
if (stylesStringsMap.contains(styleString)) {
|
||||||
|
//get style
|
||||||
|
style = stylesStringsMap[styleString];
|
||||||
|
while((reader.readNextStartElement(),true)) {
|
||||||
|
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||||
|
if (reader.name() == QLatin1String("color")) {
|
||||||
|
QXmlStreamAttributes colorAttrs = reader.attributes();
|
||||||
|
if (colorAttrs.hasAttribute(QLatin1String("rgb"))) {
|
||||||
|
QString colorString = colorAttrs.value(QLatin1String("rgb")).toString();
|
||||||
|
//get color
|
||||||
|
color = fromARGBString(colorString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (reader.tokenType() == QXmlStreamReader::EndElement) {
|
||||||
|
if (reader.name() == name)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Styles::readCellXfs(XmlStreamReader &reader)
|
bool Styles::readCellXfs(XmlStreamReader &reader)
|
||||||
@@ -750,6 +850,15 @@ bool Styles::readCellXfs(XmlStreamReader &reader)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (xfAttrs.hasAttribute(QLatin1String("applyBorder"))) {
|
||||||
|
int id = xfAttrs.value(QLatin1String("borderId")).toInt();
|
||||||
|
if (id >= m_bordersList.size()) {
|
||||||
|
qDebug("Error read styles.xml, cellXfs borderId");
|
||||||
|
} else {
|
||||||
|
format->d_func()->borderData = *m_bordersList[id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
addFormat(format);
|
addFormat(format);
|
||||||
|
|
||||||
//Find the endElement of xf
|
//Find the endElement of xf
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#define XLSXSTYLES_H
|
#define XLSXSTYLES_H
|
||||||
|
|
||||||
#include "xlsxglobal.h"
|
#include "xlsxglobal.h"
|
||||||
|
#include "xlsxformat.h"
|
||||||
#include <QSharedPointer>
|
#include <QSharedPointer>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
@@ -76,6 +77,8 @@ private:
|
|||||||
bool readFills(XmlStreamReader &reader);
|
bool readFills(XmlStreamReader &reader);
|
||||||
bool readFill(XmlStreamReader &reader);
|
bool readFill(XmlStreamReader &reader);
|
||||||
bool readBorders(XmlStreamReader &reader);
|
bool readBorders(XmlStreamReader &reader);
|
||||||
|
bool readBorder(XmlStreamReader &reader);
|
||||||
|
bool readSubBorder(XmlStreamReader &reader, const QString &name, Format::BorderStyle &style, QColor &color);
|
||||||
bool readCellXfs(XmlStreamReader &reader);
|
bool readCellXfs(XmlStreamReader &reader);
|
||||||
|
|
||||||
QHash<QString, int> m_builtinNumFmtsHash;
|
QHash<QString, int> m_builtinNumFmtsHash;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ private Q_SLOTS:
|
|||||||
|
|
||||||
void testReadFonts();
|
void testReadFonts();
|
||||||
void testReadFills();
|
void testReadFills();
|
||||||
void testReaderBorders();
|
void testReadBorders();
|
||||||
};
|
};
|
||||||
|
|
||||||
StylesTest::StylesTest()
|
StylesTest::StylesTest()
|
||||||
@@ -105,7 +105,7 @@ void StylesTest::testReadFills()
|
|||||||
"</fills>";
|
"</fills>";
|
||||||
QXlsx::Styles styles(true);
|
QXlsx::Styles styles(true);
|
||||||
QXlsx::XmlStreamReader reader(xmlData);
|
QXlsx::XmlStreamReader reader(xmlData);
|
||||||
reader.readNextStartElement();//So current node is fonts
|
reader.readNextStartElement();//So current node is fills
|
||||||
styles.readFills(reader);
|
styles.readFills(reader);
|
||||||
|
|
||||||
QCOMPARE(styles.m_fillsList.size(), 4);
|
QCOMPARE(styles.m_fillsList.size(), 4);
|
||||||
@@ -113,9 +113,19 @@ void StylesTest::testReadFills()
|
|||||||
QCOMPARE(styles.m_fillsList[3]->bgColor, QColor(Qt::gray));//for solid pattern, bg vs. fg color!
|
QCOMPARE(styles.m_fillsList[3]->bgColor, QColor(Qt::gray));//for solid pattern, bg vs. fg color!
|
||||||
}
|
}
|
||||||
|
|
||||||
void StylesTest::testReaderBorders()
|
void StylesTest::testReadBorders()
|
||||||
{
|
{
|
||||||
|
QByteArray xmlData ="<borders count=\"2\">"
|
||||||
|
"<border><left/><right/><top/><bottom/><diagonal/></border>"
|
||||||
|
"<border><left style=\"dashDotDot\"><color auto=\"1\"/></left><right style=\"dashDotDot\"><color auto=\"1\"/></right><top style=\"dashDotDot\"><color auto=\"1\"/></top><bottom style=\"dashDotDot\"><color auto=\"1\"/></bottom><diagonal/></border>"
|
||||||
|
"</borders>";
|
||||||
|
|
||||||
|
QXlsx::Styles styles(true);
|
||||||
|
QXlsx::XmlStreamReader reader(xmlData);
|
||||||
|
reader.readNextStartElement();//So current node is borders
|
||||||
|
styles.readBorders(reader);
|
||||||
|
|
||||||
|
QCOMPARE(styles.m_bordersList.size(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_APPLESS_MAIN(StylesTest)
|
QTEST_APPLESS_MAIN(StylesTest)
|
||||||
|
|||||||
Reference in New Issue
Block a user