Can read .xlsx files with border styles now
This commit is contained in:
@@ -12,6 +12,7 @@ int main()
|
||||
QXlsx::Format *format = xlsx.createFormat();
|
||||
format->setFontColor(QColor(Qt::blue));
|
||||
format->setFontSize(15);
|
||||
format->setBorderStyle(QXlsx::Format::BorderDashDotDot);
|
||||
format->setPatternBackgroundColor(QColor(Qt::gray));
|
||||
xlsx.write("A1", "Hello Qt!", format);
|
||||
xlsx.write("A2", 500);
|
||||
|
||||
+110
-1
@@ -704,7 +704,107 @@ bool Styles::readFill(XmlStreamReader &reader)
|
||||
|
||||
bool Styles::readBorders(XmlStreamReader &reader)
|
||||
{
|
||||
return false;
|
||||
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;
|
||||
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)
|
||||
@@ -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);
|
||||
|
||||
//Find the endElement of xf
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#define XLSXSTYLES_H
|
||||
|
||||
#include "xlsxglobal.h"
|
||||
#include "xlsxformat.h"
|
||||
#include <QSharedPointer>
|
||||
#include <QHash>
|
||||
#include <QList>
|
||||
@@ -76,6 +77,8 @@ private:
|
||||
bool readFills(XmlStreamReader &reader);
|
||||
bool readFill(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);
|
||||
|
||||
QHash<QString, int> m_builtinNumFmtsHash;
|
||||
|
||||
@@ -20,7 +20,7 @@ private Q_SLOTS:
|
||||
|
||||
void testReadFonts();
|
||||
void testReadFills();
|
||||
void testReaderBorders();
|
||||
void testReadBorders();
|
||||
};
|
||||
|
||||
StylesTest::StylesTest()
|
||||
@@ -105,7 +105,7 @@ void StylesTest::testReadFills()
|
||||
"</fills>";
|
||||
QXlsx::Styles styles(true);
|
||||
QXlsx::XmlStreamReader reader(xmlData);
|
||||
reader.readNextStartElement();//So current node is fonts
|
||||
reader.readNextStartElement();//So current node is fills
|
||||
styles.readFills(reader);
|
||||
|
||||
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!
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user