Don't lost hyperlinks when edit an exist xlsx file
This commit is contained in:
@@ -0,0 +1,9 @@
|
|||||||
|
TARGET = hyperlinks
|
||||||
|
|
||||||
|
#include(../../../src/xlsx/qtxlsx.pri)
|
||||||
|
QT+=xlsx
|
||||||
|
|
||||||
|
CONFIG += console
|
||||||
|
CONFIG -= app_bundle
|
||||||
|
|
||||||
|
SOURCES += main.cpp
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#include <QtCore>
|
||||||
|
#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;
|
||||||
|
}
|
||||||
@@ -13,5 +13,6 @@ SUBDIRS = hello \
|
|||||||
richtext \
|
richtext \
|
||||||
conditionalformatting \
|
conditionalformatting \
|
||||||
worksheetoperations \
|
worksheetoperations \
|
||||||
|
hyperlinks \
|
||||||
demo
|
demo
|
||||||
|
|
||||||
|
|||||||
+43
-16
@@ -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)
|
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<Cell>(new Cell(displayString, Cell::String, fmt, this));
|
d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(displayString, Cell::String, fmt, this));
|
||||||
|
|
||||||
//Store the hyperlink data in a separate table
|
//Store the hyperlink data in a separate table
|
||||||
d->urlTable[row][column] = new XlsxHyperlinkData(XlsxHyperlinkData::External, urlString, locationString, tip);
|
d->urlTable[row][column] = QSharedPointer<XlsxHyperlinkData>(new XlsxHyperlinkData(XlsxHyperlinkData::External, urlString, locationString, QString(), tip));
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@@ -1390,36 +1390,31 @@ void WorksheetPrivate::saveXmlHyperlinks(QXmlStreamWriter &writer) const
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
writer.writeStartElement(QStringLiteral("hyperlinks"));
|
writer.writeStartElement(QStringLiteral("hyperlinks"));
|
||||||
QMapIterator<int, QMap<int, XlsxHyperlinkData *> > it(urlTable);
|
QMapIterator<int, QMap<int, QSharedPointer<XlsxHyperlinkData> > > it(urlTable);
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
it.next();
|
it.next();
|
||||||
int row = it.key();
|
int row = it.key();
|
||||||
QMapIterator <int, XlsxHyperlinkData *> it2(it.value());
|
QMapIterator <int, QSharedPointer<XlsxHyperlinkData> > it2(it.value());
|
||||||
while (it2.hasNext()) {
|
while (it2.hasNext()) {
|
||||||
it2.next();
|
it2.next();
|
||||||
int col = it2.key();
|
int col = it2.key();
|
||||||
XlsxHyperlinkData *data = it2.value();
|
QSharedPointer<XlsxHyperlinkData> data = it2.value();
|
||||||
QString ref = xl_rowcol_to_cell(row, col);
|
QString ref = xl_rowcol_to_cell(row, col);
|
||||||
writer.writeEmptyElement(QStringLiteral("hyperlink"));
|
writer.writeEmptyElement(QStringLiteral("hyperlink"));
|
||||||
writer.writeAttribute(QStringLiteral("ref"), ref);
|
writer.writeAttribute(QStringLiteral("ref"), ref);
|
||||||
if (data->linkType == XlsxHyperlinkData::External) {
|
if (data->linkType == XlsxHyperlinkData::External) {
|
||||||
|
|
||||||
//Update relationships
|
//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()));
|
writer.writeAttribute(QStringLiteral("r:id"), QStringLiteral("rId%1").arg(relationships.count()));
|
||||||
|
}
|
||||||
|
|
||||||
if (!data->location.isEmpty())
|
if (!data->location.isEmpty())
|
||||||
writer.writeAttribute(QStringLiteral("location"), data->location);
|
writer.writeAttribute(QStringLiteral("location"), data->location);
|
||||||
if (!data->display.isEmpty())
|
if (!data->display.isEmpty())
|
||||||
writer.writeAttribute(QStringLiteral("display"), data->url);
|
writer.writeAttribute(QStringLiteral("display"), data->display);
|
||||||
if (!data->tip.isEmpty())
|
if (!data->tooltip.isEmpty())
|
||||||
writer.writeAttribute(QStringLiteral("tooltip"), data->tip);
|
writer.writeAttribute(QStringLiteral("tooltip"), data->tooltip);
|
||||||
} else {
|
|
||||||
writer.writeAttribute(QStringLiteral("location"), data->url);
|
|
||||||
if (!data->tip.isEmpty())
|
|
||||||
writer.writeAttribute(QStringLiteral("tooltip"), data->tip);
|
|
||||||
writer.writeAttribute(QStringLiteral("display"), data->location);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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<XlsxHyperlinkData> 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)
|
bool Worksheet::loadFromXmlFile(QIODevice *device)
|
||||||
{
|
{
|
||||||
Q_D(Worksheet);
|
Q_D(Worksheet);
|
||||||
@@ -2183,6 +2208,8 @@ bool Worksheet::loadFromXmlFile(QIODevice *device)
|
|||||||
ConditionalFormatting cf;
|
ConditionalFormatting cf;
|
||||||
cf.loadFromXml(reader, workbook()->styles());
|
cf.loadFromXml(reader, workbook()->styles());
|
||||||
d->conditionalFormattingList.append(cf);
|
d->conditionalFormattingList.append(cf);
|
||||||
|
} else if (reader.name() == QLatin1String("hyperlinks")) {
|
||||||
|
d->loadXmlHyperlinks(reader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,17 +65,18 @@ struct XlsxHyperlinkData
|
|||||||
Internal
|
Internal
|
||||||
};
|
};
|
||||||
|
|
||||||
XlsxHyperlinkData(LinkType linkType=External, const QString &url=QString(), const QString &location=QString(), const QString &tip=QString()) :
|
XlsxHyperlinkData(LinkType linkType=External, const QString &target=QString(), const QString &location=QString()
|
||||||
linkType(linkType), url(url), location(location), tip(tip)
|
, const QString &display=QString(), const QString &tip=QString())
|
||||||
|
:linkType(linkType), target(target), location(location), display(display), tooltip(tip)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LinkType linkType;
|
LinkType linkType;
|
||||||
QString url;
|
QString target; //For External link
|
||||||
QString location; //location string
|
QString location;
|
||||||
QString display;
|
QString display;
|
||||||
QString tip;
|
QString tooltip;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct XlsxImageData
|
struct XlsxImageData
|
||||||
@@ -201,6 +202,7 @@ public:
|
|||||||
void loadXmlMergeCells(QXmlStreamReader &reader);
|
void loadXmlMergeCells(QXmlStreamReader &reader);
|
||||||
void loadXmlDataValidations(QXmlStreamReader &reader);
|
void loadXmlDataValidations(QXmlStreamReader &reader);
|
||||||
void loadXmlSheetViews(QXmlStreamReader &reader);
|
void loadXmlSheetViews(QXmlStreamReader &reader);
|
||||||
|
void loadXmlHyperlinks(QXmlStreamReader &reader);
|
||||||
|
|
||||||
SharedStrings *sharedStrings() const;
|
SharedStrings *sharedStrings() const;
|
||||||
|
|
||||||
@@ -210,7 +212,7 @@ public:
|
|||||||
Drawing *drawing;
|
Drawing *drawing;
|
||||||
QMap<int, QMap<int, QSharedPointer<Cell> > > cellTable;
|
QMap<int, QMap<int, QSharedPointer<Cell> > > cellTable;
|
||||||
QMap<int, QMap<int, QString> > comments;
|
QMap<int, QMap<int, QString> > comments;
|
||||||
QMap<int, QMap<int, XlsxHyperlinkData *> > urlTable;
|
QMap<int, QMap<int, QSharedPointer<XlsxHyperlinkData> > > urlTable;
|
||||||
QList<CellRange> merges;
|
QList<CellRange> merges;
|
||||||
QList<XlsxImageData *> imageList;
|
QList<XlsxImageData *> imageList;
|
||||||
QMap<int, QSharedPointer<XlsxRowInfo> > rowsInfo;
|
QMap<int, QSharedPointer<XlsxRowInfo> > rowsInfo;
|
||||||
|
|||||||
Reference in New Issue
Block a user