Browse Source

Can read .xlsx files with border styles now

master
Debao Zhang 11 years ago
parent
commit
31270604c6
  1. 1
      examples/xlsx/readwrite/main.cpp
  2. 111
      src/xlsx/xlsxstyles.cpp
  3. 3
      src/xlsx/xlsxstyles_p.h
  4. 16
      tests/auto/styles/tst_stylestest.cpp

1
examples/xlsx/readwrite/main.cpp

@ -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);

111
src/xlsx/xlsxstyles.cpp

@ -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

3
src/xlsx/xlsxstyles_p.h

@ -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;

16
tests/auto/styles/tst_stylestest.cpp

@ -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)

Loading…
Cancel
Save