diff --git a/examples/xlsx/hyperlinks/hyperlinks.pro b/examples/xlsx/hyperlinks/hyperlinks.pro new file mode 100644 index 0000000..c64e480 --- /dev/null +++ b/examples/xlsx/hyperlinks/hyperlinks.pro @@ -0,0 +1,9 @@ +TARGET = hyperlinks + +#include(../../../src/xlsx/qtxlsx.pri) +QT+=xlsx + +CONFIG += console +CONFIG -= app_bundle + +SOURCES += main.cpp diff --git a/examples/xlsx/hyperlinks/main.cpp b/examples/xlsx/hyperlinks/main.cpp new file mode 100644 index 0000000..74333cc --- /dev/null +++ b/examples/xlsx/hyperlinks/main.cpp @@ -0,0 +1,25 @@ +#include +#include "xlsxdocument.h" + +int main() +{ + //![0] + QXlsx::Document xlsx; + //![0] + + //![1] + xlsx.write("A1", "http://qt-project.org"); + xlsx.write("A2", "http://qt-project.org/wiki#0f68b904e33d9ac04605aecc958bcf52"); + xlsx.write("A3", "mailto:info@qt-project.org"); + xlsx.write("A4", "file:///C:/User/test/abc.txt"); + //![1] + + //![2] + xlsx.save(); + //![2] + + QXlsx::Document xlsx2("Book1.xlsx"); + xlsx2.saveAs("Book2.xlsx"); + + return 0; +} diff --git a/examples/xlsx/xlsx.pro b/examples/xlsx/xlsx.pro index 8a212d0..2137c0c 100644 --- a/examples/xlsx/xlsx.pro +++ b/examples/xlsx/xlsx.pro @@ -13,5 +13,6 @@ SUBDIRS = hello \ richtext \ conditionalformatting \ worksheetoperations \ + hyperlinks \ demo diff --git a/src/xlsx/xlsxworksheet.cpp b/src/xlsx/xlsxworksheet.cpp index d56b924..a318f66 100755 --- a/src/xlsx/xlsxworksheet.cpp +++ b/src/xlsx/xlsxworksheet.cpp @@ -945,7 +945,7 @@ int Worksheet::writeHyperlink(const QString &row_column, const QUrl &url, const } /*! - Write a QUrl \a value to the cell (\a row, \a column) with the \a format + Write a QUrl \a url to the cell (\a row, \a column) with the given \a format */ int Worksheet::writeHyperlink(int row, int column, const QUrl &url, const Format &format, const QString &display, const QString &tip) { @@ -993,7 +993,7 @@ int Worksheet::writeHyperlink(int row, int column, const QUrl &url, const Format d->cellTable[row][column] = QSharedPointer(new Cell(displayString, Cell::String, fmt, this)); //Store the hyperlink data in a separate table - d->urlTable[row][column] = new XlsxHyperlinkData(XlsxHyperlinkData::External, urlString, locationString, tip); + d->urlTable[row][column] = QSharedPointer(new XlsxHyperlinkData(XlsxHyperlinkData::External, urlString, locationString, QString(), tip)); return error; } @@ -1390,36 +1390,31 @@ void WorksheetPrivate::saveXmlHyperlinks(QXmlStreamWriter &writer) const return; writer.writeStartElement(QStringLiteral("hyperlinks")); - QMapIterator > it(urlTable); + QMapIterator > > it(urlTable); while (it.hasNext()) { it.next(); int row = it.key(); - QMapIterator it2(it.value()); + QMapIterator > it2(it.value()); while (it2.hasNext()) { it2.next(); int col = it2.key(); - XlsxHyperlinkData *data = it2.value(); + QSharedPointer data = it2.value(); QString ref = xl_rowcol_to_cell(row, col); writer.writeEmptyElement(QStringLiteral("hyperlink")); writer.writeAttribute(QStringLiteral("ref"), ref); if (data->linkType == XlsxHyperlinkData::External) { - //Update relationships - relationships.addWorksheetRelationship(QStringLiteral("/hyperlink"), data->url, QStringLiteral("External")); + relationships.addWorksheetRelationship(QStringLiteral("/hyperlink"), data->target, QStringLiteral("External")); writer.writeAttribute(QStringLiteral("r:id"), QStringLiteral("rId%1").arg(relationships.count())); - if (!data->location.isEmpty()) - writer.writeAttribute(QStringLiteral("location"), data->location); - if (!data->display.isEmpty()) - writer.writeAttribute(QStringLiteral("display"), data->url); - if (!data->tip.isEmpty()) - writer.writeAttribute(QStringLiteral("tooltip"), data->tip); - } else { - writer.writeAttribute(QStringLiteral("location"), data->url); - if (!data->tip.isEmpty()) - writer.writeAttribute(QStringLiteral("tooltip"), data->tip); - writer.writeAttribute(QStringLiteral("display"), data->location); } + + if (!data->location.isEmpty()) + writer.writeAttribute(QStringLiteral("location"), data->location); + if (!data->display.isEmpty()) + writer.writeAttribute(QStringLiteral("display"), data->display); + if (!data->tooltip.isEmpty()) + writer.writeAttribute(QStringLiteral("tooltip"), data->tooltip); } } @@ -2155,6 +2150,36 @@ void WorksheetPrivate::loadXmlSheetViews(QXmlStreamReader &reader) } } +void WorksheetPrivate::loadXmlHyperlinks(QXmlStreamReader &reader) +{ + Q_ASSERT(reader.name() == QLatin1String("hyperlinks")); + + while (!reader.atEnd() && !(reader.name() == QLatin1String("hyperlinks") + && reader.tokenType() == QXmlStreamReader::EndElement)) { + reader.readNextStartElement(); + if (reader.tokenType() == QXmlStreamReader::StartElement && reader.name() == QLatin1String("hyperlink")) { + QXmlStreamAttributes attrs = reader.attributes(); + QPoint pos = xl_cell_to_rowcol(attrs.value(QLatin1String("ref")).toString()); + if (pos.x() != -1) { //Valid + QSharedPointer link(new XlsxHyperlinkData); + link->display = attrs.value(QLatin1String("display")).toString(); + link->tooltip = attrs.value(QLatin1String("tooltip")).toString(); + link->location = attrs.value(QLatin1String("location")).toString(); + + if (attrs.hasAttribute(QLatin1String("r:id"))) { + link->linkType = XlsxHyperlinkData::External; + XlsxRelationship ship = relationships.getRelationshipById(attrs.value(QLatin1String("r:id")).toString()); + link->target = ship.target; + } else { + link->linkType = XlsxHyperlinkData::Internal; + } + + urlTable[pos.x()][pos.y()] = link; + } + } + } +} + bool Worksheet::loadFromXmlFile(QIODevice *device) { Q_D(Worksheet); @@ -2183,6 +2208,8 @@ bool Worksheet::loadFromXmlFile(QIODevice *device) ConditionalFormatting cf; cf.loadFromXml(reader, workbook()->styles()); d->conditionalFormattingList.append(cf); + } else if (reader.name() == QLatin1String("hyperlinks")) { + d->loadXmlHyperlinks(reader); } } } diff --git a/src/xlsx/xlsxworksheet_p.h b/src/xlsx/xlsxworksheet_p.h index cb30253..15346a2 100644 --- a/src/xlsx/xlsxworksheet_p.h +++ b/src/xlsx/xlsxworksheet_p.h @@ -65,17 +65,18 @@ struct XlsxHyperlinkData Internal }; - XlsxHyperlinkData(LinkType linkType=External, const QString &url=QString(), const QString &location=QString(), const QString &tip=QString()) : - linkType(linkType), url(url), location(location), tip(tip) + XlsxHyperlinkData(LinkType linkType=External, const QString &target=QString(), const QString &location=QString() + , const QString &display=QString(), const QString &tip=QString()) + :linkType(linkType), target(target), location(location), display(display), tooltip(tip) { } LinkType linkType; - QString url; - QString location; //location string + QString target; //For External link + QString location; QString display; - QString tip; + QString tooltip; }; struct XlsxImageData @@ -201,6 +202,7 @@ public: void loadXmlMergeCells(QXmlStreamReader &reader); void loadXmlDataValidations(QXmlStreamReader &reader); void loadXmlSheetViews(QXmlStreamReader &reader); + void loadXmlHyperlinks(QXmlStreamReader &reader); SharedStrings *sharedStrings() const; @@ -210,7 +212,7 @@ public: Drawing *drawing; QMap > > cellTable; QMap > comments; - QMap > urlTable; + QMap > > urlTable; QList merges; QList imageList; QMap > rowsInfo;