comparison 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
comparison
equal deleted inserted replaced
0:49cd5cc0b072 1:93d3106bb9a4
1 /****************************************************************************
2 ** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
3 ** All right reserved.
4 **
5 ** Permission is hereby granted, free of charge, to any person obtaining
6 ** a copy of this software and associated documentation files (the
7 ** "Software"), to deal in the Software without restriction, including
8 ** without limitation the rights to use, copy, modify, merge, publish,
9 ** distribute, sublicense, and/or sell copies of the Software, and to
10 ** permit persons to whom the Software is furnished to do so, subject to
11 ** the following conditions:
12 **
13 ** The above copyright notice and this permission notice shall be
14 ** included in all copies or substantial portions of the Software.
15 **
16 ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 ** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 ** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 ** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 **
24 ****************************************************************************/
25 #include "xlsxworkbook.h"
26 #include "xlsxworkbook_p.h"
27 #include "xlsxsharedstrings_p.h"
28 #include "xlsxworksheet.h"
29 #include "xlsxchartsheet.h"
30 #include "xlsxstyles_p.h"
31 #include "xlsxformat.h"
32 #include "xlsxworksheet_p.h"
33 #include "xlsxformat_p.h"
34 #include "xlsxmediafile_p.h"
35 #include "xlsxutility_p.h"
36
37 #include <QXmlStreamWriter>
38 #include <QXmlStreamReader>
39 #include <QFile>
40 #include <QBuffer>
41 #include <QDir>
42
43 QT_BEGIN_NAMESPACE_XLSX
44
45 WorkbookPrivate::WorkbookPrivate(Workbook *q, Workbook::CreateFlag flag) :
46 AbstractOOXmlFilePrivate(q, flag)
47 {
48 sharedStrings = QSharedPointer<SharedStrings> (new SharedStrings(flag));
49 styles = QSharedPointer<Styles>(new Styles(flag));
50 theme = QSharedPointer<Theme>(new Theme(flag));
51
52 x_window = 240;
53 y_window = 15;
54 window_width = 16095;
55 window_height = 9660;
56
57 strings_to_numbers_enabled = false;
58 strings_to_hyperlinks_enabled = true;
59 html_to_richstring_enabled = false;
60 date1904 = false;
61 defaultDateFormat = QStringLiteral("yyyy-mm-dd");
62 activesheetIndex = 0;
63 firstsheet = 0;
64 table_count = 0;
65
66 last_worksheet_index = 0;
67 last_chartsheet_index = 0;
68 last_sheet_id = 0;
69 }
70
71 Workbook::Workbook(CreateFlag flag)
72 : AbstractOOXmlFile(new WorkbookPrivate(this, flag))
73 {
74
75 }
76
77 Workbook::~Workbook()
78 {
79 }
80
81 bool Workbook::isDate1904() const
82 {
83 Q_D(const Workbook);
84 return d->date1904;
85 }
86
87 /*!
88 Excel for Windows uses a default epoch of 1900 and Excel
89 for Mac uses an epoch of 1904. However, Excel on either
90 platform will convert automatically between one system
91 and the other. Qt Xlsx stores dates in the 1900 format
92 by default.
93
94 \note This function should be called before any date/time
95 has been written.
96 */
97 void Workbook::setDate1904(bool date1904)
98 {
99 Q_D(Workbook);
100 d->date1904 = date1904;
101 }
102
103 /*
104 Enable the worksheet.write() method to convert strings
105 to numbers, where possible, using float() in order to avoid
106 an Excel warning about "Numbers Stored as Text".
107
108 The default is false
109 */
110 void Workbook::setStringsToNumbersEnabled(bool enable)
111 {
112 Q_D(Workbook);
113 d->strings_to_numbers_enabled = enable;
114 }
115
116 bool Workbook::isStringsToNumbersEnabled() const
117 {
118 Q_D(const Workbook);
119 return d->strings_to_numbers_enabled;
120 }
121
122 void Workbook::setStringsToHyperlinksEnabled(bool enable)
123 {
124 Q_D(Workbook);
125 d->strings_to_hyperlinks_enabled = enable;
126 }
127
128 bool Workbook::isStringsToHyperlinksEnabled() const
129 {
130 Q_D(const Workbook);
131 return d->strings_to_hyperlinks_enabled;
132 }
133
134 void Workbook::setHtmlToRichStringEnabled(bool enable)
135 {
136 Q_D(Workbook);
137 d->html_to_richstring_enabled = enable;
138 }
139
140 bool Workbook::isHtmlToRichStringEnabled() const
141 {
142 Q_D(const Workbook);
143 return d->html_to_richstring_enabled;
144 }
145
146 QString Workbook::defaultDateFormat() const
147 {
148 Q_D(const Workbook);
149 return d->defaultDateFormat;
150 }
151
152 void Workbook::setDefaultDateFormat(const QString &format)
153 {
154 Q_D(Workbook);
155 d->defaultDateFormat = format;
156 }
157
158 /*!
159 * \brief Create a defined name in the workbook.
160 * \param name The defined name
161 * \param formula The cell or range that the defined name refers to.
162 * \param comment
163 * \param scope The name of one worksheet, or empty which means golbal scope.
164 * \return Return false if the name invalid.
165 */
166 bool Workbook::defineName(const QString &name, const QString &formula, const QString &comment, const QString &scope)
167 {
168 Q_D(Workbook);
169
170 //Remove the = sign from the formula if it exists.
171 QString formulaString = formula;
172 if (formulaString.startsWith(QLatin1Char('=')))
173 formulaString = formula.mid(1);
174
175 int id=-1;
176 if (!scope.isEmpty()) {
177 for (int i=0; i<d->sheets.size(); ++i) {
178 if (d->sheets[i]->sheetName() == scope) {
179 id = d->sheets[i]->sheetId();
180 break;
181 }
182 }
183 }
184
185 d->definedNamesList.append(XlsxDefineNameData(name, formulaString, comment, id));
186 return true;
187 }
188
189 AbstractSheet *Workbook::addSheet(const QString &name, AbstractSheet::SheetType type)
190 {
191 Q_D(Workbook);
192 return insertSheet(d->sheets.size(), name, type);
193 }
194
195 /*!
196 * \internal
197 */
198 QStringList Workbook::worksheetNames() const
199 {
200 Q_D(const Workbook);
201 return d->sheetNames;
202 }
203
204 /*!
205 * \internal
206 * Used only when load the xlsx file!!
207 */
208 AbstractSheet *Workbook::addSheet(const QString &name, int sheetId, AbstractSheet::SheetType type)
209 {
210 Q_D(Workbook);
211 if (sheetId > d->last_sheet_id)
212 d->last_sheet_id = sheetId;
213 AbstractSheet *sheet=0;
214 if (type == AbstractSheet::ST_WorkSheet) {
215 sheet = new Worksheet(name, sheetId, this, F_LoadFromExists);
216 } else if (type == AbstractSheet::ST_ChartSheet) {
217 sheet = new Chartsheet(name, sheetId, this, F_LoadFromExists);
218 } else {
219 qWarning("unsupported sheet type.");
220 Q_ASSERT(false);
221 }
222 d->sheets.append(QSharedPointer<AbstractSheet>(sheet));
223 d->sheetNames.append(name);
224 return sheet;
225 }
226
227 AbstractSheet *Workbook::insertSheet(int index, const QString &name, AbstractSheet::SheetType type)
228 {
229 Q_D(Workbook);
230 QString sheetName = createSafeSheetName(name);
231 if (!sheetName.isEmpty()) {
232 //If user given an already in-used name, we should not continue any more!
233 if (d->sheetNames.contains(sheetName))
234 return 0;
235 } else {
236 if (type == AbstractSheet::ST_WorkSheet) {
237 do {
238 ++d->last_worksheet_index;
239 sheetName = QStringLiteral("Sheet%1").arg(d->last_worksheet_index);
240 } while (d->sheetNames.contains(sheetName));
241 } else if (type == AbstractSheet::ST_ChartSheet) {
242 do {
243 ++d->last_chartsheet_index;
244 sheetName = QStringLiteral("Chart%1").arg(d->last_chartsheet_index);
245 } while (d->sheetNames.contains(sheetName));
246 } else {
247 qWarning("unsupported sheet type.");
248 return 0;
249 }
250 }
251
252 ++d->last_sheet_id;
253 AbstractSheet *sheet;
254 if (type == AbstractSheet::ST_WorkSheet)
255 sheet = new Worksheet(sheetName, d->last_sheet_id, this, F_NewFromScratch);
256 else
257 sheet = new Chartsheet(sheetName, d->last_sheet_id, this, F_NewFromScratch);
258
259 d->sheets.insert(index, QSharedPointer<AbstractSheet>(sheet));
260 d->sheetNames.insert(index, sheetName);
261 d->activesheetIndex = index;
262 return sheet;
263 }
264
265 /*!
266 * Returns current active worksheet.
267 */
268 AbstractSheet *Workbook::activeSheet() const
269 {
270 Q_D(const Workbook);
271 if (d->sheets.isEmpty())
272 const_cast<Workbook*>(this)->addSheet();
273 return d->sheets[d->activesheetIndex].data();
274 }
275
276 bool Workbook::setActiveSheet(int index)
277 {
278 Q_D(Workbook);
279 if (index < 0 || index >= d->sheets.size()) {
280 //warning
281 return false;
282 }
283 d->activesheetIndex = index;
284 return true;
285 }
286
287 /*!
288 * Rename the worksheet at the \a index to \a newName.
289 */
290 bool Workbook::renameSheet(int index, const QString &newName)
291 {
292 Q_D(Workbook);
293 QString name = createSafeSheetName(newName);
294 if (index < 0 || index >= d->sheets.size())
295 return false;
296
297 //If user given an already in-used name, return false
298 for (int i=0; i<d->sheets.size(); ++i) {
299 if (d->sheets[i]->sheetName() == name)
300 return false;
301 }
302
303 d->sheets[index]->setSheetName(name);
304 d->sheetNames[index] = name;
305 return true;
306 }
307
308 /*!
309 * Remove the worksheet at pos \a index.
310 */
311 bool Workbook::deleteSheet(int index)
312 {
313 Q_D(Workbook);
314 if (d->sheets.size() <= 1)
315 return false;
316 if (index < 0 || index >= d->sheets.size())
317 return false;
318 d->sheets.removeAt(index);
319 d->sheetNames.removeAt(index);
320 return true;
321 }
322
323 /*!
324 * Moves the worksheet form \a srcIndex to \a distIndex.
325 */
326 bool Workbook::moveSheet(int srcIndex, int distIndex)
327 {
328 Q_D(Workbook);
329 if (srcIndex == distIndex)
330 return false;
331
332 if (srcIndex < 0 || srcIndex >= d->sheets.size())
333 return false;
334
335 QSharedPointer<AbstractSheet> sheet = d->sheets.takeAt(srcIndex);
336 d->sheetNames.takeAt(srcIndex);
337 if (distIndex >= 0 || distIndex <= d->sheets.size()) {
338 d->sheets.insert(distIndex, sheet);
339 d->sheetNames.insert(distIndex, sheet->sheetName());
340 } else {
341 d->sheets.append(sheet);
342 d->sheetNames.append(sheet->sheetName());
343 }
344 return true;
345 }
346
347 bool Workbook::copySheet(int index, const QString &newName)
348 {
349 Q_D(Workbook);
350 if (index < 0 || index >= d->sheets.size())
351 return false;
352
353 QString worksheetName = createSafeSheetName(newName);
354 if (!newName.isEmpty()) {
355 //If user given an already in-used name, we should not continue any more!
356 if (d->sheetNames.contains(newName))
357 return false;
358 } else {
359 int copy_index = 1;
360 do {
361 ++copy_index;
362 worksheetName = QStringLiteral("%1(%2)").arg(d->sheets[index]->sheetName()).arg(copy_index);
363 } while (d->sheetNames.contains(worksheetName));
364 }
365
366 ++d->last_sheet_id;
367 AbstractSheet *sheet = d->sheets[index]->copy(worksheetName, d->last_sheet_id);
368 d->sheets.append(QSharedPointer<AbstractSheet> (sheet));
369 d->sheetNames.append(sheet->sheetName());
370
371 return false;
372 }
373
374 /*!
375 * Returns count of worksheets.
376 */
377 int Workbook::sheetCount() const
378 {
379 Q_D(const Workbook);
380 return d->sheets.count();
381 }
382
383 /*!
384 * Returns the sheet object at index \a sheetIndex.
385 */
386 AbstractSheet *Workbook::sheet(int index) const
387 {
388 Q_D(const Workbook);
389 if (index < 0 || index >= d->sheets.size())
390 return 0;
391 return d->sheets.at(index).data();
392 }
393
394 SharedStrings *Workbook::sharedStrings() const
395 {
396 Q_D(const Workbook);
397 return d->sharedStrings.data();
398 }
399
400 Styles *Workbook::styles()
401 {
402 Q_D(Workbook);
403 return d->styles.data();
404 }
405
406 Theme *Workbook::theme()
407 {
408 Q_D(Workbook);
409 return d->theme.data();
410 }
411
412 /*!
413 * \internal
414 *
415 * Unlike media files, drawing file is a property of the sheet.
416 */
417 QList<Drawing *> Workbook::drawings()
418 {
419 Q_D(Workbook);
420 QList<Drawing *> ds;
421 for (int i=0; i<d->sheets.size(); ++i) {
422 QSharedPointer<AbstractSheet> sheet = d->sheets[i];
423 if (sheet->drawing())
424 ds.append(sheet->drawing());
425 }
426
427 return ds;
428 }
429
430 /*!
431 * \internal
432 */
433 QList<QSharedPointer<AbstractSheet> > Workbook::getSheetsByTypes(AbstractSheet::SheetType type) const
434 {
435 Q_D(const Workbook);
436 QList<QSharedPointer<AbstractSheet> > list;
437 for (int i=0; i<d->sheets.size(); ++i) {
438 if (d->sheets[i]->sheetType() == type)
439 list.append(d->sheets[i]);
440 }
441 return list;
442 }
443
444 void Workbook::saveToXmlFile(QIODevice *device) const
445 {
446 Q_D(const Workbook);
447 d->relationships->clear();
448 if (d->sheets.isEmpty())
449 const_cast<Workbook *>(this)->addSheet();
450
451 QXmlStreamWriter writer(device);
452
453 writer.writeStartDocument(QStringLiteral("1.0"), true);
454 writer.writeStartElement(QStringLiteral("workbook"));
455 writer.writeAttribute(QStringLiteral("xmlns"), QStringLiteral("http://schemas.openxmlformats.org/spreadsheetml/2006/main"));
456 writer.writeAttribute(QStringLiteral("xmlns:r"), QStringLiteral("http://schemas.openxmlformats.org/officeDocument/2006/relationships"));
457
458 writer.writeEmptyElement(QStringLiteral("fileVersion"));
459 writer.writeAttribute(QStringLiteral("appName"), QStringLiteral("xl"));
460 writer.writeAttribute(QStringLiteral("lastEdited"), QStringLiteral("4"));
461 writer.writeAttribute(QStringLiteral("lowestEdited"), QStringLiteral("4"));
462 writer.writeAttribute(QStringLiteral("rupBuild"), QStringLiteral("4505"));
463 // writer.writeAttribute(QStringLiteral("codeName"), QStringLiteral("{37E998C4-C9E5-D4B9-71C8-EB1FF731991C}"));
464
465 writer.writeEmptyElement(QStringLiteral("workbookPr"));
466 if (d->date1904)
467 writer.writeAttribute(QStringLiteral("date1904"), QStringLiteral("1"));
468 writer.writeAttribute(QStringLiteral("defaultThemeVersion"), QStringLiteral("124226"));
469
470 writer.writeStartElement(QStringLiteral("bookViews"));
471 writer.writeEmptyElement(QStringLiteral("workbookView"));
472 writer.writeAttribute(QStringLiteral("xWindow"), QString::number(d->x_window));
473 writer.writeAttribute(QStringLiteral("yWindow"), QString::number(d->y_window));
474 writer.writeAttribute(QStringLiteral("windowWidth"), QString::number(d->window_width));
475 writer.writeAttribute(QStringLiteral("windowHeight"), QString::number(d->window_height));
476 //Store the firstSheet when it isn't the default
477 //For example, when "the first sheet 0 is hidden", the first sheet will be 1
478 if (d->firstsheet > 0)
479 writer.writeAttribute(QStringLiteral("firstSheet"), QString::number(d->firstsheet + 1));
480 //Store the activeTab when it isn't the first sheet
481 if (d->activesheetIndex > 0)
482 writer.writeAttribute(QStringLiteral("activeTab"), QString::number(d->activesheetIndex));
483 writer.writeEndElement();//bookViews
484
485 writer.writeStartElement(QStringLiteral("sheets"));
486 int worksheetIndex = 0;
487 int chartsheetIndex = 0;
488 for (int i=0; i<d->sheets.size(); ++i) {
489 QSharedPointer<AbstractSheet> sheet = d->sheets[i];
490 writer.writeEmptyElement(QStringLiteral("sheet"));
491 writer.writeAttribute(QStringLiteral("name"), sheet->sheetName());
492 writer.writeAttribute(QStringLiteral("sheetId"), QString::number(sheet->sheetId()));
493 if (sheet->sheetState() == AbstractSheet::SS_Hidden)
494 writer.writeAttribute(QStringLiteral("state"), QStringLiteral("hidden"));
495 else if (sheet->sheetState() == AbstractSheet::SS_VeryHidden)
496 writer.writeAttribute(QStringLiteral("state"), QStringLiteral("veryHidden"));
497
498 if (sheet->sheetType() == AbstractSheet::ST_WorkSheet)
499 d->relationships->addDocumentRelationship(QStringLiteral("/worksheet"), QStringLiteral("worksheets/sheet%1.xml").arg(++worksheetIndex));
500 else
501 d->relationships->addDocumentRelationship(QStringLiteral("/chartsheet"), QStringLiteral("chartsheets/sheet%1.xml").arg(++chartsheetIndex));
502
503 writer.writeAttribute(QStringLiteral("r:id"), QStringLiteral("rId%1").arg(d->relationships->count()));
504 }
505 writer.writeEndElement();//sheets
506
507 if (d->externalLinks.size() > 0) {
508 writer.writeStartElement(QStringLiteral("externalReferences"));
509 for (int i=0; i<d->externalLinks.size(); ++i) {
510 writer.writeEmptyElement(QStringLiteral("externalReference"));
511 d->relationships->addDocumentRelationship(QStringLiteral("/externalLink"), QStringLiteral("externalLinks/externalLink%1.xml").arg(i+1));
512 writer.writeAttribute(QStringLiteral("r:id"), QStringLiteral("rId%1").arg(d->relationships->count()));
513 }
514 writer.writeEndElement();//externalReferences
515 }
516
517 if (!d->definedNamesList.isEmpty()) {
518 writer.writeStartElement(QStringLiteral("definedNames"));
519 foreach (XlsxDefineNameData data, d->definedNamesList) {
520 writer.writeStartElement(QStringLiteral("definedName"));
521 writer.writeAttribute(QStringLiteral("name"), data.name);
522 if (!data.comment.isEmpty())
523 writer.writeAttribute(QStringLiteral("comment"), data.comment);
524 if (data.sheetId != -1) {
525 //find the local index of the sheet.
526 for (int i=0; i<d->sheets.size(); ++i) {
527 if (d->sheets[i]->sheetId() == data.sheetId) {
528 writer.writeAttribute(QStringLiteral("localSheetId"), QString::number(i));
529 break;
530 }
531 }
532 }
533 writer.writeCharacters(data.formula);
534 writer.writeEndElement();//definedName
535 }
536 writer.writeEndElement();//definedNames
537 }
538
539 writer.writeStartElement(QStringLiteral("calcPr"));
540 writer.writeAttribute(QStringLiteral("calcId"), QStringLiteral("124519"));
541 writer.writeEndElement(); //calcPr
542
543 writer.writeEndElement();//workbook
544 writer.writeEndDocument();
545
546 d->relationships->addDocumentRelationship(QStringLiteral("/theme"), QStringLiteral("theme/theme1.xml"));
547 d->relationships->addDocumentRelationship(QStringLiteral("/styles"), QStringLiteral("styles.xml"));
548 if (!sharedStrings()->isEmpty())
549 d->relationships->addDocumentRelationship(QStringLiteral("/sharedStrings"), QStringLiteral("sharedStrings.xml"));
550 }
551
552 bool Workbook::loadFromXmlFile(QIODevice *device)
553 {
554 Q_D(Workbook);
555
556 QXmlStreamReader reader(device);
557 while (!reader.atEnd()) {
558 QXmlStreamReader::TokenType token = reader.readNext();
559 if (token == QXmlStreamReader::StartElement) {
560 if (reader.name() == QLatin1String("sheet")) {
561 QXmlStreamAttributes attributes = reader.attributes();
562 const QString name = attributes.value(QLatin1String("name")).toString();
563 int sheetId = attributes.value(QLatin1String("sheetId")).toString().toInt();
564 const QString rId = attributes.value(QLatin1String("r:id")).toString();
565 const QStringRef &stateString = attributes.value(QLatin1String("state"));
566 AbstractSheet::SheetState state = AbstractSheet::SS_Visible;
567 if (stateString == QLatin1String("hidden"))
568 state = AbstractSheet::SS_Hidden;
569 else if (stateString == QLatin1String("veryHidden"))
570 state = AbstractSheet::SS_VeryHidden;
571
572 XlsxRelationship relationship = d->relationships->getRelationshipById(rId);
573
574 AbstractSheet::SheetType type = AbstractSheet::ST_WorkSheet;
575 if (relationship.type.endsWith(QLatin1String("/worksheet")))
576 type = AbstractSheet::ST_WorkSheet;
577 else if (relationship.type.endsWith(QLatin1String("/chartsheet")))
578 type = AbstractSheet::ST_ChartSheet;
579 else if (relationship.type.endsWith(QLatin1String("/dialogsheet")))
580 type = AbstractSheet::ST_DialogSheet;
581 else if (relationship.type.endsWith(QLatin1String("/xlMacrosheet")))
582 type = AbstractSheet::ST_MacroSheet;
583 else
584 qWarning("unknown sheet type");
585
586 AbstractSheet *sheet = addSheet(name, sheetId, type);
587 sheet->setSheetState(state);
588 const QString fullPath = QDir::cleanPath(splitPath(filePath())[0] +QLatin1String("/")+ relationship.target);
589 sheet->setFilePath(fullPath);
590 } else if (reader.name() == QLatin1String("workbookPr")) {
591 QXmlStreamAttributes attrs = reader.attributes();
592 if (attrs.hasAttribute(QLatin1String("date1904")))
593 d->date1904 = true;
594 } else if (reader.name() == QLatin1String("bookviews")) {
595 while (!(reader.name() == QLatin1String("bookviews") && reader.tokenType() == QXmlStreamReader::EndElement)) {
596 reader.readNextStartElement();
597 if (reader.tokenType() == QXmlStreamReader::StartElement) {
598 if (reader.name() == QLatin1String("workbookView")) {
599 QXmlStreamAttributes attrs = reader.attributes();
600 if (attrs.hasAttribute(QLatin1String("xWindow")))
601 d->x_window = attrs.value(QLatin1String("xWindow")).toString().toInt();
602 if (attrs.hasAttribute(QLatin1String("yWindow")))
603 d->y_window = attrs.value(QLatin1String("yWindow")).toString().toInt();
604 if (attrs.hasAttribute(QLatin1String("windowWidth")))
605 d->window_width = attrs.value(QLatin1String("windowWidth")).toString().toInt();
606 if (attrs.hasAttribute(QLatin1String("windowHeight")))
607 d->window_height = attrs.value(QLatin1String("windowHeight")).toString().toInt();
608 if (attrs.hasAttribute(QLatin1String("firstSheet")))
609 d->firstsheet = attrs.value(QLatin1String("firstSheet")).toString().toInt();
610 if (attrs.hasAttribute(QLatin1String("activeTab")))
611 d->activesheetIndex = attrs.value(QLatin1String("activeTab")).toString().toInt();
612 }
613 }
614 }
615 } else if (reader.name() == QLatin1String("externalReference")) {
616 QXmlStreamAttributes attributes = reader.attributes();
617 const QString rId = attributes.value(QLatin1String("r:id")).toString();
618 XlsxRelationship relationship = d->relationships->getRelationshipById(rId);
619
620 QSharedPointer<SimpleOOXmlFile> link(new SimpleOOXmlFile(F_LoadFromExists));
621 const QString fullPath = QDir::cleanPath(splitPath(filePath())[0] +QLatin1String("/")+ relationship.target);
622 link->setFilePath(fullPath);
623 d->externalLinks.append(link);
624 } else if (reader.name() == QLatin1String("definedName")) {
625 QXmlStreamAttributes attrs = reader.attributes();
626 XlsxDefineNameData data;
627
628 data.name = attrs.value(QLatin1String("name")).toString();
629 if (attrs.hasAttribute(QLatin1String("comment")))
630 data.comment = attrs.value(QLatin1String("comment")).toString();
631 if (attrs.hasAttribute(QLatin1String("localSheetId"))) {
632 int localId = attrs.value(QLatin1String("localSheetId")).toString().toInt();
633 int sheetId = d->sheets.at(localId)->sheetId();
634 data.sheetId = sheetId;
635 }
636 data.formula = reader.readElementText();
637 d->definedNamesList.append(data);
638 }
639 }
640 }
641 return true;
642 }
643
644 /*!
645 * \internal
646 */
647 QList<QSharedPointer<MediaFile> > Workbook::mediaFiles() const
648 {
649 Q_D(const Workbook);
650
651 return d->mediaFiles;
652 }
653
654 /*!
655 * \internal
656 */
657 void Workbook::addMediaFile(QSharedPointer<MediaFile> media, bool force)
658 {
659 Q_D(Workbook);
660 if (!force) {
661 for (int i=0; i<d->mediaFiles.size(); ++i) {
662 if (d->mediaFiles[i]->hashKey() == media->hashKey()) {
663 media->setIndex(i);
664 return;
665 }
666 }
667 }
668 media->setIndex(d->mediaFiles.size());
669 d->mediaFiles.append(media);
670 }
671
672 /*!
673 * \internal
674 */
675 QList<QSharedPointer<Chart> > Workbook::chartFiles() const
676 {
677 Q_D(const Workbook);
678
679 return d->chartFiles;
680 }
681
682 /*!
683 * \internal
684 */
685 void Workbook::addChartFile(QSharedPointer<Chart> chart)
686 {
687 Q_D(Workbook);
688
689 if (!d->chartFiles.contains(chart))
690 d->chartFiles.append(chart);
691 }
692
693 QT_END_NAMESPACE_XLSX
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)