We can read and modify existing simple .xlsx file now

This commit is contained in:
Debao Zhang
2013-10-19 13:28:06 +08:00
parent 7f218898b6
commit d04a02e55c
16 changed files with 135 additions and 33 deletions
+1
View File
@@ -110,5 +110,6 @@
\li \l{Xlsx Hello Example}
\li \l{Xlsx Style Example}
\li \l{Xlsx DocProperties Example}
\li \l{Xlsx Readwrite Example}
\endlist
*/
+1
View File
@@ -28,6 +28,7 @@
#include "xlsxglobal.h"
#include <QObject>
#include <QVariant>
class QIODevice;
class QImage;
+53 -7
View File
@@ -25,6 +25,8 @@
#include "xlsxpackage_p.h"
#include "xlsxworkbook.h"
#include "xlsxworksheet.h"
#include "xlsxworkbook_p.h"
#include "xlsxutility_p.h"
#include "xlsxcontenttypes_p.h"
#include "xlsxsharedstrings_p.h"
#include "xlsxdocpropscore_p.h"
@@ -38,6 +40,8 @@
#include "xlsxdocument.h"
#include <QBuffer>
#include <QDebug>
#include <QDir>
#include <QFileInfo>
namespace QXlsx {
@@ -125,17 +129,59 @@ bool Package::parsePackage(QIODevice *packageDevice)
m_document->setDocumentProperty(name, props.property(name));
}
//load workbook now
//load workbook now, Get the workbook file path from the root rels file
//In normal case, this should be "xl/workbook.xml"
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;
if (rels_xl.isEmpty())
return false;
QString xlworkbook_Path = rels_xl[0].target;
QStringList xlworkbook_PathList = splitPath(xlworkbook_Path);
QString xlworkbook_Dir = xlworkbook_PathList[0];
QString xlworkbook_Name = xlworkbook_PathList[1];
QSharedPointer<Workbook> book = Workbook::loadFromXmlData(zipReader.fileData(xlworkbook_Path));
QList<QPair<QString, QString> > sheetNameIdPairList = book->d_func()->sheetNameIdPairList;
Relationships xlworkbook_Rels = Relationships::loadFromXmlData(
zipReader.fileData(xlworkbook_Dir+QStringLiteral("/_rels/")+xlworkbook_Name+QStringLiteral(".rels")));
//ToDo: Read the workbook here!
//load styles
QList<XlsxRelationship> rels_styles = xlworkbook_Rels.documentRelationships(QStringLiteral("/styles"));
if (!rels_styles.isEmpty()) {
//In normal case this should be styles.xml which in xl
//:Todo
}
return false;
//load sharedStrings
QList<XlsxRelationship> rels_sharedStrings = xlworkbook_Rels.documentRelationships(QStringLiteral("/sharedStrings"));
if (!rels_sharedStrings.isEmpty()) {
//In normal case this should be sharedStrings.xml which in xl
QString name = rels_sharedStrings[0].target;
QString path = xlworkbook_Dir + QLatin1String("/") + name;
QSharedPointer<SharedStrings> sst= SharedStrings::loadFromXmlData(zipReader.fileData(path));
m_document->workbook()->d_ptr->sharedStrings = sst;
}
//load theme
QList<XlsxRelationship> rels_theme = xlworkbook_Rels.documentRelationships(QStringLiteral("/theme"));
if (!rels_theme.isEmpty()) {
//In normal case this should be theme/theme1.xml which in xl
//:Todo
}
//load worksheets
QList<XlsxRelationship> rels_worksheets = xlworkbook_Rels.documentRelationships(QStringLiteral("/worksheet"));
if (rels_worksheets.isEmpty())
return false;
for (int i=0; i<sheetNameIdPairList.size(); ++i) {
QPair<QString, QString> pair = sheetNameIdPairList[i];
QString worksheet_rId = pair.second;
QString name = xlworkbook_Rels.getRelationshipById(worksheet_rId).target;
QString worksheet_path = xlworkbook_Dir + QLatin1String("/") + name;
Worksheet *sheet = m_document->workbook()->addWorksheet(pair.first);
sheet->loadFromXmlData(zipReader.fileData(worksheet_path));
}
return true;
}
bool Package::createPackage(QIODevice *package)
+5
View File
@@ -59,6 +59,11 @@ int SharedStrings::addSharedString(const QString &string)
return index;
}
void SharedStrings::incRefByStringIndex(int idx)
{
addSharedString(m_stringList[idx]);
}
void SharedStrings::removeSharedString(const QString &string)
{
if (!m_stringTable.contains(string))
+1
View File
@@ -54,6 +54,7 @@ public:
int addSharedString(const QString &string);
void removeSharedString(const QString &string);
void incRefByStringIndex(int idx);
int getSharedStringIndex(const QString &string) const;
QString getSharedString(int index) const;
+10
View File
@@ -28,6 +28,7 @@
#include <QPoint>
#include <QRegularExpression>
#include <QMap>
#include <QStringList>
namespace QXlsx {
@@ -41,6 +42,15 @@ int intPow(int x, int p)
else return x * tmp * tmp;
}
QStringList splitPath(const QString &path)
{
int idx = path.lastIndexOf(QLatin1Char('/'));
if (idx == -1)
return QStringList()<<QStringLiteral(".")<<path;
return QStringList()<<path.left(idx)<<path.mid(idx+1);
}
QPoint xl_cell_to_rowcol(const QString &cell_str)
{
if (cell_str.isEmpty())
+4
View File
@@ -28,13 +28,17 @@
#include "xlsxglobal.h"
class QPoint;
class QString;
class QStringList;
namespace QXlsx {
XLSX_AUTOTEST_EXPORT int intPow(int x, int p);
XLSX_AUTOTEST_EXPORT QStringList splitPath(const QString &path);
XLSX_AUTOTEST_EXPORT QPoint xl_cell_to_rowcol(const QString &cell_str);
XLSX_AUTOTEST_EXPORT QString xl_col_to_name(int col_num);
XLSX_AUTOTEST_EXPORT QString xl_rowcol_to_cell(int row, int col, bool row_abs=false, bool col_abs=false);
XLSX_AUTOTEST_EXPORT QString xl_rowcol_to_cell_fast(int row, int col);
} //QXlsx
#endif // XLSXUTILITY_H
-8
View File
@@ -337,12 +337,4 @@ QSharedPointer<Workbook> Workbook::loadFromXmlData(const QByteArray &data)
return loadFromXmlFile(&buffer);
}
void Workbook::addWorksheet(const QString &name, QSharedPointer<Worksheet> sheet)
{
Q_D(Workbook);
sheet->setSheetName(name);
d->worksheets.append(sheet);
}
QT_END_NAMESPACE_XLSX
-1
View File
@@ -78,7 +78,6 @@ private:
QByteArray saveToXmlData();
static QSharedPointer<Workbook> loadFromXmlFile(QIODevice *device);
static QSharedPointer<Workbook> loadFromXmlData(const QByteArray &data);
void addWorksheet(const QString &name, QSharedPointer<Worksheet> sheet);
SharedStrings *sharedStrings();
Styles *styles();
+15 -14
View File
@@ -1074,9 +1074,9 @@ QByteArray Worksheet::saveToXmlData()
return data;
}
QSharedPointer<Worksheet> Worksheet::loadFromXmlFile(QIODevice *device)
bool Worksheet::loadFromXmlFile(QIODevice *device)
{
Worksheet *sheet = new Worksheet(QStringLiteral("Sheet9999"));
Q_D(Worksheet);
XmlStreamReader reader(device);
while(!reader.atEnd()) {
@@ -1088,16 +1088,16 @@ QSharedPointer<Worksheet> Worksheet::loadFromXmlFile(QIODevice *device)
if (range.size() == 2) {
QPoint start = xl_cell_to_rowcol(range[0]);
QPoint end = xl_cell_to_rowcol(range[1]);
sheet->d_func()->dim_rowmin = start.x();
sheet->d_func()->dim_colmin = start.y();
sheet->d_func()->dim_rowmax = end.x();
sheet->d_func()->dim_colmax = end.y();
d->dim_rowmin = start.x();
d->dim_colmin = start.y();
d->dim_rowmax = end.x();
d->dim_colmax = end.y();
} else {
QPoint p = xl_cell_to_rowcol(range[0]);
sheet->d_func()->dim_rowmin = p.x();
sheet->d_func()->dim_colmin = p.y();
sheet->d_func()->dim_rowmax = p.x();
sheet->d_func()->dim_colmax = p.y();
d->dim_rowmin = p.x();
d->dim_colmin = p.y();
d->dim_rowmax = p.x();
d->dim_colmax = p.y();
}
} else if (reader.name() == QLatin1String("c")) {
QXmlStreamAttributes attributes = reader.attributes();
@@ -1111,8 +1111,9 @@ QSharedPointer<Worksheet> Worksheet::loadFromXmlFile(QIODevice *device)
reader.readNextStartElement();
if (reader.name() == QLatin1String("v")) {
QString value = reader.readElementText();
d->workbook->sharedStrings()->incRefByStringIndex(value.toInt());
XlsxCellData *data = new XlsxCellData(value ,XlsxCellData::String);
sheet->d_func()->cellTable[pos.x()][pos.y()] = QSharedPointer<XlsxCellData>(data);
d->cellTable[pos.x()][pos.y()] = QSharedPointer<XlsxCellData>(data);
}
}
} else {
@@ -1121,17 +1122,17 @@ QSharedPointer<Worksheet> Worksheet::loadFromXmlFile(QIODevice *device)
if (reader.name() == QLatin1String("v")) {
QString value = reader.readElementText();
XlsxCellData *data = new XlsxCellData(value ,XlsxCellData::Number);
sheet->d_func()->cellTable[pos.x()][pos.y()] = QSharedPointer<XlsxCellData>(data);
d->cellTable[pos.x()][pos.y()] = QSharedPointer<XlsxCellData>(data);
}
}
}
}
}
return QSharedPointer<Worksheet> (sheet);
return true;
}
QSharedPointer<Worksheet> Worksheet::loadFromXmlData(const QByteArray &data)
bool Worksheet::loadFromXmlData(const QByteArray &data)
{
QBuffer buffer;
buffer.setData(data);
+2 -2
View File
@@ -74,8 +74,8 @@ public:
void saveToXmlFile(QIODevice *device);
QByteArray saveToXmlData();
static QSharedPointer<Worksheet> loadFromXmlFile(QIODevice *device);
static QSharedPointer<Worksheet> loadFromXmlData(const QByteArray &data);
bool loadFromXmlFile(QIODevice *device);
bool loadFromXmlData(const QByteArray &data);
~Worksheet();
private: