Add read xml function for SharedStrings
This commit is contained in:
@@ -31,7 +31,7 @@ int main()
|
|||||||
xlsx.write(1, 1, 200);
|
xlsx.write(1, 1, 200);
|
||||||
xlsx.write(2, 1, 300);
|
xlsx.write(2, 1, 300);
|
||||||
xlsx.write(3, 1, 400);
|
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");
|
xlsx.saveAs(DATA_PATH"Test.xlsx");
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -283,11 +283,7 @@ void Package::writeDocPropsCoreFile(ZipWriter &zipWriter)
|
|||||||
|
|
||||||
void Package::writeSharedStringsFile(ZipWriter &zipWriter)
|
void Package::writeSharedStringsFile(ZipWriter &zipWriter)
|
||||||
{
|
{
|
||||||
QByteArray data;
|
zipWriter.addFile(QStringLiteral("xl/sharedStrings.xml"), m_workbook->sharedStrings()->saveToXmlData());
|
||||||
QBuffer buffer(&data);
|
|
||||||
buffer.open(QIODevice::WriteOnly);
|
|
||||||
m_workbook->sharedStrings()->saveToXmlFile(&buffer);
|
|
||||||
zipWriter.addFile(QStringLiteral("xl/sharedStrings.xml"), data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Package::writeStylesFiles(ZipWriter &zipWriter)
|
void Package::writeStylesFiles(ZipWriter &zipWriter)
|
||||||
|
|||||||
@@ -24,15 +24,16 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#include "xlsxsharedstrings_p.h"
|
#include "xlsxsharedstrings_p.h"
|
||||||
#include "xlsxxmlwriter_p.h"
|
#include "xlsxxmlwriter_p.h"
|
||||||
|
#include "xlsxxmlreader_p.h"
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QBuffer>
|
||||||
|
|
||||||
namespace QXlsx {
|
namespace QXlsx {
|
||||||
|
|
||||||
SharedStrings::SharedStrings(QObject *parent) :
|
SharedStrings::SharedStrings()
|
||||||
QObject(parent)
|
|
||||||
{
|
{
|
||||||
m_stringCount = 0;
|
m_stringCount = 0;
|
||||||
}
|
}
|
||||||
@@ -46,23 +47,49 @@ int SharedStrings::addSharedString(const QString &string)
|
|||||||
{
|
{
|
||||||
m_stringCount += 1;
|
m_stringCount += 1;
|
||||||
|
|
||||||
if (m_stringTable.contains(string))
|
if (m_stringTable.contains(string)) {
|
||||||
return m_stringTable[string];
|
XlsxSharedStringInfo &item = m_stringTable[string];
|
||||||
|
item.count += 1;
|
||||||
|
return item.index;
|
||||||
|
}
|
||||||
|
|
||||||
int index = m_stringTable.size();
|
int index = m_stringTable.size();
|
||||||
m_stringTable[string] = index;
|
m_stringTable[string] = XlsxSharedStringInfo(index);
|
||||||
m_stringList.append(string);
|
m_stringList.append(string);
|
||||||
return index;
|
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
|
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
|
QString SharedStrings::getSharedString(int index) const
|
||||||
{
|
{
|
||||||
|
if (index < m_stringList.count() && index >= 0)
|
||||||
return m_stringList[index];
|
return m_stringList[index];
|
||||||
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList SharedStrings::getSharedStrings() const
|
QStringList SharedStrings::getSharedStrings() const
|
||||||
@@ -99,4 +126,56 @@ void SharedStrings::saveToXmlFile(QIODevice *device) const
|
|||||||
writer.writeEndDocument();
|
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
|
} //namespace
|
||||||
|
|||||||
@@ -25,31 +25,47 @@
|
|||||||
#ifndef XLSXSHAREDSTRINGS_H
|
#ifndef XLSXSHAREDSTRINGS_H
|
||||||
#define XLSXSHAREDSTRINGS_H
|
#define XLSXSHAREDSTRINGS_H
|
||||||
|
|
||||||
#include <QObject>
|
#include "xlsxglobal.h"
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
#include <QSharedPointer>
|
||||||
|
|
||||||
class QIODevice;
|
class QIODevice;
|
||||||
|
|
||||||
namespace QXlsx {
|
namespace QXlsx {
|
||||||
|
|
||||||
class SharedStrings : public QObject
|
class XlsxSharedStringInfo
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
|
||||||
public:
|
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;
|
int count() const;
|
||||||
|
|
||||||
public slots:
|
|
||||||
int addSharedString(const QString &string);
|
int addSharedString(const QString &string);
|
||||||
|
void removeSharedString(const QString &string);
|
||||||
|
|
||||||
int getSharedStringIndex(const QString &string) const;
|
int getSharedStringIndex(const QString &string) const;
|
||||||
QString getSharedString(int index) const;
|
QString getSharedString(int index) const;
|
||||||
QStringList getSharedStrings() const;
|
QStringList getSharedStrings() const;
|
||||||
|
|
||||||
void saveToXmlFile(QIODevice *device) const;
|
void saveToXmlFile(QIODevice *device) const;
|
||||||
|
QByteArray saveToXmlData() const;
|
||||||
|
static QSharedPointer<SharedStrings> loadFromXmlFile(QIODevice *device);
|
||||||
|
static QSharedPointer<SharedStrings> loadFromXmlData(const QByteArray &data);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QHash<QString, int> m_stringTable; //for fast lookup
|
QHash<QString, XlsxSharedStringInfo> m_stringTable; //for fast lookup
|
||||||
QStringList m_stringList;
|
QStringList m_stringList;
|
||||||
int m_stringCount;
|
int m_stringCount;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace QXlsx {
|
|||||||
WorkbookPrivate::WorkbookPrivate(Workbook *q) :
|
WorkbookPrivate::WorkbookPrivate(Workbook *q) :
|
||||||
q_ptr(q)
|
q_ptr(q)
|
||||||
{
|
{
|
||||||
sharedStrings = new SharedStrings(q);
|
sharedStrings = QSharedPointer<SharedStrings> (new SharedStrings);
|
||||||
styles = new Styles(q);
|
styles = new Styles(q);
|
||||||
|
|
||||||
x_window = 240;
|
x_window = 240;
|
||||||
@@ -176,7 +176,7 @@ QList<Worksheet *> Workbook::worksheets() const
|
|||||||
SharedStrings *Workbook::sharedStrings()
|
SharedStrings *Workbook::sharedStrings()
|
||||||
{
|
{
|
||||||
Q_D(Workbook);
|
Q_D(Workbook);
|
||||||
return d->sharedStrings;
|
return d->sharedStrings.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
Styles *Workbook::styles()
|
Styles *Workbook::styles()
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#ifndef XLSXWORKBOOK_P_H
|
#ifndef XLSXWORKBOOK_P_H
|
||||||
#define XLSXWORKBOOK_P_H
|
#define XLSXWORKBOOK_P_H
|
||||||
#include "xlsxworkbook.h"
|
#include "xlsxworkbook.h"
|
||||||
|
#include <QSharedPointer>
|
||||||
|
|
||||||
namespace QXlsx {
|
namespace QXlsx {
|
||||||
|
|
||||||
@@ -36,7 +37,7 @@ public:
|
|||||||
|
|
||||||
Workbook *q_ptr;
|
Workbook *q_ptr;
|
||||||
|
|
||||||
SharedStrings *sharedStrings;
|
QSharedPointer<SharedStrings> sharedStrings;
|
||||||
QList<Worksheet *> worksheets;
|
QList<Worksheet *> worksheets;
|
||||||
Styles *styles;
|
Styles *styles;
|
||||||
QList<QImage> images;
|
QList<QImage> images;
|
||||||
|
|||||||
+2
-1
@@ -6,4 +6,5 @@ SUBDIRS=\
|
|||||||
relationships \
|
relationships \
|
||||||
propscore \
|
propscore \
|
||||||
propsapp \
|
propsapp \
|
||||||
readdocument
|
readdocument \
|
||||||
|
sharedstrings
|
||||||
|
|||||||
@@ -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/\\\"
|
||||||
@@ -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"
|
||||||
Reference in New Issue
Block a user