diff --git a/src/xlsx/qtxlsx.pri b/src/xlsx/qtxlsx.pri index b9d3364..1058864 100755 --- a/src/xlsx/qtxlsx.pri +++ b/src/xlsx/qtxlsx.pri @@ -16,7 +16,6 @@ HEADERS += $$PWD/xlsxdocpropscore_p.h \ $$PWD/xlsxstyles_p.h \ $$PWD/xlsxworksheet.h \ $$PWD/xlsxzipwriter_p.h \ - $$PWD/xlsxpackage_p.h \ $$PWD/xlsxworkbook_p.h \ $$PWD/xlsxworksheet_p.h \ $$PWD/xlsxformat_p.h \ @@ -49,7 +48,6 @@ SOURCES += $$PWD/xlsxdocpropscore.cpp \ $$PWD/xlsxworkbook.cpp \ $$PWD/xlsxworksheet.cpp \ $$PWD/xlsxzipwriter.cpp \ - $$PWD/xlsxpackage.cpp \ $$PWD/xlsxdrawing.cpp \ $$PWD/xlsxzipreader.cpp \ $$PWD/xlsxdocument.cpp \ diff --git a/src/xlsx/xlsxdocument.cpp b/src/xlsx/xlsxdocument.cpp index 9c1b879..8f8bd21 100644 --- a/src/xlsx/xlsxdocument.cpp +++ b/src/xlsx/xlsxdocument.cpp @@ -27,13 +27,60 @@ #include "xlsxdocument_p.h" #include "xlsxworkbook.h" #include "xlsxworksheet.h" -#include "xlsxpackage_p.h" +#include "xlsxcontenttypes_p.h" +#include "xlsxrelationships_p.h" +#include "xlsxstyles_p.h" +#include "xlsxtheme_p.h" +#include "xlsxdocpropsapp_p.h" +#include "xlsxdocpropscore_p.h" +#include "xlsxsharedstrings_p.h" +#include "xlsxutility_p.h" +#include "xlsxworkbook_p.h" +#include "xlsxdrawing_p.h" +#include "xlsxzipreader_p.h" +#include "xlsxzipwriter_p.h" #include #include +#include QT_BEGIN_NAMESPACE_XLSX +/* + From Wikipedia: The Open Packaging Conventions (OPC) is a + container-file technology initially created by Microsoft to store + a combination of XML and non-XML files that together form a single + entity such as an Open XML Paper Specification (OpenXPS) + document. http://en.wikipedia.org/wiki/Open_Packaging_Conventions. + + At its simplest an Excel XLSX file contains the following elements: + + ____ [Content_Types].xml + | + |____ docProps + | |____ app.xml + | |____ core.xml + | + |____ xl + | |____ workbook.xml + | |____ worksheets + | | |____ sheet1.xml + | | + | |____ styles.xml + | | + | |____ theme + | | |____ theme1.xml + | | + | |_____rels + | |____ workbook.xml.rels + | + |_____rels + |____ .rels + + The Packager class coordinates the classes that represent the + elements of the package and writes them into the XLSX file. +*/ + DocumentPrivate::DocumentPrivate(Document *p) : q_ptr(p), defaultPackageName(QStringLiteral("Book1.xlsx")) { @@ -49,8 +96,206 @@ void DocumentPrivate::init() bool DocumentPrivate::loadPackage(QIODevice *device) { Q_Q(Document); - Package package(q); - return package.parsePackage(device); + ZipReader zipReader(device); + QStringList filePaths = zipReader.filePaths(); + + if (!filePaths.contains(QLatin1String("_rels/.rels"))) + return false; + + Relationships rootRels; + rootRels.loadFromXmlData(zipReader.fileData(QStringLiteral("_rels/.rels"))); + + //load core property + QList 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()) + q->setDocumentProperty(name, props.property(name)); + } + + //load app property + QList 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()) + q->setDocumentProperty(name, props.property(name)); + } + + //load workbook now, Get the workbook file path from the root rels file + //In normal case, this should be "xl/workbook.xml" + QList rels_xl = rootRels.documentRelationships(QStringLiteral("/officeDocument")); + 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]; + workbook->loadFromXmlData(zipReader.fileData(xlworkbook_Path)); + QList sheetNameIdPairList = workbook->d_func()->sheetItemInfoList; + Relationships xlworkbook_Rels; + xlworkbook_Rels.loadFromXmlData(zipReader.fileData(xlworkbook_Dir+QStringLiteral("/_rels/")+xlworkbook_Name+QStringLiteral(".rels"))); + + //load styles + QList rels_styles = xlworkbook_Rels.documentRelationships(QStringLiteral("/styles")); + if (!rels_styles.isEmpty()) { + //In normal case this should be styles.xml which in xl + QString name = rels_styles[0].target; + QString path = xlworkbook_Dir + QLatin1String("/") + name; + QSharedPointer styles (new Styles(true)); + styles->loadFromXmlData(zipReader.fileData(path)); + workbook->d_ptr->styles = styles; + } + + //load sharedStrings + QList 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; + workbook->d_ptr->sharedStrings->loadFromXmlData(zipReader.fileData(path)); + } + + //load theme + QList rels_theme = xlworkbook_Rels.documentRelationships(QStringLiteral("/theme")); + if (!rels_theme.isEmpty()) { + //In normal case this should be theme/theme1.xml which in xl + QString name = rels_theme[0].target; + QString path = xlworkbook_Dir + QLatin1String("/") + name; + workbook->theme()->loadFromXmlData(zipReader.fileData(path)); + } + + //load worksheets + QList rels_worksheets = xlworkbook_Rels.documentRelationships(QStringLiteral("/worksheet")); + if (rels_worksheets.isEmpty()) + return false; + + for (int i=0; iaddWorksheet(info.name, info.sheetId); + //If the .rel file exists, load it. + if (zipReader.filePaths().contains(rel_path)) + sheet->relationships().loadFromXmlData(zipReader.fileData(rel_path)); + sheet->loadFromXmlData(zipReader.fileData(worksheet_path)); + } + + return true; +} + +bool DocumentPrivate::savePackage(QIODevice *device) +{ + Q_Q(Document); + ZipWriter zipWriter(device); + if (zipWriter.error()) + return false; + + ContentTypes contentTypes; + DocPropsApp docPropsApp; + DocPropsCore docPropsCore; + + workbook->prepareDrawings(); + + // save worksheet xml files + for (int i=0; iworksheetCount(); ++i) { + Worksheet *sheet = workbook->worksheet(i); + contentTypes.addWorksheetName(QStringLiteral("sheet%1").arg(i+1)); + docPropsApp.addPartTitle(sheet->sheetName()); + + zipWriter.addFile(QStringLiteral("xl/worksheets/sheet%1.xml").arg(i+1), sheet->saveToXmlData()); + Relationships &rel = sheet->relationships(); + if (!rel.isEmpty()) + zipWriter.addFile(QStringLiteral("xl/worksheets/_rels/sheet%1.xml.rels").arg(i+1), rel.saveToXmlData()); + } + + // save workbook xml file + zipWriter.addFile(QStringLiteral("xl/workbook.xml"), workbook->saveToXmlData()); + Relationships rels; + for (int i=0; iworksheetCount(); ++i) + rels.addDocumentRelationship(QStringLiteral("/worksheet"), QStringLiteral("worksheets/sheet%1.xml").arg(i+1)); + rels.addDocumentRelationship(QStringLiteral("/theme"), QStringLiteral("theme/theme1.xml")); + rels.addDocumentRelationship(QStringLiteral("/styles"), QStringLiteral("styles.xml")); + if (!workbook->sharedStrings()->isEmpty()) + rels.addDocumentRelationship(QStringLiteral("/sharedStrings"), QStringLiteral("sharedStrings.xml")); + zipWriter.addFile(QStringLiteral("xl/_rels/workbook.xml.rels"), rels.saveToXmlData()); + + // save drawing xml files + for (int i=0; idrawings().size(); ++i) { + contentTypes.addDrawingName(QStringLiteral("drawing%1").arg(i+1)); + + Drawing *drawing = workbook->drawings()[i]; + zipWriter.addFile(QStringLiteral("xl/drawings/drawing%1.xml").arg(i+1), drawing->saveToXmlData()); + } + + for (int i=0; iworksheetCount(); ++i) { + Worksheet *sheet = workbook->worksheet(i); + if (sheet->drawingLinks().size() == 0) + continue; + Relationships rels; + + typedef QPair PairType; + foreach (PairType pair, sheet->drawingLinks()) + rels.addDocumentRelationship(pair.first, pair.second); + + zipWriter.addFile(QStringLiteral("xl/drawings/_rels/drawing%1.xml.rels").arg(i+1), rels.saveToXmlData()); + } + + // save docProps app/core xml file + foreach (QString name, q->documentPropertyNames()) { + docPropsApp.setProperty(name, q->documentProperty(name)); + docPropsCore.setProperty(name, q->documentProperty(name)); + } + if (workbook->worksheetCount()) + docPropsApp.addHeadingPair(QStringLiteral("Worksheets"), workbook->worksheetCount()); + zipWriter.addFile(QStringLiteral("docProps/app.xml"), docPropsApp.saveToXmlData()); + zipWriter.addFile(QStringLiteral("docProps/core.xml"), docPropsCore.saveToXmlData()); + + // save sharedStrings xml file + if (!workbook->sharedStrings()->isEmpty()) { + contentTypes.addSharedString(); + zipWriter.addFile(QStringLiteral("xl/sharedStrings.xml"), workbook->sharedStrings()->saveToXmlData()); + } + + // save styles xml file + zipWriter.addFile(QStringLiteral("xl/styles.xml"), workbook->styles()->saveToXmlData()); + + // save theme xml file + zipWriter.addFile(QStringLiteral("xl/theme/theme1.xml"), workbook->theme()->saveToXmlData()); + + // save image files + if (!workbook->images().isEmpty()) + contentTypes.addImageTypes(QStringList()<images().size(); ++i) { + QImage image = workbook->images()[i]; + + QByteArray data; + QBuffer buffer(&data); + buffer.open(QIODevice::WriteOnly); + image.save(&buffer, "png"); + zipWriter.addFile(QStringLiteral("xl/media/image%1.png").arg(i+1), data); + } + + // save root .rels xml file + Relationships rootrels; + rootrels.addDocumentRelationship(QStringLiteral("/officeDocument"), QStringLiteral("xl/workbook.xml")); + rootrels.addPackageRelationship(QStringLiteral("/metadata/core-properties"), QStringLiteral("docProps/core.xml")); + rootrels.addDocumentRelationship(QStringLiteral("/extended-properties"), QStringLiteral("docProps/app.xml")); + zipWriter.addFile(QStringLiteral("_rels/.rels"), rootrels.saveToXmlData()); + + // save content types xml file + zipWriter.addFile(QStringLiteral("[Content_Types].xml"), contentTypes.saveToXmlData()); + + zipWriter.close(); + return true; } @@ -505,12 +750,8 @@ bool Document::saveAs(const QString &name) */ bool Document::saveAs(QIODevice *device) { -// activedWorksheet()->setHidden(false); -// activedWorksheet()->setSelected(true); - - //Create the package based on current workbook - Package package(this); - return package.createPackage(device); + Q_D(Document); + return d->savePackage(device); } /*! diff --git a/src/xlsx/xlsxdocument.h b/src/xlsx/xlsxdocument.h index 7b67d4b..f52e12a 100644 --- a/src/xlsx/xlsxdocument.h +++ b/src/xlsx/xlsxdocument.h @@ -37,7 +37,6 @@ QT_BEGIN_NAMESPACE_XLSX class Workbook; class Worksheet; -class Package; class Cell; class CellRange; class DataValidation; @@ -103,7 +102,6 @@ public: bool saveAs(QIODevice *device); private: - friend class Package; Q_DISABLE_COPY(Document) DocumentPrivate * const d_ptr; }; diff --git a/src/xlsx/xlsxdocument_p.h b/src/xlsx/xlsxdocument_p.h index c6de373..c3262f4 100644 --- a/src/xlsx/xlsxdocument_p.h +++ b/src/xlsx/xlsxdocument_p.h @@ -52,6 +52,7 @@ public: void init(); bool loadPackage(QIODevice *device); + bool savePackage(QIODevice *device); Document *q_ptr; const QString defaultPackageName; //default name when package name not specified diff --git a/src/xlsx/xlsxpackage.cpp b/src/xlsx/xlsxpackage.cpp deleted file mode 100644 index 3f30c2b..0000000 --- a/src/xlsx/xlsxpackage.cpp +++ /dev/null @@ -1,382 +0,0 @@ -/**************************************************************************** -** Copyright (c) 2013-2014 Debao Zhang -** 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 "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" -#include "xlsxdocpropsapp_p.h" -#include "xlsxtheme_p.h" -#include "xlsxstyles_p.h" -#include "xlsxrelationships_p.h" -#include "xlsxzipwriter_p.h" -#include "xlsxdrawing_p.h" -#include "xlsxzipreader_p.h" -#include "xlsxdocument.h" -#include "xlsxformat_p.h" -#include -#include -#include -#include - -namespace QXlsx { - -//: TODO This class should be merged to Document class. - -/* - From Wikipedia: The Open Packaging Conventions (OPC) is a - container-file technology initially created by Microsoft to store - a combination of XML and non-XML files that together form a single - entity such as an Open XML Paper Specification (OpenXPS) - document. http://en.wikipedia.org/wiki/Open_Packaging_Conventions. - - At its simplest an Excel XLSX file contains the following elements: - - ____ [Content_Types].xml - | - |____ docProps - | |____ app.xml - | |____ core.xml - | - |____ xl - | |____ workbook.xml - | |____ worksheets - | | |____ sheet1.xml - | | - | |____ styles.xml - | | - | |____ theme - | | |____ theme1.xml - | | - | |_____rels - | |____ workbook.xml.rels - | - |_____rels - |____ .rels - - The Packager class coordinates the classes that represent the - elements of the package and writes them into the XLSX file. -*/ - -Package::Package(Document *document) : - m_document(document) -{ - m_workbook = m_document->workbook(); - m_worksheet_count = 0; - m_chartsheet_count = 0; - for (int i=0; iworksheetCount(); ++i) { - Worksheet *sheet = m_workbook->worksheet(i); - if (sheet->isChartsheet()) - m_chartsheet_count += 1; - else - m_worksheet_count += 1; - } -} - -bool Package::parsePackage(QIODevice *packageDevice) -{ - ZipReader zipReader(packageDevice); - QStringList filePaths = zipReader.filePaths(); - - if (!filePaths.contains(QLatin1String("_rels/.rels"))) - return false; - - Relationships rootRels; - rootRels.loadFromXmlData(zipReader.fileData(QStringLiteral("_rels/.rels"))); - - //load core property - QList 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 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, Get the workbook file path from the root rels file - //In normal case, this should be "xl/workbook.xml" - QList rels_xl = rootRels.documentRelationships(QStringLiteral("/officeDocument")); - 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]; - m_document->workbook()->loadFromXmlData(zipReader.fileData(xlworkbook_Path)); - QList sheetNameIdPairList = m_document->workbook()->d_func()->sheetItemInfoList; - Relationships xlworkbook_Rels; - xlworkbook_Rels.loadFromXmlData(zipReader.fileData(xlworkbook_Dir+QStringLiteral("/_rels/")+xlworkbook_Name+QStringLiteral(".rels"))); - - //load styles - QList rels_styles = xlworkbook_Rels.documentRelationships(QStringLiteral("/styles")); - if (!rels_styles.isEmpty()) { - //In normal case this should be styles.xml which in xl - QString name = rels_styles[0].target; - QString path = xlworkbook_Dir + QLatin1String("/") + name; - QSharedPointer styles (new Styles(true)); - styles->loadFromXmlData(zipReader.fileData(path)); - m_document->workbook()->d_ptr->styles = styles; - } - - //load sharedStrings - QList 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; - m_document->workbook()->d_ptr->sharedStrings->loadFromXmlData(zipReader.fileData(path)); - } - - //load theme - QList rels_theme = xlworkbook_Rels.documentRelationships(QStringLiteral("/theme")); - if (!rels_theme.isEmpty()) { - //In normal case this should be theme/theme1.xml which in xl - QString name = rels_theme[0].target; - QString path = xlworkbook_Dir + QLatin1String("/") + name; - m_document->workbook()->theme()->loadFromXmlData(zipReader.fileData(path)); - } - - //load worksheets - QList rels_worksheets = xlworkbook_Rels.documentRelationships(QStringLiteral("/worksheet")); - if (rels_worksheets.isEmpty()) - return false; - - for (int i=0; iworkbook()->addWorksheet(info.name, info.sheetId); - //If the .rel file exists, load it. - if (zipReader.filePaths().contains(rel_path)) - sheet->relationships().loadFromXmlData(zipReader.fileData(rel_path)); - sheet->loadFromXmlData(zipReader.fileData(worksheet_path)); - } - - return true; -} - -bool Package::createPackage(QIODevice *package) -{ - ZipWriter zipWriter(package); - if (zipWriter.error()) - return false; - - m_workbook->prepareDrawings(); - - writeWorksheetFiles(zipWriter); - zipWriter.addFile(QStringLiteral("xl/workbook.xml"), m_workbook->saveToXmlData()); - writeDrawingFiles(zipWriter); - writeDocPropsAppFile(zipWriter); - writeDocPropsCoreFile(zipWriter); - writeContentTypesFile(zipWriter); - - if (!m_workbook->sharedStrings()->isEmpty()) - zipWriter.addFile(QStringLiteral("xl/sharedStrings.xml"), m_workbook->sharedStrings()->saveToXmlData()); - zipWriter.addFile(QStringLiteral("xl/styles.xml"), m_workbook->styles()->saveToXmlData()); - zipWriter.addFile(QStringLiteral("xl/theme/theme1.xml"), m_workbook->theme()->saveToXmlData()); - - writeRootRelsFile(zipWriter); - writeWorkbookRelsFile(zipWriter); - writeDrawingRelsFiles(zipWriter); - writeImageFiles(zipWriter); - - zipWriter.close(); - return true; -} - -void Package::writeWorksheetFiles(ZipWriter &zipWriter) -{ - for (int i=0; iworksheetCount(); ++i) { - Worksheet *sheet = m_workbook->worksheet(i); - if (sheet->isChartsheet()) - continue; - - zipWriter.addFile(QStringLiteral("xl/worksheets/sheet%1.xml").arg(i+1), sheet->saveToXmlData()); - Relationships &rel = sheet->relationships(); - if (!rel.isEmpty()) - zipWriter.addFile(QStringLiteral("xl/worksheets/_rels/sheet%1.xml.rels").arg(i+1), rel.saveToXmlData()); - } -} - -void Package::writeDrawingFiles(ZipWriter &zipWriter) -{ - for (int i=0; idrawings().size(); ++i) { - Drawing *drawing = m_workbook->drawings()[i]; - zipWriter.addFile(QStringLiteral("xl/drawings/drawing%1.xml").arg(i+1), drawing->saveToXmlData()); - } -} - -void Package::writeContentTypesFile(ZipWriter &zipWriter) -{ - ContentTypes content; - - for (int i=0; iworksheetCount(); ++i) { - Worksheet *sheet = m_workbook->worksheet(i); - if (sheet->isChartsheet()) { - - } else { - content.addWorksheetName(QStringLiteral("sheet%1").arg(i+1)); - } - } - - int drawing_index = 1; - foreach (Drawing *drawing, m_workbook->drawings()) { - Q_UNUSED(drawing); - content.addDrawingName(QStringLiteral("drawing%1").arg(drawing_index)); - drawing_index += 1; - } - - if (!m_workbook->images().isEmpty()) - content.addImageTypes(QStringList()<sharedStrings()->count()) - content.addSharedString(); - - zipWriter.addFile(QStringLiteral("[Content_Types].xml"), content.saveToXmlData()); -} - -void Package::writeDocPropsAppFile(ZipWriter &zipWriter) -{ - DocPropsApp props; - - foreach (QString name, m_document->documentPropertyNames()) - props.setProperty(name, m_document->documentProperty(name)); - - if (m_worksheet_count) - props.addHeadingPair(QStringLiteral("Worksheets"), m_worksheet_count); - if (m_chartsheet_count) - props.addHeadingPair(QStringLiteral("Chartsheets"), m_chartsheet_count); - - //Add worksheet parts - for (int i=0; iworksheetCount(); ++i) { - Worksheet *sheet = m_workbook->worksheet(i); - if (!sheet->isChartsheet()) - props.addPartTitle(sheet->sheetName()); - } - - //Add the chartsheet parts - for (int i=0; iworksheetCount(); ++i) { - Worksheet *sheet = m_workbook->worksheet(i); - if (sheet->isChartsheet()) - props.addPartTitle(sheet->sheetName()); - } - - zipWriter.addFile(QStringLiteral("docProps/app.xml"), props.saveToXmlData()); -} - -void Package::writeDocPropsCoreFile(ZipWriter &zipWriter) -{ - DocPropsCore props; - - foreach (QString name, m_document->documentPropertyNames()) - props.setProperty(name, m_document->documentProperty(name)); - - zipWriter.addFile(QStringLiteral("docProps/core.xml"), props.saveToXmlData()); -} - -void Package::writeRootRelsFile(ZipWriter &zipWriter) -{ - Relationships rels; - rels.addDocumentRelationship(QStringLiteral("/officeDocument"), QStringLiteral("xl/workbook.xml")); - rels.addPackageRelationship(QStringLiteral("/metadata/core-properties"), QStringLiteral("docProps/core.xml")); - rels.addDocumentRelationship(QStringLiteral("/extended-properties"), QStringLiteral("docProps/app.xml")); - - zipWriter.addFile(QStringLiteral("_rels/.rels"), rels.saveToXmlData()); -} - -void Package::writeWorkbookRelsFile(ZipWriter &zipWriter) -{ - Relationships rels; - - int worksheet_index = 1; - int chartsheet_index = 1; - for (int i=0; iworksheetCount(); ++i) { - Worksheet *sheet = m_workbook->worksheet(i); - if (sheet->isChartsheet()) { - rels.addDocumentRelationship(QStringLiteral("/chartsheet"), QStringLiteral("chartsheets/sheet%1.xml").arg(chartsheet_index)); - chartsheet_index += 1; - } else { - rels.addDocumentRelationship(QStringLiteral("/worksheet"), QStringLiteral("worksheets/sheet%1.xml").arg(worksheet_index)); - worksheet_index += 1; - } - } - - rels.addDocumentRelationship(QStringLiteral("/theme"), QStringLiteral("theme/theme1.xml")); - rels.addDocumentRelationship(QStringLiteral("/styles"), QStringLiteral("styles.xml")); - - if (!m_workbook->sharedStrings()->isEmpty()) - rels.addDocumentRelationship(QStringLiteral("/sharedStrings"), QStringLiteral("sharedStrings.xml")); - - zipWriter.addFile(QStringLiteral("xl/_rels/workbook.xml.rels"), rels.saveToXmlData()); -} - -void Package::writeDrawingRelsFiles(ZipWriter &zipWriter) -{ - for (int i=0; iworksheetCount(); ++i) { - Worksheet *sheet = m_workbook->worksheet(i); - if (sheet->drawingLinks().size() == 0) - continue; - Relationships rels; - - typedef QPair PairType; - foreach (PairType pair, sheet->drawingLinks()) - rels.addDocumentRelationship(pair.first, pair.second); - - zipWriter.addFile(QStringLiteral("xl/drawings/_rels/drawing%1.xml.rels").arg(i+1), rels.saveToXmlData()); - } -} - -void Package::writeImageFiles(ZipWriter &zipWriter) -{ - for (int i=0; iimages().size(); ++i) { - QImage image = m_workbook->images()[i]; - - QByteArray data; - QBuffer buffer(&data); - buffer.open(QIODevice::WriteOnly); - image.save(&buffer, "png"); - zipWriter.addFile(QStringLiteral("xl/media/image%1.png").arg(i+1), data); - } -} - -} // namespace QXlsx diff --git a/src/xlsx/xlsxpackage_p.h b/src/xlsx/xlsxpackage_p.h deleted file mode 100644 index afe3d8c..0000000 --- a/src/xlsx/xlsxpackage_p.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** Copyright (c) 2013-2014 Debao Zhang -** 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. -** -****************************************************************************/ -#ifndef QXLSX_PACKAGE_H -#define QXLSX_PACKAGE_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt Xlsx API. It exists for the convenience -// of the Qt Xlsx. This header file may change from -// version to version without notice, or even be removed. -// -// We mean it. -// - -#include "xlsxglobal.h" -#include -class QIODevice; - -namespace QXlsx { - -class Workbook; -class ZipWriter; -class ZipReader; -class Document; -class Relationships; -class DocPropsCore; -class DocPropsApp; - -class XLSX_AUTOTEST_EXPORT Package -{ -public: - Package(Document *document); - - bool parsePackage(QIODevice *packageDevice); - bool createPackage(QIODevice *package); - -private: - - void writeWorksheetFiles(ZipWriter &zipWriter); - void writeDrawingFiles(ZipWriter &zipWriter); - void writeDocPropsAppFile(ZipWriter &zipWriter); - void writeDocPropsCoreFile(ZipWriter &zipWriter); - void writeContentTypesFile(ZipWriter &zipWriter); - void writeRootRelsFile(ZipWriter &zipWriter); - void writeWorkbookRelsFile(ZipWriter &zipWriter); - void writeDrawingRelsFiles(ZipWriter &zipWriter); - void writeImageFiles(ZipWriter &zipWriter); - - Document *m_document; - Workbook *m_workbook; - int m_worksheet_count; - int m_chartsheet_count; -}; - -} // namespace QXlsx - -#endif // QXLSX_PACKAGE_H diff --git a/src/xlsx/xlsxworkbook.cpp b/src/xlsx/xlsxworkbook.cpp index 631f790..046c347 100755 --- a/src/xlsx/xlsxworkbook.cpp +++ b/src/xlsx/xlsxworkbook.cpp @@ -28,7 +28,6 @@ #include "xlsxworksheet.h" #include "xlsxstyles_p.h" #include "xlsxformat.h" -#include "xlsxpackage_p.h" #include "xlsxworksheet_p.h" #include "xlsxformat_p.h" diff --git a/src/xlsx/xlsxworkbook.h b/src/xlsx/xlsxworkbook.h index 14ac4a7..cd49942 100755 --- a/src/xlsx/xlsxworkbook.h +++ b/src/xlsx/xlsxworkbook.h @@ -37,7 +37,6 @@ QT_BEGIN_NAMESPACE_XLSX class Worksheet; class SharedStrings; class Styles; -class Package; class Drawing; class Document; class Theme; @@ -74,7 +73,6 @@ public: void setDefaultDateFormat(const QString &format); private: - friend class Package; friend class Worksheet; friend class WorksheetPrivate; friend class Document; diff --git a/src/xlsx/xlsxworksheet.cpp b/src/xlsx/xlsxworksheet.cpp index 7e4cf33..8086601 100755 --- a/src/xlsx/xlsxworksheet.cpp +++ b/src/xlsx/xlsxworksheet.cpp @@ -244,6 +244,9 @@ void Worksheet::setSheetName(const QString &sheetName) d->name = sheetName; } +/*! + * \internal + */ Relationships &Worksheet::relationships() { Q_D(Worksheet); diff --git a/src/xlsx/xlsxworksheet.h b/src/xlsx/xlsxworksheet.h index 841921c..7a34868 100755 --- a/src/xlsx/xlsxworksheet.h +++ b/src/xlsx/xlsxworksheet.h @@ -40,7 +40,7 @@ class QImage; class WorksheetTest; QT_BEGIN_NAMESPACE_XLSX -class Package; +class DocumentPrivate; class Workbook; class Format; class Drawing; @@ -129,15 +129,15 @@ public: QString sheetName() const; Workbook *workbook() const; + Relationships &relationships(); ~Worksheet(); private: - friend class Package; + friend class DocumentPrivate; friend class Workbook; friend class ::WorksheetTest; Worksheet(const QString &sheetName, int sheetId, Workbook *book); QSharedPointer copy(const QString &distName, int distId) const; void setSheetName(const QString &sheetName); - Relationships &relationships(); void saveToXmlFile(QIODevice *device) const; QByteArray saveToXmlData() const;