Browse Source

Don't lost hyperlinks when edit an exist xlsx file

master
Debao Zhang 11 years ago
parent
commit
a49180906a
  1. 9
      examples/xlsx/hyperlinks/hyperlinks.pro
  2. 25
      examples/xlsx/hyperlinks/main.cpp
  3. 1
      examples/xlsx/xlsx.pro
  4. 63
      src/xlsx/xlsxworksheet.cpp
  5. 14
      src/xlsx/xlsxworksheet_p.h

9
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

25
examples/xlsx/hyperlinks/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;
}

1
examples/xlsx/xlsx.pro

@ -13,5 +13,6 @@ SUBDIRS = hello \
richtext \ richtext \
conditionalformatting \ conditionalformatting \
worksheetoperations \ worksheetoperations \
hyperlinks \
demo demo

63
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) 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())
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<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);
} }
} }
} }

14
src/xlsx/xlsxworksheet_p.h

@ -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;

Loading…
Cancel
Save