Add read xml function for SharedStrings
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
+2
-1
@@ -6,4 +6,5 @@ SUBDIRS=\
|
||||
relationships \
|
||||
propscore \
|
||||
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