Able to read the document properties back now!
This commit is contained in:
@@ -10,11 +10,9 @@
|
|||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
QXlsx::Document xlsx;
|
QXlsx::Document xlsx;
|
||||||
/*
|
xlsx.write("A1", "View the properties through:");
|
||||||
These properties are visible when you use the
|
xlsx.write("A2", "Office Button -> Prepare -> Properties option in Excel");
|
||||||
Office Button -> Prepare -> Properties option in Excel and are also
|
|
||||||
available to external applications that read or index windows files
|
|
||||||
*/
|
|
||||||
xlsx.setDocumentProperty("title", "This is an example spreadsheet");
|
xlsx.setDocumentProperty("title", "This is an example spreadsheet");
|
||||||
xlsx.setDocumentProperty("subject", "With document properties");
|
xlsx.setDocumentProperty("subject", "With document properties");
|
||||||
xlsx.setDocumentProperty("creator", "Debao Zhang");
|
xlsx.setDocumentProperty("creator", "Debao Zhang");
|
||||||
|
|||||||
@@ -24,15 +24,17 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#include "xlsxdocpropsapp_p.h"
|
#include "xlsxdocpropsapp_p.h"
|
||||||
#include "xlsxxmlwriter_p.h"
|
#include "xlsxxmlwriter_p.h"
|
||||||
|
#include "xlsxxmlreader_p.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
#include <QBuffer>
|
||||||
|
|
||||||
namespace QXlsx {
|
namespace QXlsx {
|
||||||
|
|
||||||
DocPropsApp::DocPropsApp(QObject *parent) :
|
DocPropsApp::DocPropsApp()
|
||||||
QObject(parent)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,6 +48,36 @@ void DocPropsApp::addHeadingPair(const QString &name, int value)
|
|||||||
m_headingPairsList.append(qMakePair(name, value));
|
m_headingPairsList.append(qMakePair(name, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DocPropsApp::setProperty(const QString &name, const QString &value)
|
||||||
|
{
|
||||||
|
static QStringList validKeys;
|
||||||
|
if (validKeys.isEmpty()) {
|
||||||
|
validKeys << QStringLiteral("manager") << QStringLiteral("company");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!validKeys.contains(name))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (value.isEmpty())
|
||||||
|
m_properties.remove(name);
|
||||||
|
else
|
||||||
|
m_properties[name] = value;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DocPropsApp::property(const QString &name) const
|
||||||
|
{
|
||||||
|
if (m_properties.contains(name))
|
||||||
|
return m_properties[name];
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList DocPropsApp::propertyNames() const
|
||||||
|
{
|
||||||
|
return m_properties.keys();
|
||||||
|
}
|
||||||
|
|
||||||
void DocPropsApp::saveToXmlFile(QIODevice *device)
|
void DocPropsApp::saveToXmlFile(QIODevice *device)
|
||||||
{
|
{
|
||||||
@@ -84,10 +116,10 @@ void DocPropsApp::saveToXmlFile(QIODevice *device)
|
|||||||
writer.writeEndElement();//vt:vector
|
writer.writeEndElement();//vt:vector
|
||||||
writer.writeEndElement();//TitlesOfParts
|
writer.writeEndElement();//TitlesOfParts
|
||||||
|
|
||||||
if (property("manager").isValid())
|
if (m_properties.contains(QStringLiteral("manager")))
|
||||||
writer.writeTextElement(QStringLiteral("Manager"), property("manager").toString());
|
writer.writeTextElement(QStringLiteral("Manager"), m_properties[QStringLiteral("manager")]);
|
||||||
//Not like "manager", "company" always exists for Excel generated file.
|
//Not like "manager", "company" always exists for Excel generated file.
|
||||||
writer.writeTextElement(QStringLiteral("Company"), property("company").isValid() ? property("company").toString() : QString());
|
writer.writeTextElement(QStringLiteral("Company"), m_properties.contains(QStringLiteral("company")) ? m_properties[QStringLiteral("company")]: QString());
|
||||||
writer.writeTextElement(QStringLiteral("LinksUpToDate"), QStringLiteral("false"));
|
writer.writeTextElement(QStringLiteral("LinksUpToDate"), QStringLiteral("false"));
|
||||||
writer.writeTextElement(QStringLiteral("SharedDoc"), QStringLiteral("false"));
|
writer.writeTextElement(QStringLiteral("SharedDoc"), QStringLiteral("false"));
|
||||||
writer.writeTextElement(QStringLiteral("HyperlinksChanged"), QStringLiteral("false"));
|
writer.writeTextElement(QStringLiteral("HyperlinksChanged"), QStringLiteral("false"));
|
||||||
@@ -97,4 +129,46 @@ void DocPropsApp::saveToXmlFile(QIODevice *device)
|
|||||||
writer.writeEndDocument();
|
writer.writeEndDocument();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray DocPropsApp::saveToXmlData()
|
||||||
|
{
|
||||||
|
QByteArray data;
|
||||||
|
QBuffer buffer(&data);
|
||||||
|
buffer.open(QIODevice::WriteOnly);
|
||||||
|
saveToXmlFile(&buffer);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
DocPropsApp DocPropsApp::loadFromXmlFile(QIODevice *device)
|
||||||
|
{
|
||||||
|
DocPropsApp props;
|
||||||
|
XmlStreamReader reader(device);
|
||||||
|
while(!reader.atEnd()) {
|
||||||
|
QXmlStreamReader::TokenType token = reader.readNext();
|
||||||
|
if (token == QXmlStreamReader::StartElement) {
|
||||||
|
if (reader.name() == QLatin1String("Properties"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (reader.name() == QStringLiteral("Manager")) {
|
||||||
|
props.setProperty(QStringLiteral("manager"), reader.readElementText());
|
||||||
|
} else if (reader.qualifiedName() == QStringLiteral("Company")) {
|
||||||
|
props.setProperty(QStringLiteral("company"), reader.readElementText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reader.hasError()) {
|
||||||
|
qDebug("Error when read doc props app file.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
|
DocPropsApp DocPropsApp::loadFromXmlData(const QByteArray &data)
|
||||||
|
{
|
||||||
|
QBuffer buffer;
|
||||||
|
buffer.setData(data);
|
||||||
|
buffer.open(QIODevice::ReadOnly);
|
||||||
|
return loadFromXmlFile(&buffer);
|
||||||
|
}
|
||||||
|
|
||||||
} //namespace
|
} //namespace
|
||||||
|
|||||||
@@ -26,31 +26,36 @@
|
|||||||
#define XLSXDOCPROPSAPP_H
|
#define XLSXDOCPROPSAPP_H
|
||||||
|
|
||||||
#include "xlsxglobal.h"
|
#include "xlsxglobal.h"
|
||||||
#include <QObject>
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QPair>
|
#include <QPair>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
#include <QMap>
|
||||||
|
|
||||||
class QIODevice;
|
class QIODevice;
|
||||||
|
|
||||||
namespace QXlsx {
|
namespace QXlsx {
|
||||||
|
|
||||||
class XLSX_AUTOTEST_EXPORT DocPropsApp : public QObject
|
class XLSX_AUTOTEST_EXPORT DocPropsApp
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
explicit DocPropsApp(QObject *parent = 0);
|
DocPropsApp();
|
||||||
|
|
||||||
signals:
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void addPartTitle(const QString &title);
|
void addPartTitle(const QString &title);
|
||||||
void addHeadingPair(const QString &name, int value);
|
void addHeadingPair(const QString &name, int value);
|
||||||
|
|
||||||
|
bool setProperty(const QString &name, const QString &value);
|
||||||
|
QString property(const QString &name) const;
|
||||||
|
QStringList propertyNames() const;
|
||||||
|
|
||||||
|
QByteArray saveToXmlData();
|
||||||
void saveToXmlFile(QIODevice *device);
|
void saveToXmlFile(QIODevice *device);
|
||||||
|
static DocPropsApp loadFromXmlFile(QIODevice *device);
|
||||||
|
static DocPropsApp loadFromXmlData(const QByteArray &data);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QStringList m_titlesOfPartsList;
|
QStringList m_titlesOfPartsList;
|
||||||
QList<QPair<QString, int> > m_headingPairsList;
|
QList<QPair<QString, int> > m_headingPairsList;
|
||||||
|
QMap<QString, QString> m_properties;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+118
-18
@@ -24,18 +24,54 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#include "xlsxdocpropscore_p.h"
|
#include "xlsxdocpropscore_p.h"
|
||||||
#include "xlsxxmlwriter_p.h"
|
#include "xlsxxmlwriter_p.h"
|
||||||
|
#include "xlsxxmlreader_p.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QVariant>
|
#include <QDebug>
|
||||||
|
#include <QBuffer>
|
||||||
|
|
||||||
namespace QXlsx {
|
namespace QXlsx {
|
||||||
|
|
||||||
DocPropsCore::DocPropsCore(QObject *parent) :
|
DocPropsCore::DocPropsCore()
|
||||||
QObject(parent)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DocPropsCore::setProperty(const QString &name, const QString &value)
|
||||||
|
{
|
||||||
|
static QStringList validKeys;
|
||||||
|
if (validKeys.isEmpty()) {
|
||||||
|
validKeys << QStringLiteral("title") << QStringLiteral("subject")
|
||||||
|
<< QStringLiteral("keywords") << QStringLiteral("description")
|
||||||
|
<< QStringLiteral("category") << QStringLiteral("status")
|
||||||
|
<< QStringLiteral("created") << QStringLiteral("creator");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!validKeys.contains(name))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (value.isEmpty())
|
||||||
|
m_properties.remove(name);
|
||||||
|
else
|
||||||
|
m_properties[name] = value;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DocPropsCore::property(const QString &name) const
|
||||||
|
{
|
||||||
|
if (m_properties.contains(name))
|
||||||
|
return m_properties[name];
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList DocPropsCore::propertyNames() const
|
||||||
|
{
|
||||||
|
return m_properties.keys();
|
||||||
|
}
|
||||||
|
|
||||||
void DocPropsCore::saveToXmlFile(QIODevice *device)
|
void DocPropsCore::saveToXmlFile(QIODevice *device)
|
||||||
{
|
{
|
||||||
XmlStreamWriter writer(device);
|
XmlStreamWriter writer(device);
|
||||||
@@ -47,21 +83,26 @@ void DocPropsCore::saveToXmlFile(QIODevice *device)
|
|||||||
writer.writeAttribute(QStringLiteral("xmlns:dcterms"), QStringLiteral("http://purl.org/dc/terms/"));
|
writer.writeAttribute(QStringLiteral("xmlns:dcterms"), QStringLiteral("http://purl.org/dc/terms/"));
|
||||||
writer.writeAttribute(QStringLiteral("xmlns:dcmitype"), QStringLiteral("http://purl.org/dc/dcmitype/"));
|
writer.writeAttribute(QStringLiteral("xmlns:dcmitype"), QStringLiteral("http://purl.org/dc/dcmitype/"));
|
||||||
writer.writeAttribute(QStringLiteral("xmlns:xsi"), QStringLiteral("http://www.w3.org/2001/XMLSchema-instance"));
|
writer.writeAttribute(QStringLiteral("xmlns:xsi"), QStringLiteral("http://www.w3.org/2001/XMLSchema-instance"));
|
||||||
if (property("title").isValid())
|
|
||||||
writer.writeTextElement(QStringLiteral("dc:title"), property("title").toString());
|
|
||||||
if (property("subject").isValid())
|
|
||||||
writer.writeTextElement(QStringLiteral("dc:subject"), property("subject").toString());
|
|
||||||
writer.writeTextElement(QStringLiteral("dc:creator"), property("creator").isValid() ? property("creator").toString() : QStringLiteral("Qt Xlsx Library"));
|
|
||||||
|
|
||||||
if (property("keywords").isValid())
|
if (m_properties.contains(QStringLiteral("title")))
|
||||||
writer.writeTextElement(QStringLiteral("cp:keywords"), property("keywords").toString());
|
writer.writeTextElement(QStringLiteral("dc:title"), m_properties[QStringLiteral("title")]);
|
||||||
if (property("description").isValid())
|
|
||||||
writer.writeTextElement(QStringLiteral("dc:description"), property("description").toString());
|
if (m_properties.contains(QStringLiteral("subject")))
|
||||||
writer.writeTextElement(QStringLiteral("cp:lastModifiedBy"), property("creator").isValid() ? property("creator").toString() : QStringLiteral("Qt Xlsx Library"));
|
writer.writeTextElement(QStringLiteral("dc:subject"), m_properties[QStringLiteral("subject")]);
|
||||||
|
|
||||||
|
writer.writeTextElement(QStringLiteral("dc:creator"), m_properties.contains(QStringLiteral("creator")) ? m_properties[QStringLiteral("creator")] : QStringLiteral("Qt Xlsx Library"));
|
||||||
|
|
||||||
|
if (m_properties.contains(QStringLiteral("keywords")))
|
||||||
|
writer.writeTextElement(QStringLiteral("cp:keywords"), m_properties[QStringLiteral("keywords")]);
|
||||||
|
|
||||||
|
if (m_properties.contains(QStringLiteral("description")))
|
||||||
|
writer.writeTextElement(QStringLiteral("dc:description"), m_properties[QStringLiteral("description")]);
|
||||||
|
|
||||||
|
writer.writeTextElement(QStringLiteral("cp:lastModifiedBy"), m_properties.contains(QStringLiteral("creator")) ? m_properties[QStringLiteral("creator")] : QStringLiteral("Qt Xlsx Library"));
|
||||||
|
|
||||||
writer.writeStartElement(QStringLiteral("dcterms:created"));
|
writer.writeStartElement(QStringLiteral("dcterms:created"));
|
||||||
writer.writeAttribute(QStringLiteral("xsi:type"), QStringLiteral("dcterms:W3CDTF"));
|
writer.writeAttribute(QStringLiteral("xsi:type"), QStringLiteral("dcterms:W3CDTF"));
|
||||||
writer.writeCharacters(QDateTime::currentDateTime().toString(Qt::ISODate));
|
writer.writeCharacters(m_properties.contains(QStringLiteral("created")) ? m_properties[QStringLiteral("created")] : QDateTime::currentDateTime().toString(Qt::ISODate));
|
||||||
writer.writeEndElement();//dcterms:created
|
writer.writeEndElement();//dcterms:created
|
||||||
|
|
||||||
writer.writeStartElement(QStringLiteral("dcterms:modified"));
|
writer.writeStartElement(QStringLiteral("dcterms:modified"));
|
||||||
@@ -69,12 +110,71 @@ void DocPropsCore::saveToXmlFile(QIODevice *device)
|
|||||||
writer.writeCharacters(QDateTime::currentDateTime().toString(Qt::ISODate));
|
writer.writeCharacters(QDateTime::currentDateTime().toString(Qt::ISODate));
|
||||||
writer.writeEndElement();//dcterms:created
|
writer.writeEndElement();//dcterms:created
|
||||||
|
|
||||||
if (property("category").isValid())
|
if (m_properties.contains(QStringLiteral("category")))
|
||||||
writer.writeTextElement(QStringLiteral("cp:category"), property("category").toString());
|
writer.writeTextElement(QStringLiteral("cp:category"), m_properties[QStringLiteral("category")]);
|
||||||
if (property("status").isValid())
|
|
||||||
writer.writeTextElement(QStringLiteral("cp:contentStatus"), property("status").toString());
|
if (m_properties.contains(QStringLiteral("status")))
|
||||||
|
writer.writeTextElement(QStringLiteral("cp:contentStatus"), m_properties[QStringLiteral("status")]);
|
||||||
|
|
||||||
writer.writeEndElement(); //cp:coreProperties
|
writer.writeEndElement(); //cp:coreProperties
|
||||||
writer.writeEndDocument();
|
writer.writeEndDocument();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray DocPropsCore::saveToXmlData()
|
||||||
|
{
|
||||||
|
QByteArray data;
|
||||||
|
QBuffer buffer(&data);
|
||||||
|
buffer.open(QIODevice::WriteOnly);
|
||||||
|
saveToXmlFile(&buffer);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
DocPropsCore DocPropsCore::loadFromXmlFile(QIODevice *device)
|
||||||
|
{
|
||||||
|
DocPropsCore props;
|
||||||
|
XmlStreamReader reader(device);
|
||||||
|
while(!reader.atEnd()) {
|
||||||
|
QXmlStreamReader::TokenType token = reader.readNext();
|
||||||
|
if (token == QXmlStreamReader::StartElement) {
|
||||||
|
if (reader.qualifiedName() == QLatin1String("cp:coreProperties"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
QString text = reader.readElementText();
|
||||||
|
if (reader.qualifiedName() == QStringLiteral("dc:subject")) {
|
||||||
|
props.setProperty(QStringLiteral("subject"), text);
|
||||||
|
} else if (reader.qualifiedName() == QStringLiteral("dc:title")) {
|
||||||
|
props.setProperty(QStringLiteral("title"), text);
|
||||||
|
} else if (reader.qualifiedName() == QStringLiteral("dc:creator")) {
|
||||||
|
props.setProperty(QStringLiteral("creator"), text);
|
||||||
|
} else if (reader.qualifiedName() == QStringLiteral("dc:description")) {
|
||||||
|
props.setProperty(QStringLiteral("description"), text);
|
||||||
|
} else if (reader.qualifiedName() == QStringLiteral("cp:keywords")) {
|
||||||
|
props.setProperty(QStringLiteral("keywords"), text);
|
||||||
|
} else if (reader.qualifiedName() == QStringLiteral("dcterms:created")) {
|
||||||
|
props.setProperty(QStringLiteral("created"), text);
|
||||||
|
} else if (reader.qualifiedName() == QStringLiteral("cp:category")) {
|
||||||
|
props.setProperty(QStringLiteral("category"), text);
|
||||||
|
} else if (reader.qualifiedName() == QStringLiteral("cp:contentStatus")) {
|
||||||
|
props.setProperty(QStringLiteral("status"), text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reader.hasError()) {
|
||||||
|
qDebug()<<"Error when read doc props core file.";
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
|
DocPropsCore DocPropsCore::loadFromXmlData(const QByteArray &data)
|
||||||
|
{
|
||||||
|
QBuffer buffer;
|
||||||
|
buffer.setData(data);
|
||||||
|
buffer.open(QIODevice::ReadOnly);
|
||||||
|
return loadFromXmlFile(&buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} //namespace
|
} //namespace
|
||||||
|
|||||||
@@ -26,22 +26,29 @@
|
|||||||
#define XLSXDOCPROPSCORE_H
|
#define XLSXDOCPROPSCORE_H
|
||||||
|
|
||||||
#include "xlsxglobal.h"
|
#include "xlsxglobal.h"
|
||||||
#include <QObject>
|
#include <QMap>
|
||||||
#include <QList>
|
|
||||||
#include <QPair>
|
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
|
||||||
class QIODevice;
|
class QIODevice;
|
||||||
|
|
||||||
namespace QXlsx {
|
namespace QXlsx {
|
||||||
|
|
||||||
class XLSX_AUTOTEST_EXPORT DocPropsCore : public QObject
|
class XLSX_AUTOTEST_EXPORT DocPropsCore
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
explicit DocPropsCore(QObject *parent = 0);
|
explicit DocPropsCore();
|
||||||
|
|
||||||
|
bool setProperty(const QString &name, const QString &value);
|
||||||
|
QString property(const QString &name) const;
|
||||||
|
QStringList propertyNames() const;
|
||||||
|
|
||||||
void saveToXmlFile(QIODevice *device);
|
void saveToXmlFile(QIODevice *device);
|
||||||
|
QByteArray saveToXmlData();
|
||||||
|
static DocPropsCore loadFromXmlFile(QIODevice *device);
|
||||||
|
static DocPropsCore loadFromXmlData(const QByteArray &data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QMap<QString, QString> m_properties;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ void DocumentPrivate::init()
|
|||||||
|
|
||||||
bool DocumentPrivate::loadPackage(QIODevice *device)
|
bool DocumentPrivate::loadPackage(QIODevice *device)
|
||||||
{
|
{
|
||||||
return false;
|
Q_Q(Document);
|
||||||
|
Package package(q);
|
||||||
|
return package.parsePackage(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+45
-45
@@ -95,25 +95,48 @@ bool Package::parsePackage(QIODevice *packageDevice)
|
|||||||
ZipReader zipReader(packageDevice);
|
ZipReader zipReader(packageDevice);
|
||||||
QStringList filePaths = zipReader.filePaths();
|
QStringList filePaths = zipReader.filePaths();
|
||||||
|
|
||||||
if (!filePaths.contains(QLatin1String("_rels/.rel")))
|
if (!filePaths.contains(QLatin1String("_rels/.rels")))
|
||||||
return false;
|
return false;
|
||||||
Relationships rootRels = readRelsFile(zipReader, QStringLiteral("_rels/.rel"));
|
|
||||||
|
|
||||||
|
Relationships rootRels = Relationships::loadFromXmlData(zipReader.fileData(QStringLiteral("_rels/.rels")));
|
||||||
|
|
||||||
|
//load core property
|
||||||
|
QList<XlsxRelationship> rels_core = rootRels.packageRelationships(QStringLiteral("/metadata/core-properties"));
|
||||||
|
if (!rels_core.isEmpty()) {
|
||||||
|
//Get the core property file name if it exists.
|
||||||
|
//In normal case, this should be "docProps/core.xml"
|
||||||
|
QString docPropsCore_Name = rels_core[0].target;
|
||||||
|
|
||||||
|
DocPropsCore props = DocPropsCore::loadFromXmlData(zipReader.fileData(docPropsCore_Name));
|
||||||
|
foreach (QString name, props.propertyNames())
|
||||||
|
m_document->setDocumentProperty(name, props.property(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
//load app property
|
||||||
|
QList<XlsxRelationship> rels_app = rootRels.documentRelationships(QStringLiteral("/extended-properties"));
|
||||||
|
if (!rels_app.isEmpty()) {
|
||||||
|
//Get the app property file name if it exists.
|
||||||
|
//In normal case, this should be "docProps/app.xml"
|
||||||
|
QString docPropsApp_Name = rels_app[0].target;
|
||||||
|
|
||||||
|
DocPropsApp props = DocPropsApp::loadFromXmlData(zipReader.fileData(docPropsApp_Name));
|
||||||
|
foreach (QString name, props.propertyNames())
|
||||||
|
m_document->setDocumentProperty(name, props.property(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
//load workbook now
|
||||||
|
QList<XlsxRelationship> rels_xl = rootRels.documentRelationships(QStringLiteral("/officeDocument"));
|
||||||
|
if (!rels_xl.isEmpty()) {
|
||||||
|
//Get the app property file name if it exists.
|
||||||
|
//In normal case, this should be "xl/workbook.xml"
|
||||||
|
QString xlworkbook_Name = rels_xl[0].target;
|
||||||
|
|
||||||
|
//ToDo: Read the workbook here!
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Relationships Package::readRelsFile(ZipReader &zipReader, const QString &filePath)
|
|
||||||
{
|
|
||||||
QByteArray relsData = zipReader.fileData(filePath);
|
|
||||||
QBuffer buffer(&relsData);
|
|
||||||
buffer.open(QIODevice::ReadOnly);
|
|
||||||
|
|
||||||
Relationships rels;
|
|
||||||
rels.loadFromXmlFile(&buffer);
|
|
||||||
return rels;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Package::createPackage(QIODevice *package)
|
bool Package::createPackage(QIODevice *package)
|
||||||
{
|
{
|
||||||
ZipWriter zipWriter(package);
|
ZipWriter zipWriter(package);
|
||||||
@@ -226,7 +249,7 @@ void Package::writeDocPropsAppFile(ZipWriter &zipWriter)
|
|||||||
DocPropsApp props;
|
DocPropsApp props;
|
||||||
|
|
||||||
foreach (QString name, m_document->documentPropertyNames())
|
foreach (QString name, m_document->documentPropertyNames())
|
||||||
props.setProperty(name.toUtf8().data(), m_document->documentProperty(name));
|
props.setProperty(name, m_document->documentProperty(name));
|
||||||
|
|
||||||
if (m_worksheet_count)
|
if (m_worksheet_count)
|
||||||
props.addHeadingPair(QStringLiteral("Worksheets"), m_worksheet_count);
|
props.addHeadingPair(QStringLiteral("Worksheets"), m_worksheet_count);
|
||||||
@@ -245,11 +268,7 @@ void Package::writeDocPropsAppFile(ZipWriter &zipWriter)
|
|||||||
props.addPartTitle(sheet->name());
|
props.addPartTitle(sheet->name());
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray data;
|
zipWriter.addFile(QStringLiteral("docProps/app.xml"), props.saveToXmlData());
|
||||||
QBuffer buffer(&data);
|
|
||||||
buffer.open(QIODevice::WriteOnly);
|
|
||||||
props.saveToXmlFile(&buffer);
|
|
||||||
zipWriter.addFile(QStringLiteral("docProps/app.xml"), data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Package::writeDocPropsCoreFile(ZipWriter &zipWriter)
|
void Package::writeDocPropsCoreFile(ZipWriter &zipWriter)
|
||||||
@@ -257,13 +276,9 @@ void Package::writeDocPropsCoreFile(ZipWriter &zipWriter)
|
|||||||
DocPropsCore props;
|
DocPropsCore props;
|
||||||
|
|
||||||
foreach (QString name, m_document->documentPropertyNames())
|
foreach (QString name, m_document->documentPropertyNames())
|
||||||
props.setProperty(name.toUtf8().data(), m_document->documentProperty(name));
|
props.setProperty(name, m_document->documentProperty(name));
|
||||||
|
|
||||||
QByteArray data;
|
zipWriter.addFile(QStringLiteral("docProps/core.xml"), props.saveToXmlData());
|
||||||
QBuffer buffer(&data);
|
|
||||||
buffer.open(QIODevice::WriteOnly);
|
|
||||||
props.saveToXmlFile(&buffer);
|
|
||||||
zipWriter.addFile(QStringLiteral("docProps/core.xml"), data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Package::writeSharedStringsFile(ZipWriter &zipWriter)
|
void Package::writeSharedStringsFile(ZipWriter &zipWriter)
|
||||||
@@ -300,11 +315,7 @@ void Package::writeRootRelsFile(ZipWriter &zipWriter)
|
|||||||
rels.addPackageRelationship(QStringLiteral("/metadata/core-properties"), QStringLiteral("docProps/core.xml"));
|
rels.addPackageRelationship(QStringLiteral("/metadata/core-properties"), QStringLiteral("docProps/core.xml"));
|
||||||
rels.addDocumentRelationship(QStringLiteral("/extended-properties"), QStringLiteral("docProps/app.xml"));
|
rels.addDocumentRelationship(QStringLiteral("/extended-properties"), QStringLiteral("docProps/app.xml"));
|
||||||
|
|
||||||
QByteArray data;
|
zipWriter.addFile(QStringLiteral("_rels/.rels"), rels.saveToXmlData());
|
||||||
QBuffer buffer(&data);
|
|
||||||
buffer.open(QIODevice::WriteOnly);
|
|
||||||
rels.saveToXmlFile(&buffer);
|
|
||||||
zipWriter.addFile(QStringLiteral("_rels/.rels"), data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Package::writeWorkbookRelsFile(ZipWriter &zipWriter)
|
void Package::writeWorkbookRelsFile(ZipWriter &zipWriter)
|
||||||
@@ -329,11 +340,7 @@ void Package::writeWorkbookRelsFile(ZipWriter &zipWriter)
|
|||||||
if (m_workbook->sharedStrings()->count())
|
if (m_workbook->sharedStrings()->count())
|
||||||
rels.addDocumentRelationship(QStringLiteral("/sharedStrings"), QStringLiteral("sharedStrings.xml"));
|
rels.addDocumentRelationship(QStringLiteral("/sharedStrings"), QStringLiteral("sharedStrings.xml"));
|
||||||
|
|
||||||
QByteArray data;
|
zipWriter.addFile(QStringLiteral("xl/_rels/workbook.xml.rels"), rels.saveToXmlData());
|
||||||
QBuffer buffer(&data);
|
|
||||||
buffer.open(QIODevice::WriteOnly);
|
|
||||||
rels.saveToXmlFile(&buffer);
|
|
||||||
zipWriter.addFile(QStringLiteral("xl/_rels/workbook.xml.rels"), data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Package::writeWorksheetRelsFiles(ZipWriter &zipWriter)
|
void Package::writeWorksheetRelsFiles(ZipWriter &zipWriter)
|
||||||
@@ -348,11 +355,8 @@ void Package::writeWorksheetRelsFiles(ZipWriter &zipWriter)
|
|||||||
rels.addWorksheetRelationship(QStringLiteral("/hyperlink"), link, QStringLiteral("External"));
|
rels.addWorksheetRelationship(QStringLiteral("/hyperlink"), link, QStringLiteral("External"));
|
||||||
foreach (QString link, sheet->externDrawingList())
|
foreach (QString link, sheet->externDrawingList())
|
||||||
rels.addWorksheetRelationship(QStringLiteral("/drawing"), link);
|
rels.addWorksheetRelationship(QStringLiteral("/drawing"), link);
|
||||||
QByteArray data;
|
|
||||||
QBuffer buffer(&data);
|
zipWriter.addFile(QStringLiteral("xl/worksheets/_rels/sheet%1.xml.rels").arg(index), rels.saveToXmlData());
|
||||||
buffer.open(QIODevice::WriteOnly);
|
|
||||||
rels.saveToXmlFile(&buffer);
|
|
||||||
zipWriter.addFile(QStringLiteral("xl/worksheets/_rels/sheet%1.xml.rels").arg(index), data);
|
|
||||||
index += 1;
|
index += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -369,11 +373,7 @@ void Package::writeDrawingRelsFiles(ZipWriter &zipWriter)
|
|||||||
foreach (PairType pair, sheet->drawingLinks())
|
foreach (PairType pair, sheet->drawingLinks())
|
||||||
rels.addDocumentRelationship(pair.first, pair.second);
|
rels.addDocumentRelationship(pair.first, pair.second);
|
||||||
|
|
||||||
QByteArray data;
|
zipWriter.addFile(QStringLiteral("xl/drawings/_rels/drawing%1.xml.rels").arg(index), rels.saveToXmlData());
|
||||||
QBuffer buffer(&data);
|
|
||||||
buffer.open(QIODevice::WriteOnly);
|
|
||||||
rels.saveToXmlFile(&buffer);
|
|
||||||
zipWriter.addFile(QStringLiteral("xl/drawings/_rels/drawing%1.xml.rels").arg(index), data);
|
|
||||||
index += 1;
|
index += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ class ZipWriter;
|
|||||||
class ZipReader;
|
class ZipReader;
|
||||||
class Document;
|
class Document;
|
||||||
class Relationships;
|
class Relationships;
|
||||||
|
class DocPropsCore;
|
||||||
|
class DocPropsApp;
|
||||||
|
|
||||||
class XLSX_AUTOTEST_EXPORT Package
|
class XLSX_AUTOTEST_EXPORT Package
|
||||||
{
|
{
|
||||||
@@ -46,7 +48,6 @@ public:
|
|||||||
bool createPackage(QIODevice *package);
|
bool createPackage(QIODevice *package);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Relationships readRelsFile(ZipReader &reader, const QString &filePath);
|
|
||||||
|
|
||||||
void writeWorksheetFiles(ZipWriter &zipWriter);
|
void writeWorksheetFiles(ZipWriter &zipWriter);
|
||||||
// void writeChartsheetFiles(ZipWriter &zipWriter);
|
// void writeChartsheetFiles(ZipWriter &zipWriter);
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include "xlsxxmlreader_p.h"
|
#include "xlsxxmlreader_p.h"
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include <QBuffer>
|
||||||
|
|
||||||
namespace QXlsx {
|
namespace QXlsx {
|
||||||
|
|
||||||
@@ -119,9 +120,20 @@ void Relationships::saveToXmlFile(QIODevice *device)
|
|||||||
writer.writeEndDocument();
|
writer.writeEndDocument();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Relationships::loadFromXmlFile(QIODevice *device)
|
QByteArray Relationships::saveToXmlData()
|
||||||
{
|
{
|
||||||
m_relationships.clear();
|
QByteArray data;
|
||||||
|
QBuffer buffer(&data);
|
||||||
|
buffer.open(QIODevice::WriteOnly);
|
||||||
|
saveToXmlFile(&buffer);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
Relationships Relationships::loadFromXmlFile(QIODevice *device)
|
||||||
|
{
|
||||||
|
Relationships rels;
|
||||||
|
|
||||||
XmlStreamReader reader(device);
|
XmlStreamReader reader(device);
|
||||||
while(!reader.atEnd()) {
|
while(!reader.atEnd()) {
|
||||||
QXmlStreamReader::TokenType token = reader.readNext();
|
QXmlStreamReader::TokenType token = reader.readNext();
|
||||||
@@ -133,7 +145,7 @@ void Relationships::loadFromXmlFile(QIODevice *device)
|
|||||||
relationship.type = attributes.value(QLatin1String("Type")).toString();
|
relationship.type = attributes.value(QLatin1String("Type")).toString();
|
||||||
relationship.target = attributes.value(QLatin1String("Target")).toString();
|
relationship.target = attributes.value(QLatin1String("Target")).toString();
|
||||||
relationship.targetMode = attributes.value(QLatin1String("TargetMode")).toString();
|
relationship.targetMode = attributes.value(QLatin1String("TargetMode")).toString();
|
||||||
m_relationships.append(relationship);
|
rels.m_relationships.append(relationship);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,6 +153,15 @@ void Relationships::loadFromXmlFile(QIODevice *device)
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return rels;
|
||||||
|
}
|
||||||
|
|
||||||
|
Relationships Relationships::loadFromXmlData(const QByteArray &data)
|
||||||
|
{
|
||||||
|
QBuffer buffer;
|
||||||
|
buffer.setData(data);
|
||||||
|
buffer.open(QIODevice::ReadOnly);
|
||||||
|
return loadFromXmlFile(&buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
} //namespace
|
} //namespace
|
||||||
|
|||||||
@@ -56,7 +56,9 @@ public:
|
|||||||
void addWorksheetRelationship(const QString &relativeType, const QString &target, const QString &targetMode=QString());
|
void addWorksheetRelationship(const QString &relativeType, const QString &target, const QString &targetMode=QString());
|
||||||
|
|
||||||
void saveToXmlFile(QIODevice *device);
|
void saveToXmlFile(QIODevice *device);
|
||||||
void loadFromXmlFile(QIODevice *device);
|
QByteArray saveToXmlData();
|
||||||
|
static Relationships loadFromXmlFile(QIODevice *device);
|
||||||
|
static Relationships loadFromXmlData(const QByteArray &data);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<XlsxRelationship> relationships(const QString &type) const;
|
QList<XlsxRelationship> relationships(const QString &type) const;
|
||||||
|
|||||||
+4
-1
@@ -3,4 +3,7 @@ SUBDIRS=\
|
|||||||
utility \
|
utility \
|
||||||
mergecell \
|
mergecell \
|
||||||
zipreader \
|
zipreader \
|
||||||
relationships
|
relationships \
|
||||||
|
propscore \
|
||||||
|
propsapp \
|
||||||
|
readdocument
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
QT += testlib xlsx xlsx-private
|
||||||
|
CONFIG += testcase
|
||||||
|
DEFINES += XLSX_TEST
|
||||||
|
|
||||||
|
TARGET = tst_docpropsapptest
|
||||||
|
CONFIG += console
|
||||||
|
CONFIG -= app_bundle
|
||||||
|
|
||||||
|
TEMPLATE = app
|
||||||
|
|
||||||
|
|
||||||
|
SOURCES += tst_docpropsapptest.cpp
|
||||||
|
DEFINES += SRCDIR=\\\"$$PWD/\\\"
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#include "private/xlsxdocpropsapp_p.h"
|
||||||
|
#include <QString>
|
||||||
|
#include <QtTest>
|
||||||
|
|
||||||
|
class DocPropsAppTest : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
DocPropsAppTest();
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void testCase1();
|
||||||
|
};
|
||||||
|
|
||||||
|
DocPropsAppTest::DocPropsAppTest()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void DocPropsAppTest::testCase1()
|
||||||
|
{
|
||||||
|
QXlsx::DocPropsApp props;
|
||||||
|
|
||||||
|
props.setProperty("company", "HMI CN");
|
||||||
|
props.setProperty("manager", "Debao");
|
||||||
|
|
||||||
|
QFile f1("temp.xml");
|
||||||
|
f1.open(QFile::WriteOnly);
|
||||||
|
props.saveToXmlFile(&f1);
|
||||||
|
f1.close();
|
||||||
|
|
||||||
|
f1.open(QFile::ReadOnly);
|
||||||
|
QXlsx::DocPropsApp props2 = QXlsx::DocPropsApp::loadFromXmlFile(&f1);
|
||||||
|
|
||||||
|
QCOMPARE(props2.property("company"), QString("HMI CN"));
|
||||||
|
QCOMPARE(props2.property("manager"), QString("Debao"));
|
||||||
|
QFile::remove("temp.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
QTEST_APPLESS_MAIN(DocPropsAppTest)
|
||||||
|
|
||||||
|
#include "tst_docpropsapptest.moc"
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
QT += testlib xlsx xlsx-private
|
||||||
|
CONFIG += testcase
|
||||||
|
DEFINES += XLSX_TEST
|
||||||
|
|
||||||
|
TARGET = tst_propscoretest
|
||||||
|
CONFIG += console
|
||||||
|
CONFIG -= app_bundle
|
||||||
|
|
||||||
|
TEMPLATE = app
|
||||||
|
|
||||||
|
|
||||||
|
SOURCES += tst_propscoretest.cpp
|
||||||
|
DEFINES += SRCDIR=\\\"$$PWD/\\\"
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
#include "private/xlsxdocpropscore_p.h"
|
||||||
|
#include <QString>
|
||||||
|
#include <QtTest>
|
||||||
|
#include <QFile>
|
||||||
|
|
||||||
|
class DocPropsCoreTest : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
DocPropsCoreTest();
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void testCase1();
|
||||||
|
};
|
||||||
|
|
||||||
|
DocPropsCoreTest::DocPropsCoreTest()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void DocPropsCoreTest::testCase1()
|
||||||
|
{
|
||||||
|
QXlsx::DocPropsCore props;
|
||||||
|
|
||||||
|
props.setProperty("creator", "Debao");
|
||||||
|
props.setProperty("keywords", "Test, test, TEST");
|
||||||
|
props.setProperty("title", "ABC");
|
||||||
|
|
||||||
|
QFile f1("temp.xml");
|
||||||
|
f1.open(QFile::WriteOnly);
|
||||||
|
props.saveToXmlFile(&f1);
|
||||||
|
f1.close();
|
||||||
|
|
||||||
|
f1.open(QFile::ReadOnly);
|
||||||
|
QXlsx::DocPropsCore props2 = QXlsx::DocPropsCore::loadFromXmlFile(&f1);
|
||||||
|
|
||||||
|
QCOMPARE(props2.property("creator"), QString("Debao"));
|
||||||
|
QCOMPARE(props2.property("keywords"), QString("Test, test, TEST"));
|
||||||
|
QCOMPARE(props2.property("title"), QString("ABC"));
|
||||||
|
QFile::remove("temp.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
QTEST_APPLESS_MAIN(DocPropsCoreTest)
|
||||||
|
|
||||||
|
#include "tst_propscoretest.moc"
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
QT += testlib xlsx xlsx-private
|
||||||
|
CONFIG += testcase
|
||||||
|
DEFINES += XLSX_TEST
|
||||||
|
|
||||||
|
TARGET = tst_readdocumenttest
|
||||||
|
CONFIG += console
|
||||||
|
CONFIG -= app_bundle
|
||||||
|
|
||||||
|
TEMPLATE = app
|
||||||
|
|
||||||
|
|
||||||
|
SOURCES += tst_readdocumenttest.cpp
|
||||||
|
DEFINES += SRCDIR=\\\"$$PWD/\\\"
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#include "xlsxdocument.h"
|
||||||
|
#include <QString>
|
||||||
|
#include <QtTest>
|
||||||
|
|
||||||
|
class ReadDocumentTest : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
ReadDocumentTest();
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void testDocProps();
|
||||||
|
};
|
||||||
|
|
||||||
|
ReadDocumentTest::ReadDocumentTest()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReadDocumentTest::testDocProps()
|
||||||
|
{
|
||||||
|
QXlsx::Document doc1;
|
||||||
|
doc1.setDocumentProperty("creator", "Debao");
|
||||||
|
doc1.setDocumentProperty("company", "Test");
|
||||||
|
doc1.saveAs("test.xlsx");
|
||||||
|
|
||||||
|
QXlsx::Document doc2("test.xlsx");
|
||||||
|
QCOMPARE(doc2.documentProperty("creator"), QString("Debao"));
|
||||||
|
QCOMPARE(doc2.documentProperty("company"), QString("Test"));
|
||||||
|
|
||||||
|
QFile::remove("test.xlsx");
|
||||||
|
}
|
||||||
|
|
||||||
|
QTEST_APPLESS_MAIN(ReadDocumentTest)
|
||||||
|
|
||||||
|
#include "tst_readdocumenttest.moc"
|
||||||
Reference in New Issue
Block a user