Browse Source

wip: Add read function for workbook

master
Debao Zhang 11 years ago
parent
commit
7748184ba1
  1. 2
      src/xlsx/xlsxdocument.cpp
  2. 21
      src/xlsx/xlsxpackage.cpp
  3. 9
      src/xlsx/xlsxrelationships.cpp
  4. 1
      src/xlsx/xlsxrelationships_p.h
  5. 47
      src/xlsx/xlsxworkbook.cpp
  6. 3
      src/xlsx/xlsxworkbook.h
  7. 5
      src/xlsx/xlsxworkbook_p.h
  8. 85
      src/xlsx/xlsxworksheet.cpp
  9. 3
      src/xlsx/xlsxworksheet.h
  10. 5
      src/xlsx/xlsxworksheet_p.h

2
src/xlsx/xlsxdocument.cpp

@ -168,7 +168,7 @@ Worksheet *Document::activedWorksheet() const
if (d->workbook->worksheets().size() == 0)
return 0;
return d->workbook->worksheets().at(d->workbook->activedWorksheet());
return d->workbook->worksheets().at(d->workbook->activedWorksheet()).data();
}
int Document::activedWorksheetIndex() const

21
src/xlsx/xlsxpackage.cpp

@ -75,6 +75,7 @@ namespace QXlsx {
The Packager class coordinates the classes that represent the
elements of the package and writes them into the XLSX file.
*/
typedef QSharedPointer<Worksheet> WorksheetPtrType;
Package::Package(Document *document) :
m_document(document)
@ -82,7 +83,7 @@ Package::Package(Document *document) :
m_workbook = m_document->workbook();
m_worksheet_count = 0;
m_chartsheet_count = 0;
foreach (Worksheet *sheet, m_workbook->worksheets()) {
foreach (WorksheetPtrType sheet, m_workbook->worksheets()) {
if (sheet->isChartsheet())
m_chartsheet_count += 1;
else
@ -174,7 +175,7 @@ bool Package::createPackage(QIODevice *package)
void Package::writeWorksheetFiles(ZipWriter &zipWriter)
{
int index = 1;
foreach (Worksheet *sheet, m_workbook->worksheets()) {
foreach (WorksheetPtrType sheet, m_workbook->worksheets()) {
if (sheet->isChartsheet())
continue;
@ -206,7 +207,7 @@ void Package::writeContentTypesFile(ZipWriter &zipWriter)
ContentTypes content;
int worksheet_index = 1;
foreach (Worksheet *sheet, m_workbook->worksheets()) {
foreach (WorksheetPtrType sheet, m_workbook->worksheets()) {
if (sheet->isChartsheet()) {
} else {
@ -247,15 +248,15 @@ void Package::writeDocPropsAppFile(ZipWriter &zipWriter)
props.addHeadingPair(QStringLiteral("Chartsheets"), m_chartsheet_count);
//Add worksheet parts
foreach (Worksheet *sheet, m_workbook->worksheets()){
foreach (WorksheetPtrType sheet, m_workbook->worksheets()){
if (!sheet->isChartsheet())
props.addPartTitle(sheet->name());
props.addPartTitle(sheet->sheetName());
}
//Add the chartsheet parts
foreach (Worksheet *sheet, m_workbook->worksheets()){
foreach (WorksheetPtrType sheet, m_workbook->worksheets()){
if (sheet->isChartsheet())
props.addPartTitle(sheet->name());
props.addPartTitle(sheet->sheetName());
}
zipWriter.addFile(QStringLiteral("docProps/app.xml"), props.saveToXmlData());
@ -306,7 +307,7 @@ void Package::writeWorkbookRelsFile(ZipWriter &zipWriter)
int worksheet_index = 1;
int chartsheet_index = 1;
foreach (Worksheet *sheet, m_workbook->worksheets()) {
foreach (WorksheetPtrType sheet, m_workbook->worksheets()) {
if (sheet->isChartsheet()) {
rels.addDocumentRelationship(QStringLiteral("/chartsheet"), QStringLiteral("chartsheets/sheet%1.xml").arg(chartsheet_index));
chartsheet_index += 1;
@ -328,7 +329,7 @@ void Package::writeWorkbookRelsFile(ZipWriter &zipWriter)
void Package::writeWorksheetRelsFiles(ZipWriter &zipWriter)
{
int index = 1;
foreach (Worksheet *sheet, m_workbook->worksheets()) {
foreach (WorksheetPtrType sheet, m_workbook->worksheets()) {
if (sheet->isChartsheet())
continue;
Relationships rels;
@ -346,7 +347,7 @@ void Package::writeWorksheetRelsFiles(ZipWriter &zipWriter)
void Package::writeDrawingRelsFiles(ZipWriter &zipWriter)
{
int index = 1;
foreach (Worksheet *sheet, m_workbook->worksheets()) {
foreach (WorksheetPtrType sheet, m_workbook->worksheets()) {
if (sheet->drawingLinks().size() == 0)
continue;
Relationships rels;

9
src/xlsx/xlsxrelationships.cpp

@ -164,4 +164,13 @@ Relationships Relationships::loadFromXmlData(const QByteArray &data)
return loadFromXmlFile(&buffer);
}
XlsxRelationship Relationships::getRelationshipById(const QString &id) const
{
foreach (XlsxRelationship ship, m_relationships) {
if (ship.id == id)
return ship;
}
return XlsxRelationship();
}
} //namespace

1
src/xlsx/xlsxrelationships_p.h

@ -59,6 +59,7 @@ public:
QByteArray saveToXmlData();
static Relationships loadFromXmlFile(QIODevice *device);
static Relationships loadFromXmlData(const QByteArray &data);
XlsxRelationship getRelationshipById(const QString &id) const;
private:
QList<XlsxRelationship> relationships(const QString &type) const;

47
src/xlsx/xlsxworkbook.cpp

@ -30,6 +30,7 @@
#include "xlsxformat.h"
#include "xlsxpackage_p.h"
#include "xlsxxmlwriter_p.h"
#include "xlsxxmlreader_p.h"
#include "xlsxworksheet_p.h"
#include <QFile>
@ -63,7 +64,6 @@ Workbook::Workbook() :
Workbook::~Workbook()
{
qDeleteAll(d_ptr->worksheets);
delete d_ptr;
}
@ -123,9 +123,10 @@ Worksheet *Workbook::insertWorkSheet(int index, const QString &name)
QString worksheetName = name;
if (!name.isEmpty()) {
//If user given an already in-use name, we should not continue any more!
foreach (Worksheet *sheet, d->worksheets) {
if (sheet->name() == name)
for (int i=0; i<d->worksheets.size(); ++i) {
if (d->worksheets[i]->sheetName() == name) {
return 0;
}
}
} else {
bool exists;
@ -133,15 +134,15 @@ Worksheet *Workbook::insertWorkSheet(int index, const QString &name)
++lastIndex;
exists = false;
worksheetName = QStringLiteral("Sheet%1").arg(lastIndex+1);
foreach (Worksheet *sheet, d->worksheets) {
if (sheet->name() == worksheetName)
for (int i=0; i<d->worksheets.size(); ++i) {
if (d->worksheets[i]->sheetName() == worksheetName)
exists = true;
}
} while (exists);
}
Worksheet *sheet = new Worksheet(worksheetName, this);
d->worksheets.insert(index, sheet);
d->worksheets.insert(index, QSharedPointer<Worksheet>(sheet));
d->activesheet = index;
return sheet;
}
@ -168,7 +169,7 @@ Format *Workbook::createFormat()
return d->styles->createFormat();
}
QList<Worksheet *> Workbook::worksheets() const
QList<QSharedPointer<Worksheet> > Workbook::worksheets() const
{
Q_D(const Workbook);
return d->worksheets;
@ -206,7 +207,8 @@ void Workbook::prepareDrawings()
d->images.clear();
d->drawings.clear();
foreach (Worksheet *sheet, d->worksheets) {
for (int i=0; i<d->worksheets.size(); ++i) {
QSharedPointer<Worksheet> sheet = d->worksheets[i];
if (sheet->images().isEmpty()) //No drawing (such as Image, ...)
continue;
@ -262,9 +264,9 @@ void Workbook::saveToXmlFile(QIODevice *device)
writer.writeStartElement(QStringLiteral("sheets"));
for (int i=0; i<d->worksheets.size(); ++i) {
Worksheet *sheet = d->worksheets[i];
QSharedPointer<Worksheet> sheet = d->worksheets[i];
writer.writeEmptyElement(QStringLiteral("sheet"));
writer.writeAttribute(QStringLiteral("name"), sheet->name());
writer.writeAttribute(QStringLiteral("name"), sheet->sheetName());
writer.writeAttribute(QStringLiteral("sheetId"), QString::number(i+1));
if (sheet->isHidden())
writer.writeAttribute(QStringLiteral("state"), QStringLiteral("hidden"));
@ -295,8 +297,21 @@ QByteArray Workbook::saveToXmlData()
QSharedPointer<Workbook> Workbook::loadFromXmlFile(QIODevice *device)
{
return QSharedPointer<Workbook>(new Workbook);
Workbook *book = new Workbook;
XmlStreamReader reader(device);
while(!reader.atEnd()) {
QXmlStreamReader::TokenType token = reader.readNext();
if (token == QXmlStreamReader::StartElement) {
if (reader.name() == QLatin1String("sheet")) {
QXmlStreamAttributes attributes = reader.attributes();
QString sheetName = attributes.value(QLatin1String("name")).toString();
QString rId = attributes.value(QLatin1String("r:id")).toString();
book->d_func()->sheetNameIdPairList.append(QPair<QString, QString>(sheetName, rId));
}
}
}
return QSharedPointer<Workbook>(book);
}
QSharedPointer<Workbook> Workbook::loadFromXmlData(const QByteArray &data)
@ -308,4 +323,12 @@ 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);
}
} //namespace

3
src/xlsx/xlsxworkbook.h

@ -50,7 +50,7 @@ class Q_XLSX_EXPORT Workbook
public:
~Workbook();
QList<Worksheet *> worksheets() const;
QList<QSharedPointer<Worksheet> > worksheets() const;
Worksheet *addWorksheet(const QString &name = QString());
Worksheet *insertWorkSheet(int index, const QString &name = QString());
int activedWorksheet() const;
@ -76,6 +76,7 @@ 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();

5
src/xlsx/xlsxworkbook_p.h

@ -26,6 +26,7 @@
#define XLSXWORKBOOK_P_H
#include "xlsxworkbook.h"
#include <QSharedPointer>
#include <QPair>
namespace QXlsx {
@ -38,11 +39,13 @@ public:
Workbook *q_ptr;
QSharedPointer<SharedStrings> sharedStrings;
QList<Worksheet *> worksheets;
QList<QSharedPointer<Worksheet> > worksheets;
QSharedPointer<Styles> styles;
QList<QImage> images;
QList<Drawing *> drawings;
QList<QPair<QString, QString> > sheetNameIdPairList;//Data from xml file
bool strings_to_numbers_enabled;
bool date1904;

85
src/xlsx/xlsxworksheet.cpp

@ -29,6 +29,7 @@
#include "xlsxutility_p.h"
#include "xlsxsharedstrings_p.h"
#include "xlsxxmlwriter_p.h"
#include "xlsxxmlreader_p.h"
#include "xlsxdrawing_p.h"
#include "xlsxstyles_p.h"
@ -74,12 +75,6 @@ WorksheetPrivate::WorksheetPrivate(Worksheet *p) :
WorksheetPrivate::~WorksheetPrivate()
{
typedef QMap<int, XlsxCellData *> RowMap;
foreach (RowMap row, cellTable) {
foreach (XlsxCellData *item, row)
delete item;
}
foreach (XlsxRowInfo *row, rowsInfo)
delete row;
@ -224,12 +219,18 @@ bool Worksheet::isChartsheet() const
return false;
}
QString Worksheet::name() const
QString Worksheet::sheetName() const
{
Q_D(const Worksheet);
return d->name;
}
void Worksheet::setSheetName(const QString &sheetName)
{
Q_D(Worksheet);
d->name = sheetName;
}
bool Worksheet::isHidden() const
{
Q_D(const Worksheet);
@ -354,7 +355,7 @@ int Worksheet::writeString(int row, int column, const QString &value, Format *fo
SharedStrings *sharedStrings = d->workbook->sharedStrings();
int index = sharedStrings->addSharedString(content);
d->cellTable[row][column] = new XlsxCellData(index, XlsxCellData::String, format);
d->cellTable[row][column] = QSharedPointer<XlsxCellData>(new XlsxCellData(index, XlsxCellData::String, format));
d->workbook->styles()->addFormat(format);
return error;
}
@ -365,7 +366,7 @@ int Worksheet::writeNumber(int row, int column, double value, Format *format)
if (d->checkDimensions(row, column))
return -1;
d->cellTable[row][column] = new XlsxCellData(value, XlsxCellData::Number, format);
d->cellTable[row][column] = QSharedPointer<XlsxCellData>(new XlsxCellData(value, XlsxCellData::Number, format));
d->workbook->styles()->addFormat(format);
return 0;
}
@ -384,7 +385,7 @@ int Worksheet::writeFormula(int row, int column, const QString &content, Format
XlsxCellData *data = new XlsxCellData(result, XlsxCellData::Formula, format);
data->formula = formula;
d->cellTable[row][column] = data;
d->cellTable[row][column] = QSharedPointer<XlsxCellData>(data);
d->workbook->styles()->addFormat(format);
return error;
@ -396,7 +397,7 @@ int Worksheet::writeBlank(int row, int column, Format *format)
if (d->checkDimensions(row, column))
return -1;
d->cellTable[row][column] = new XlsxCellData(QVariant(), XlsxCellData::Blank, format);
d->cellTable[row][column] = QSharedPointer<XlsxCellData>(new XlsxCellData(QVariant(), XlsxCellData::Blank, format));
d->workbook->styles()->addFormat(format);
return 0;
@ -408,7 +409,7 @@ int Worksheet::writeBool(int row, int column, bool value, Format *format)
if (d->checkDimensions(row, column))
return -1;
d->cellTable[row][column] = new XlsxCellData(value, XlsxCellData::Boolean, format);
d->cellTable[row][column] = QSharedPointer<XlsxCellData>(new XlsxCellData(value, XlsxCellData::Boolean, format));
d->workbook->styles()->addFormat(format);
return 0;
@ -420,7 +421,7 @@ int Worksheet::writeDateTime(int row, int column, const QDateTime &dt, Format *f
if (d->checkDimensions(row, column))
return -1;
d->cellTable[row][column] = new XlsxCellData(dt, XlsxCellData::DateTime, format);
d->cellTable[row][column] = QSharedPointer<XlsxCellData>(new XlsxCellData(dt, XlsxCellData::DateTime, format));
d->workbook->styles()->addFormat(format);
return 0;
@ -482,7 +483,7 @@ int Worksheet::writeUrl(int row, int column, const QUrl &url, Format *format, co
//Write the hyperlink string as normal string.
SharedStrings *sharedStrings = d->workbook->sharedStrings();
int index = sharedStrings->addSharedString(urlString);
d->cellTable[row][column] = new XlsxCellData(index, XlsxCellData::String, format);
d->cellTable[row][column] = QSharedPointer<XlsxCellData>(new XlsxCellData(index, XlsxCellData::String, format));
//Store the hyperlink data in sa separate table
d->urlTable[row][column] = new XlsxUrlData(link_type, urlString, locationString, tip);
@ -695,7 +696,7 @@ void WorksheetPrivate::writeSheetData(XmlStreamWriter &writer)
}
}
void WorksheetPrivate::writeCellData(XmlStreamWriter &writer, int row, int col, XlsxCellData *cell)
void WorksheetPrivate::writeCellData(XmlStreamWriter &writer, int row, int col, QSharedPointer<XlsxCellData> cell)
{
//This is the innermost loop so efficiency is important.
QString cell_range = xl_rowcol_to_cell_fast(row, col);
@ -1068,7 +1069,59 @@ QByteArray Worksheet::saveToXmlData()
QSharedPointer<Worksheet> Worksheet::loadFromXmlFile(QIODevice *device)
{
return QSharedPointer<Worksheet>(new Worksheet(QString()));
Worksheet *sheet = new Worksheet(QStringLiteral("Sheet9999"));
XmlStreamReader reader(device);
while(!reader.atEnd()) {
QXmlStreamReader::TokenType token = reader.readNext();
if (token == QXmlStreamReader::StartElement) {
if (reader.name() == QLatin1String("dimension")) {
QXmlStreamAttributes attributes = reader.attributes();
QStringList range = attributes.value(QLatin1String("ref")).toString().split(QLatin1Char(':'));
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();
} 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();
}
} else if (reader.name() == QLatin1String("c")) {
QXmlStreamAttributes attributes = reader.attributes();
QString r = attributes.value(QLatin1String("r")).toString();
QPoint pos = xl_cell_to_rowcol(r);
if (attributes.hasAttribute(QLatin1String("t"))) {
QString type = attributes.value(QLatin1String("t")).toString();
if (type == QLatin1String("s")) {
//string type
reader.readNextStartElement();
if (reader.name() == QLatin1String("v")) {
QString value = reader.readElementText();
XlsxCellData *data = new XlsxCellData(value ,XlsxCellData::String);
sheet->d_func()->cellTable[pos.x()][pos.y()] = QSharedPointer<XlsxCellData>(data);
}
}
} else {
//number type
reader.readNextStartElement();
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);
}
}
}
}
}
return QSharedPointer<Worksheet> (sheet);
}
QSharedPointer<Worksheet> Worksheet::loadFromXmlData(const QByteArray &data)

3
src/xlsx/xlsxworksheet.h

@ -84,7 +84,8 @@ private:
Worksheet(const QString &sheetName, Workbook *book=0);
virtual bool isChartsheet() const;
QString name() const;
QString sheetName() const;
void setSheetName(const QString &sheetName);
bool isHidden() const;
bool isSelected() const;
void setHidden(bool hidden);

5
src/xlsx/xlsxworksheet_p.h

@ -27,6 +27,7 @@
#include "xlsxworksheet.h"
#include <QImage>
#include <QSharedPointer>
namespace QXlsx {
@ -182,7 +183,7 @@ public:
QString generateDimensionString();
void calculateSpans();
void writeSheetData(XmlStreamWriter &writer);
void writeCellData(XmlStreamWriter &writer, int row, int col, XlsxCellData *cell);
void writeCellData(XmlStreamWriter &writer, int row, int col, QSharedPointer<XlsxCellData> cell);
void writeMergeCells(XmlStreamWriter &writer);
void writeHyperlinks(XmlStreamWriter &writer);
void writeDrawings(XmlStreamWriter &writer);
@ -193,7 +194,7 @@ public:
Workbook *workbook;
Drawing *drawing;
QMap<int, QMap<int, XlsxCellData *> > cellTable;
QMap<int, QMap<int, QSharedPointer<XlsxCellData> > > cellTable;
QMap<int, QMap<int, QString> > comments;
QMap<int, QMap<int, XlsxUrlData *> > urlTable;
QList<XlsxCellRange> merges;

Loading…
Cancel
Save