Browse Source

Add read xml function for SharedStrings

master
Debao Zhang 12 years ago
parent
commit
426ce14311
  1. 2
      examples/xlsx/hello/main.cpp
  2. 6
      src/xlsx/xlsxpackage.cpp
  3. 93
      src/xlsx/xlsxsharedstrings.cpp
  4. 28
      src/xlsx/xlsxsharedstrings_p.h
  5. 4
      src/xlsx/xlsxworkbook.cpp
  6. 3
      src/xlsx/xlsxworkbook_p.h
  7. 3
      tests/auto/auto.pro
  8. 13
      tests/auto/sharedstrings/sharedstrings.pro
  9. 103
      tests/auto/sharedstrings/tst_sharedstringstest.cpp

2
examples/xlsx/hello/main.cpp

@ -31,7 +31,7 @@ int main()
xlsx.write(1, 1, 200);
xlsx.write(2, 1, 300);
xlsx.write(3, 1, 400);
xlsx.write(4, 1, "=SUM(B1:B4)");
// xlsx.write(4, 1, "=SUM(B1:B4)");
xlsx.saveAs(DATA_PATH"Test.xlsx");
return 0;

6
src/xlsx/xlsxpackage.cpp

@ -283,11 +283,7 @@ void Package::writeDocPropsCoreFile(ZipWriter &zipWriter)
void Package::writeSharedStringsFile(ZipWriter &zipWriter)
{
QByteArray data;
QBuffer buffer(&data);
buffer.open(QIODevice::WriteOnly);
m_workbook->sharedStrings()->saveToXmlFile(&buffer);
zipWriter.addFile(QStringLiteral("xl/sharedStrings.xml"), data);
zipWriter.addFile(QStringLiteral("xl/sharedStrings.xml"), m_workbook->sharedStrings()->saveToXmlData());
}
void Package::writeStylesFiles(ZipWriter &zipWriter)

93
src/xlsx/xlsxsharedstrings.cpp

@ -24,15 +24,16 @@
****************************************************************************/
#include "xlsxsharedstrings_p.h"
#include "xlsxxmlwriter_p.h"
#include "xlsxxmlreader_p.h"
#include <QDir>
#include <QFile>
#include <QRegularExpression>
#include <QDebug>
#include <QBuffer>
namespace QXlsx {
SharedStrings::SharedStrings(QObject *parent) :
QObject(parent)
SharedStrings::SharedStrings()
{
m_stringCount = 0;
}
@ -46,23 +47,49 @@ int SharedStrings::addSharedString(const QString &string)
{
m_stringCount += 1;
if (m_stringTable.contains(string))
return m_stringTable[string];
if (m_stringTable.contains(string)) {
XlsxSharedStringInfo &item = m_stringTable[string];
item.count += 1;
return item.index;
}
int index = m_stringTable.size();
m_stringTable[string] = index;
m_stringTable[string] = XlsxSharedStringInfo(index);
m_stringList.append(string);
return index;
}
void SharedStrings::removeSharedString(const QString &string)
{
if (!m_stringTable.contains(string))
return;
m_stringCount -= 1;
XlsxSharedStringInfo &item = m_stringTable[string];
item.count -= 1;
if (item.count <= 0) {
for (int i=item.index+1; i<m_stringList.size(); ++i)
m_stringTable[m_stringList[i]].index -= 1;
m_stringList.removeAt(item.index);
m_stringTable.remove(string);
}
}
int SharedStrings::getSharedStringIndex(const QString &string) const
{
return m_stringTable[string];
if (m_stringTable.contains(string))
return m_stringTable[string].index;
return -1;
}
QString SharedStrings::getSharedString(int index) const
{
return m_stringList[index];
if (index < m_stringList.count() && index >= 0)
return m_stringList[index];
return QString();
}
QStringList SharedStrings::getSharedStrings() const
@ -99,4 +126,56 @@ void SharedStrings::saveToXmlFile(QIODevice *device) const
writer.writeEndDocument();
}
QByteArray SharedStrings::saveToXmlData() const
{
QByteArray data;
QBuffer buffer(&data);
buffer.open(QIODevice::WriteOnly);
saveToXmlFile(&buffer);
return data;
}
QSharedPointer<SharedStrings> SharedStrings::loadFromXmlFile(QIODevice *device)
{
QSharedPointer<SharedStrings> sst(new SharedStrings);
XmlStreamReader reader(device);
int count = 0;
while(!reader.atEnd()) {
QXmlStreamReader::TokenType token = reader.readNext();
if (token == QXmlStreamReader::StartElement) {
if (reader.name() == QLatin1String("sst")) {
QXmlStreamAttributes attributes = reader.attributes();
count = attributes.value(QLatin1String("uniqueCount")).toInt();
} else if (reader.name() == QLatin1String("si")) {
if (reader.readNextStartElement()) {
if (reader.name() == QLatin1String("t")) {
QXmlStreamAttributes attributes = reader.attributes();
QString string = reader.readElementText();
sst->m_stringTable[string] = XlsxSharedStringInfo(sst->m_stringTable.size(), 0);
sst->m_stringList.append(string);
}
}
}
}
}
if (sst->m_stringTable.size() != count) {
qDebug("Error: Shared string count");
}
return sst;
}
QSharedPointer<SharedStrings> SharedStrings::loadFromXmlData(const QByteArray &data)
{
QBuffer buffer;
buffer.setData(data);
buffer.open(QIODevice::ReadOnly);
return loadFromXmlFile(&buffer);
}
} //namespace

28
src/xlsx/xlsxsharedstrings_p.h

@ -25,31 +25,47 @@
#ifndef XLSXSHAREDSTRINGS_H
#define XLSXSHAREDSTRINGS_H
#include <QObject>
#include "xlsxglobal.h"
#include <QHash>
#include <QStringList>
#include <QSharedPointer>
class QIODevice;
namespace QXlsx {
class SharedStrings : public QObject
class XlsxSharedStringInfo
{
Q_OBJECT
public:
explicit SharedStrings(QObject *parent = 0);
XlsxSharedStringInfo(int index=0, int count = 1) :
index(index), count(count)
{
}
int index;
int count;
};
class XLSX_AUTOTEST_EXPORT SharedStrings
{
public:
SharedStrings();
int count() const;
public slots:
int addSharedString(const QString &string);
void removeSharedString(const QString &string);
int getSharedStringIndex(const QString &string) const;
QString getSharedString(int index) const;
QStringList getSharedStrings() const;
void saveToXmlFile(QIODevice *device) const;
QByteArray saveToXmlData() const;
static QSharedPointer<SharedStrings> loadFromXmlFile(QIODevice *device);
static QSharedPointer<SharedStrings> loadFromXmlData(const QByteArray &data);
private:
QHash<QString, int> m_stringTable; //for fast lookup
QHash<QString, XlsxSharedStringInfo> m_stringTable; //for fast lookup
QStringList m_stringList;
int m_stringCount;
};

4
src/xlsx/xlsxworkbook.cpp

@ -40,7 +40,7 @@ namespace QXlsx {
WorkbookPrivate::WorkbookPrivate(Workbook *q) :
q_ptr(q)
{
sharedStrings = new SharedStrings(q);
sharedStrings = QSharedPointer<SharedStrings> (new SharedStrings);
styles = new Styles(q);
x_window = 240;
@ -176,7 +176,7 @@ QList<Worksheet *> Workbook::worksheets() const
SharedStrings *Workbook::sharedStrings()
{
Q_D(Workbook);
return d->sharedStrings;
return d->sharedStrings.data();
}
Styles *Workbook::styles()

3
src/xlsx/xlsxworkbook_p.h

@ -25,6 +25,7 @@
#ifndef XLSXWORKBOOK_P_H
#define XLSXWORKBOOK_P_H
#include "xlsxworkbook.h"
#include <QSharedPointer>
namespace QXlsx {
@ -36,7 +37,7 @@ public:
Workbook *q_ptr;
SharedStrings *sharedStrings;
QSharedPointer<SharedStrings> sharedStrings;
QList<Worksheet *> worksheets;
Styles *styles;
QList<QImage> images;

3
tests/auto/auto.pro

@ -6,4 +6,5 @@ SUBDIRS=\
relationships \
propscore \
propsapp \
readdocument
readdocument \
sharedstrings

13
tests/auto/sharedstrings/sharedstrings.pro

@ -0,0 +1,13 @@
QT += testlib xlsx xlsx-private
CONFIG += testcase
DEFINES += XLSX_TEST
TARGET = tst_sharedstringstest
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += tst_sharedstringstest.cpp
DEFINES += SRCDIR=\\\"$$PWD/\\\"

103
tests/auto/sharedstrings/tst_sharedstringstest.cpp

@ -0,0 +1,103 @@
#include "private/xlsxsharedstrings_p.h"
#include <QString>
#include <QtTest>
#include <QXmlStreamReader>
class SharedStringsTest : public QObject
{
Q_OBJECT
public:
SharedStringsTest();
private Q_SLOTS:
void testAddSharedString();
void testRemoveSharedString();
void testLoadXmlData();
};
SharedStringsTest::SharedStringsTest()
{
}
void SharedStringsTest::testAddSharedString()
{
QXlsx::SharedStrings sst;
sst.addSharedString("Hello Qt!");
sst.addSharedString("Xlsx Writer");
sst.addSharedString("Hello World");
sst.addSharedString("Hello Qt!");
QByteArray xmlData = sst.saveToXmlData();
QXmlStreamReader reader(xmlData);
int count = 0;
int uniqueCount = 0;
while(!reader.atEnd()) {
QXmlStreamReader::TokenType token = reader.readNext();
if (token == QXmlStreamReader::StartElement) {
if (reader.name() == QLatin1String("sst")) {
QXmlStreamAttributes attributes = reader.attributes();
count = attributes.value("count").toInt();
uniqueCount = attributes.value("uniqueCount").toInt();
}
}
}
QCOMPARE(count, 4);
QCOMPARE(uniqueCount, 3);
}
void SharedStringsTest::testRemoveSharedString()
{
QXlsx::SharedStrings sst;
sst.addSharedString("Hello Qt!");
sst.addSharedString("Xlsx Writer");
sst.addSharedString("Hello World");
sst.addSharedString("Hello Qt!");
sst.addSharedString("Hello Qt!");
sst.removeSharedString("Hello World");
sst.removeSharedString("Hello Qt!");
sst.removeSharedString("Non exists");
QByteArray xmlData = sst.saveToXmlData();
QXmlStreamReader reader(xmlData);
int count = 0;
int uniqueCount = 0;
while(!reader.atEnd()) {
QXmlStreamReader::TokenType token = reader.readNext();
if (token == QXmlStreamReader::StartElement) {
if (reader.name() == QLatin1String("sst")) {
QXmlStreamAttributes attributes = reader.attributes();
count = attributes.value("count").toInt();
uniqueCount = attributes.value("uniqueCount").toInt();
}
}
}
QCOMPARE(count, 3);
QCOMPARE(uniqueCount, 2);
}
void SharedStringsTest::testLoadXmlData()
{
QXlsx::SharedStrings sst;
sst.addSharedString("Hello Qt!");
sst.addSharedString("Xlsx Writer");
sst.addSharedString("Hello World");
sst.addSharedString("Hello Qt!");
QByteArray xmlData = sst.saveToXmlData();
QSharedPointer<QXlsx::SharedStrings> sst2 = QXlsx::SharedStrings::loadFromXmlData(xmlData);
QCOMPARE(sst2->getSharedString(0), QStringLiteral("Hello Qt!"));
QCOMPARE(sst2->getSharedString(2), QStringLiteral("Hello World"));
}
QTEST_APPLESS_MAIN(SharedStringsTest)
#include "tst_sharedstringstest.moc"
Loading…
Cancel
Save