diff src/xlsx/xlsxworkbook.cpp @ 1:93d3106bb9a4

Add qt xlsx library
author Andre Heinecke <andre.heinecke@intevation.de>
date Tue, 22 Mar 2016 10:38:08 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/xlsx/xlsxworkbook.cpp	Tue Mar 22 10:38:08 2016 +0100
@@ -0,0 +1,693 @@
+/****************************************************************************
+** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
+** All right reserved.
+**
+** Permission is hereby granted, free of charge, to any person obtaining
+** a copy of this software and associated documentation files (the
+** "Software"), to deal in the Software without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Software, and to
+** permit persons to whom the Software is furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be
+** included in all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**
+****************************************************************************/
+#include "xlsxworkbook.h"
+#include "xlsxworkbook_p.h"
+#include "xlsxsharedstrings_p.h"
+#include "xlsxworksheet.h"
+#include "xlsxchartsheet.h"
+#include "xlsxstyles_p.h"
+#include "xlsxformat.h"
+#include "xlsxworksheet_p.h"
+#include "xlsxformat_p.h"
+#include "xlsxmediafile_p.h"
+#include "xlsxutility_p.h"
+
+#include <QXmlStreamWriter>
+#include <QXmlStreamReader>
+#include <QFile>
+#include <QBuffer>
+#include <QDir>
+
+QT_BEGIN_NAMESPACE_XLSX
+
+WorkbookPrivate::WorkbookPrivate(Workbook *q, Workbook::CreateFlag flag) :
+    AbstractOOXmlFilePrivate(q, flag)
+{
+    sharedStrings = QSharedPointer<SharedStrings> (new SharedStrings(flag));
+    styles = QSharedPointer<Styles>(new Styles(flag));
+    theme = QSharedPointer<Theme>(new Theme(flag));
+
+    x_window = 240;
+    y_window = 15;
+    window_width = 16095;
+    window_height = 9660;
+
+    strings_to_numbers_enabled = false;
+    strings_to_hyperlinks_enabled = true;
+    html_to_richstring_enabled = false;
+    date1904 = false;
+    defaultDateFormat = QStringLiteral("yyyy-mm-dd");
+    activesheetIndex = 0;
+    firstsheet = 0;
+    table_count = 0;
+
+    last_worksheet_index = 0;
+    last_chartsheet_index = 0;
+    last_sheet_id = 0;
+}
+
+Workbook::Workbook(CreateFlag flag)
+    : AbstractOOXmlFile(new WorkbookPrivate(this, flag))
+{
+
+}
+
+Workbook::~Workbook()
+{
+}
+
+bool Workbook::isDate1904() const
+{
+    Q_D(const Workbook);
+    return d->date1904;
+}
+
+/*!
+  Excel for Windows uses a default epoch of 1900 and Excel
+  for Mac uses an epoch of 1904. However, Excel on either
+  platform will convert automatically between one system
+  and the other. Qt Xlsx stores dates in the 1900 format
+  by default.
+
+  \note This function should be called before any date/time
+  has been written.
+*/
+void Workbook::setDate1904(bool date1904)
+{
+    Q_D(Workbook);
+    d->date1904 = date1904;
+}
+
+/*
+  Enable the worksheet.write() method to convert strings
+  to numbers, where possible, using float() in order to avoid
+  an Excel warning about "Numbers Stored as Text".
+
+  The default is false
+ */
+void Workbook::setStringsToNumbersEnabled(bool enable)
+{
+    Q_D(Workbook);
+    d->strings_to_numbers_enabled = enable;
+}
+
+bool Workbook::isStringsToNumbersEnabled() const
+{
+    Q_D(const Workbook);
+    return d->strings_to_numbers_enabled;
+}
+
+void Workbook::setStringsToHyperlinksEnabled(bool enable)
+{
+    Q_D(Workbook);
+    d->strings_to_hyperlinks_enabled = enable;
+}
+
+bool Workbook::isStringsToHyperlinksEnabled() const
+{
+    Q_D(const Workbook);
+    return d->strings_to_hyperlinks_enabled;
+}
+
+void Workbook::setHtmlToRichStringEnabled(bool enable)
+{
+    Q_D(Workbook);
+    d->html_to_richstring_enabled = enable;
+}
+
+bool Workbook::isHtmlToRichStringEnabled() const
+{
+    Q_D(const Workbook);
+    return d->html_to_richstring_enabled;
+}
+
+QString Workbook::defaultDateFormat() const
+{
+    Q_D(const Workbook);
+    return d->defaultDateFormat;
+}
+
+void Workbook::setDefaultDateFormat(const QString &format)
+{
+    Q_D(Workbook);
+    d->defaultDateFormat = format;
+}
+
+/*!
+ * \brief Create a defined name in the workbook.
+ * \param name The defined name
+ * \param formula The cell or range that the defined name refers to.
+ * \param comment
+ * \param scope The name of one worksheet, or empty which means golbal scope.
+ * \return Return false if the name invalid.
+ */
+bool Workbook::defineName(const QString &name, const QString &formula, const QString &comment, const QString &scope)
+{
+    Q_D(Workbook);
+
+    //Remove the = sign from the formula if it exists.
+    QString formulaString = formula;
+    if (formulaString.startsWith(QLatin1Char('=')))
+        formulaString = formula.mid(1);
+
+    int id=-1;
+    if (!scope.isEmpty()) {
+        for (int i=0; i<d->sheets.size(); ++i) {
+            if (d->sheets[i]->sheetName() == scope) {
+                id = d->sheets[i]->sheetId();
+                break;
+            }
+        }
+    }
+
+    d->definedNamesList.append(XlsxDefineNameData(name, formulaString, comment, id));
+    return true;
+}
+
+AbstractSheet *Workbook::addSheet(const QString &name, AbstractSheet::SheetType type)
+{
+    Q_D(Workbook);
+    return insertSheet(d->sheets.size(), name, type);
+}
+
+/*!
+ * \internal
+ */
+QStringList Workbook::worksheetNames() const
+{
+    Q_D(const Workbook);
+    return d->sheetNames;
+}
+
+/*!
+ * \internal
+ * Used only when load the xlsx file!!
+ */
+AbstractSheet *Workbook::addSheet(const QString &name, int sheetId, AbstractSheet::SheetType type)
+{
+    Q_D(Workbook);
+    if (sheetId > d->last_sheet_id)
+        d->last_sheet_id = sheetId;
+    AbstractSheet *sheet=0;
+    if (type == AbstractSheet::ST_WorkSheet) {
+        sheet = new Worksheet(name, sheetId, this, F_LoadFromExists);
+    } else if (type == AbstractSheet::ST_ChartSheet) {
+        sheet = new Chartsheet(name, sheetId, this, F_LoadFromExists);
+    } else {
+        qWarning("unsupported sheet type.");
+        Q_ASSERT(false);
+    }
+    d->sheets.append(QSharedPointer<AbstractSheet>(sheet));
+    d->sheetNames.append(name);
+    return sheet;
+}
+
+AbstractSheet *Workbook::insertSheet(int index, const QString &name, AbstractSheet::SheetType type)
+{
+    Q_D(Workbook);
+    QString sheetName = createSafeSheetName(name);
+    if (!sheetName.isEmpty()) {
+        //If user given an already in-used name, we should not continue any more!
+        if (d->sheetNames.contains(sheetName))
+            return 0;
+    } else {
+        if (type == AbstractSheet::ST_WorkSheet) {
+            do {
+                ++d->last_worksheet_index;
+                sheetName = QStringLiteral("Sheet%1").arg(d->last_worksheet_index);
+            } while (d->sheetNames.contains(sheetName));
+        } else if (type == AbstractSheet::ST_ChartSheet) {
+            do {
+                ++d->last_chartsheet_index;
+                sheetName = QStringLiteral("Chart%1").arg(d->last_chartsheet_index);
+            } while (d->sheetNames.contains(sheetName));
+        } else {
+            qWarning("unsupported sheet type.");
+            return 0;
+        }
+    }
+
+    ++d->last_sheet_id;
+    AbstractSheet *sheet;
+    if (type == AbstractSheet::ST_WorkSheet)
+        sheet = new Worksheet(sheetName, d->last_sheet_id, this, F_NewFromScratch);
+    else
+        sheet = new Chartsheet(sheetName, d->last_sheet_id, this, F_NewFromScratch);
+
+    d->sheets.insert(index, QSharedPointer<AbstractSheet>(sheet));
+    d->sheetNames.insert(index, sheetName);
+    d->activesheetIndex = index;
+    return sheet;
+}
+
+/*!
+ * Returns current active worksheet.
+ */
+AbstractSheet *Workbook::activeSheet() const
+{
+    Q_D(const Workbook);
+    if (d->sheets.isEmpty())
+        const_cast<Workbook*>(this)->addSheet();
+    return d->sheets[d->activesheetIndex].data();
+}
+
+bool Workbook::setActiveSheet(int index)
+{
+    Q_D(Workbook);
+    if (index < 0 || index >= d->sheets.size()) {
+        //warning
+        return false;
+    }
+    d->activesheetIndex = index;
+    return true;
+}
+
+/*!
+ * Rename the worksheet at the \a index to \a newName.
+ */
+bool Workbook::renameSheet(int index, const QString &newName)
+{
+    Q_D(Workbook);
+    QString name = createSafeSheetName(newName);
+    if (index < 0 || index >= d->sheets.size())
+        return false;
+
+    //If user given an already in-used name, return false
+    for (int i=0; i<d->sheets.size(); ++i) {
+        if (d->sheets[i]->sheetName() == name)
+            return false;
+    }
+
+    d->sheets[index]->setSheetName(name);
+    d->sheetNames[index] = name;
+    return true;
+}
+
+/*!
+ * Remove the worksheet at pos \a index.
+ */
+bool Workbook::deleteSheet(int index)
+{
+    Q_D(Workbook);
+    if (d->sheets.size() <= 1)
+        return false;
+    if (index < 0 || index >= d->sheets.size())
+        return false;
+    d->sheets.removeAt(index);
+    d->sheetNames.removeAt(index);
+    return true;
+}
+
+/*!
+ * Moves the worksheet form \a srcIndex to \a distIndex.
+ */
+bool Workbook::moveSheet(int srcIndex, int distIndex)
+{
+    Q_D(Workbook);
+    if (srcIndex == distIndex)
+        return false;
+
+    if (srcIndex < 0 || srcIndex >= d->sheets.size())
+        return false;
+
+    QSharedPointer<AbstractSheet> sheet = d->sheets.takeAt(srcIndex);
+    d->sheetNames.takeAt(srcIndex);
+    if (distIndex >= 0 || distIndex <= d->sheets.size()) {
+        d->sheets.insert(distIndex, sheet);
+        d->sheetNames.insert(distIndex, sheet->sheetName());
+    } else {
+        d->sheets.append(sheet);
+        d->sheetNames.append(sheet->sheetName());
+    }
+    return true;
+}
+
+bool Workbook::copySheet(int index, const QString &newName)
+{
+    Q_D(Workbook);
+    if (index < 0 || index >= d->sheets.size())
+        return false;
+
+    QString worksheetName = createSafeSheetName(newName);
+    if (!newName.isEmpty()) {
+        //If user given an already in-used name, we should not continue any more!
+        if (d->sheetNames.contains(newName))
+            return false;
+    } else {
+        int copy_index = 1;
+        do {
+            ++copy_index;
+            worksheetName = QStringLiteral("%1(%2)").arg(d->sheets[index]->sheetName()).arg(copy_index);
+        } while (d->sheetNames.contains(worksheetName));
+    }
+
+    ++d->last_sheet_id;
+    AbstractSheet *sheet = d->sheets[index]->copy(worksheetName, d->last_sheet_id);
+    d->sheets.append(QSharedPointer<AbstractSheet> (sheet));
+    d->sheetNames.append(sheet->sheetName());
+
+    return false;
+}
+
+/*!
+ * Returns count of worksheets.
+ */
+int Workbook::sheetCount() const
+{
+    Q_D(const Workbook);
+    return d->sheets.count();
+}
+
+/*!
+ * Returns the sheet object at index \a sheetIndex.
+ */
+AbstractSheet *Workbook::sheet(int index) const
+{
+    Q_D(const Workbook);
+    if (index < 0 || index >= d->sheets.size())
+        return 0;
+    return d->sheets.at(index).data();
+}
+
+SharedStrings *Workbook::sharedStrings() const
+{
+    Q_D(const Workbook);
+    return d->sharedStrings.data();
+}
+
+Styles *Workbook::styles()
+{
+    Q_D(Workbook);
+    return d->styles.data();
+}
+
+Theme *Workbook::theme()
+{
+    Q_D(Workbook);
+    return d->theme.data();
+}
+
+/*!
+ * \internal
+ *
+ * Unlike media files, drawing file is a property of the sheet.
+ */
+QList<Drawing *> Workbook::drawings()
+{
+    Q_D(Workbook);
+    QList<Drawing *> ds;
+    for (int i=0; i<d->sheets.size(); ++i) {
+        QSharedPointer<AbstractSheet> sheet = d->sheets[i];
+        if (sheet->drawing())
+        ds.append(sheet->drawing());
+    }
+
+    return ds;
+}
+
+/*!
+ * \internal
+ */
+QList<QSharedPointer<AbstractSheet> > Workbook::getSheetsByTypes(AbstractSheet::SheetType type) const
+{
+    Q_D(const Workbook);
+    QList<QSharedPointer<AbstractSheet> > list;
+    for (int i=0; i<d->sheets.size(); ++i) {
+        if (d->sheets[i]->sheetType() == type)
+            list.append(d->sheets[i]);
+    }
+    return list;
+}
+
+void Workbook::saveToXmlFile(QIODevice *device) const
+{
+    Q_D(const Workbook);
+    d->relationships->clear();
+    if (d->sheets.isEmpty())
+        const_cast<Workbook *>(this)->addSheet();
+
+    QXmlStreamWriter writer(device);
+
+    writer.writeStartDocument(QStringLiteral("1.0"), true);
+    writer.writeStartElement(QStringLiteral("workbook"));
+    writer.writeAttribute(QStringLiteral("xmlns"), QStringLiteral("http://schemas.openxmlformats.org/spreadsheetml/2006/main"));
+    writer.writeAttribute(QStringLiteral("xmlns:r"), QStringLiteral("http://schemas.openxmlformats.org/officeDocument/2006/relationships"));
+
+    writer.writeEmptyElement(QStringLiteral("fileVersion"));
+    writer.writeAttribute(QStringLiteral("appName"), QStringLiteral("xl"));
+    writer.writeAttribute(QStringLiteral("lastEdited"), QStringLiteral("4"));
+    writer.writeAttribute(QStringLiteral("lowestEdited"), QStringLiteral("4"));
+    writer.writeAttribute(QStringLiteral("rupBuild"), QStringLiteral("4505"));
+//    writer.writeAttribute(QStringLiteral("codeName"), QStringLiteral("{37E998C4-C9E5-D4B9-71C8-EB1FF731991C}"));
+
+    writer.writeEmptyElement(QStringLiteral("workbookPr"));
+    if (d->date1904)
+        writer.writeAttribute(QStringLiteral("date1904"), QStringLiteral("1"));
+    writer.writeAttribute(QStringLiteral("defaultThemeVersion"), QStringLiteral("124226"));
+
+    writer.writeStartElement(QStringLiteral("bookViews"));
+    writer.writeEmptyElement(QStringLiteral("workbookView"));
+    writer.writeAttribute(QStringLiteral("xWindow"), QString::number(d->x_window));
+    writer.writeAttribute(QStringLiteral("yWindow"), QString::number(d->y_window));
+    writer.writeAttribute(QStringLiteral("windowWidth"), QString::number(d->window_width));
+    writer.writeAttribute(QStringLiteral("windowHeight"), QString::number(d->window_height));
+    //Store the firstSheet when it isn't the default
+    //For example, when "the first sheet 0 is hidden", the first sheet will be 1
+    if (d->firstsheet > 0)
+        writer.writeAttribute(QStringLiteral("firstSheet"), QString::number(d->firstsheet + 1));
+    //Store the activeTab when it isn't the first sheet
+    if (d->activesheetIndex > 0)
+        writer.writeAttribute(QStringLiteral("activeTab"), QString::number(d->activesheetIndex));
+    writer.writeEndElement();//bookViews
+
+    writer.writeStartElement(QStringLiteral("sheets"));
+    int worksheetIndex = 0;
+    int chartsheetIndex = 0;
+    for (int i=0; i<d->sheets.size(); ++i) {
+        QSharedPointer<AbstractSheet> sheet = d->sheets[i];
+        writer.writeEmptyElement(QStringLiteral("sheet"));
+        writer.writeAttribute(QStringLiteral("name"), sheet->sheetName());
+        writer.writeAttribute(QStringLiteral("sheetId"), QString::number(sheet->sheetId()));
+        if (sheet->sheetState() == AbstractSheet::SS_Hidden)
+            writer.writeAttribute(QStringLiteral("state"), QStringLiteral("hidden"));
+        else if (sheet->sheetState() == AbstractSheet::SS_VeryHidden)
+            writer.writeAttribute(QStringLiteral("state"), QStringLiteral("veryHidden"));
+
+        if (sheet->sheetType() == AbstractSheet::ST_WorkSheet)
+            d->relationships->addDocumentRelationship(QStringLiteral("/worksheet"), QStringLiteral("worksheets/sheet%1.xml").arg(++worksheetIndex));
+        else
+            d->relationships->addDocumentRelationship(QStringLiteral("/chartsheet"), QStringLiteral("chartsheets/sheet%1.xml").arg(++chartsheetIndex));
+
+        writer.writeAttribute(QStringLiteral("r:id"), QStringLiteral("rId%1").arg(d->relationships->count()));
+    }
+    writer.writeEndElement();//sheets
+
+    if (d->externalLinks.size() > 0) {
+        writer.writeStartElement(QStringLiteral("externalReferences"));
+        for (int i=0; i<d->externalLinks.size(); ++i) {
+            writer.writeEmptyElement(QStringLiteral("externalReference"));
+            d->relationships->addDocumentRelationship(QStringLiteral("/externalLink"), QStringLiteral("externalLinks/externalLink%1.xml").arg(i+1));
+            writer.writeAttribute(QStringLiteral("r:id"), QStringLiteral("rId%1").arg(d->relationships->count()));
+        }
+        writer.writeEndElement();//externalReferences
+    }
+
+    if (!d->definedNamesList.isEmpty()) {
+        writer.writeStartElement(QStringLiteral("definedNames"));
+        foreach (XlsxDefineNameData data, d->definedNamesList) {
+            writer.writeStartElement(QStringLiteral("definedName"));
+            writer.writeAttribute(QStringLiteral("name"), data.name);
+            if (!data.comment.isEmpty())
+                writer.writeAttribute(QStringLiteral("comment"), data.comment);
+            if (data.sheetId != -1) {
+                //find the local index of the sheet.
+                for (int i=0; i<d->sheets.size(); ++i) {
+                    if (d->sheets[i]->sheetId() == data.sheetId) {
+                        writer.writeAttribute(QStringLiteral("localSheetId"), QString::number(i));
+                        break;
+                    }
+                }
+            }
+            writer.writeCharacters(data.formula);
+            writer.writeEndElement();//definedName
+        }
+        writer.writeEndElement();//definedNames
+    }
+
+    writer.writeStartElement(QStringLiteral("calcPr"));
+    writer.writeAttribute(QStringLiteral("calcId"), QStringLiteral("124519"));
+    writer.writeEndElement(); //calcPr
+
+    writer.writeEndElement();//workbook
+    writer.writeEndDocument();
+
+    d->relationships->addDocumentRelationship(QStringLiteral("/theme"), QStringLiteral("theme/theme1.xml"));
+    d->relationships->addDocumentRelationship(QStringLiteral("/styles"), QStringLiteral("styles.xml"));
+    if (!sharedStrings()->isEmpty())
+        d->relationships->addDocumentRelationship(QStringLiteral("/sharedStrings"), QStringLiteral("sharedStrings.xml"));
+}
+
+bool Workbook::loadFromXmlFile(QIODevice *device)
+{
+    Q_D(Workbook);
+
+    QXmlStreamReader reader(device);
+    while (!reader.atEnd()) {
+         QXmlStreamReader::TokenType token = reader.readNext();
+         if (token == QXmlStreamReader::StartElement) {
+             if (reader.name() == QLatin1String("sheet")) {
+                 QXmlStreamAttributes attributes = reader.attributes();
+                 const QString name = attributes.value(QLatin1String("name")).toString();
+                 int sheetId = attributes.value(QLatin1String("sheetId")).toString().toInt();
+                 const QString rId = attributes.value(QLatin1String("r:id")).toString();
+                 const QStringRef &stateString = attributes.value(QLatin1String("state"));
+                 AbstractSheet::SheetState state = AbstractSheet::SS_Visible;
+                 if (stateString == QLatin1String("hidden"))
+                     state = AbstractSheet::SS_Hidden;
+                 else if (stateString == QLatin1String("veryHidden"))
+                     state = AbstractSheet::SS_VeryHidden;
+
+                 XlsxRelationship relationship = d->relationships->getRelationshipById(rId);
+
+                 AbstractSheet::SheetType type = AbstractSheet::ST_WorkSheet;
+                 if (relationship.type.endsWith(QLatin1String("/worksheet")))
+                     type = AbstractSheet::ST_WorkSheet;
+                 else if (relationship.type.endsWith(QLatin1String("/chartsheet")))
+                     type = AbstractSheet::ST_ChartSheet;
+                 else if (relationship.type.endsWith(QLatin1String("/dialogsheet")))
+                     type = AbstractSheet::ST_DialogSheet;
+                 else if (relationship.type.endsWith(QLatin1String("/xlMacrosheet")))
+                     type = AbstractSheet::ST_MacroSheet;
+                 else
+                     qWarning("unknown sheet type");
+
+                 AbstractSheet *sheet = addSheet(name, sheetId, type);
+                 sheet->setSheetState(state);
+                 const QString fullPath = QDir::cleanPath(splitPath(filePath())[0] +QLatin1String("/")+ relationship.target);
+                 sheet->setFilePath(fullPath);
+             } else if (reader.name() == QLatin1String("workbookPr")) {
+                QXmlStreamAttributes attrs = reader.attributes();
+                if (attrs.hasAttribute(QLatin1String("date1904")))
+                    d->date1904 = true;
+             } else if (reader.name() == QLatin1String("bookviews")) {
+                while (!(reader.name() == QLatin1String("bookviews") && reader.tokenType() == QXmlStreamReader::EndElement)) {
+                    reader.readNextStartElement();
+                    if (reader.tokenType() == QXmlStreamReader::StartElement) {
+                        if (reader.name() == QLatin1String("workbookView")) {
+                            QXmlStreamAttributes attrs = reader.attributes();
+                            if (attrs.hasAttribute(QLatin1String("xWindow")))
+                                d->x_window = attrs.value(QLatin1String("xWindow")).toString().toInt();
+                            if (attrs.hasAttribute(QLatin1String("yWindow")))
+                                d->y_window = attrs.value(QLatin1String("yWindow")).toString().toInt();
+                            if (attrs.hasAttribute(QLatin1String("windowWidth")))
+                                d->window_width = attrs.value(QLatin1String("windowWidth")).toString().toInt();
+                            if (attrs.hasAttribute(QLatin1String("windowHeight")))
+                                d->window_height = attrs.value(QLatin1String("windowHeight")).toString().toInt();
+                            if (attrs.hasAttribute(QLatin1String("firstSheet")))
+                                d->firstsheet = attrs.value(QLatin1String("firstSheet")).toString().toInt();
+                            if (attrs.hasAttribute(QLatin1String("activeTab")))
+                                d->activesheetIndex = attrs.value(QLatin1String("activeTab")).toString().toInt();
+                        }
+                    }
+                }
+             } else if (reader.name() == QLatin1String("externalReference")) {
+                 QXmlStreamAttributes attributes = reader.attributes();
+                 const QString rId = attributes.value(QLatin1String("r:id")).toString();
+                 XlsxRelationship relationship = d->relationships->getRelationshipById(rId);
+
+                 QSharedPointer<SimpleOOXmlFile> link(new SimpleOOXmlFile(F_LoadFromExists));
+                 const QString fullPath = QDir::cleanPath(splitPath(filePath())[0] +QLatin1String("/")+ relationship.target);
+                 link->setFilePath(fullPath);
+                 d->externalLinks.append(link);
+             } else if (reader.name() == QLatin1String("definedName")) {
+                 QXmlStreamAttributes attrs = reader.attributes();
+                 XlsxDefineNameData data;
+
+                 data.name = attrs.value(QLatin1String("name")).toString();
+                 if (attrs.hasAttribute(QLatin1String("comment")))
+                     data.comment = attrs.value(QLatin1String("comment")).toString();
+                 if (attrs.hasAttribute(QLatin1String("localSheetId"))) {
+                     int localId = attrs.value(QLatin1String("localSheetId")).toString().toInt();
+                     int sheetId = d->sheets.at(localId)->sheetId();
+                     data.sheetId = sheetId;
+                 }
+                 data.formula = reader.readElementText();
+                 d->definedNamesList.append(data);
+             }
+         }
+    }
+    return true;
+}
+
+/*!
+ * \internal
+ */
+QList<QSharedPointer<MediaFile> > Workbook::mediaFiles() const
+{
+    Q_D(const Workbook);
+
+    return d->mediaFiles;
+}
+
+/*!
+ * \internal
+ */
+void Workbook::addMediaFile(QSharedPointer<MediaFile> media, bool force)
+{
+    Q_D(Workbook);
+    if (!force) {
+        for (int i=0; i<d->mediaFiles.size(); ++i) {
+            if (d->mediaFiles[i]->hashKey() == media->hashKey()) {
+                media->setIndex(i);
+                return;
+            }
+        }
+    }
+    media->setIndex(d->mediaFiles.size());
+    d->mediaFiles.append(media);
+}
+
+/*!
+ * \internal
+ */
+QList<QSharedPointer<Chart> > Workbook::chartFiles() const
+{
+    Q_D(const Workbook);
+
+    return d->chartFiles;
+}
+
+/*!
+ * \internal
+ */
+void Workbook::addChartFile(QSharedPointer<Chart> chart)
+{
+    Q_D(Workbook);
+
+    if (!d->chartFiles.contains(chart))
+        d->chartFiles.append(chart);
+}
+
+QT_END_NAMESPACE_XLSX
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)