Browse Source

Add basic url type support for Worksheet::write()

master
Debao Zhang 11 years ago
parent
commit
7f7fa7e9fa
  1. 1
      examples/xlsx/hello/main.cpp
  2. 15
      src/xlsx/xlsxpackage.cpp
  3. 122
      src/xlsx/xlsxworksheet.cpp
  4. 3
      src/xlsx/xlsxworksheet.h
  5. 17
      src/xlsx/xlsxworksheet_p.h

1
examples/xlsx/hello/main.cpp

@ -16,6 +16,7 @@ int main()
sheet->write("B3", 12345); sheet->write("B3", 12345);
sheet->write("C5", "=44+33"); sheet->write("C5", "=44+33");
sheet->write("D7", true); sheet->write("D7", true);
sheet->write("E1", "http://qt-project.org");
QXlsx::Worksheet *sheet2 = workbook.addWorksheet(); QXlsx::Worksheet *sheet2 = workbook.addWorksheet();
//Rows and columns are zero indexed. //Rows and columns are zero indexed.

15
src/xlsx/xlsxpackage.cpp

@ -285,6 +285,21 @@ void Package::writeWorkbookRelsFile(ZipWriter &zipWriter)
void Package::writeWorksheetRelsFile(ZipWriter &zipWriter) void Package::writeWorksheetRelsFile(ZipWriter &zipWriter)
{ {
int index = 1;
foreach (Worksheet *sheet, m_workbook->worksheets()) {
if (sheet->isChartsheet())
continue;
Relationships rels;
foreach (QString link, sheet->externUrlList())
rels.addWorksheetRelationship(QStringLiteral("/hyperlink"), link, QStringLiteral("External"));
QByteArray data;
QBuffer buffer(&data);
buffer.open(QIODevice::WriteOnly);
rels.saveToXmlFile(&buffer);
zipWriter.addFile(QStringLiteral("xl/worksheets/_rels/sheet%1.xml.rels").arg(index), data);
index += 1;
}
} }
} // namespace QXlsx } // namespace QXlsx

122
src/xlsx/xlsxworksheet.cpp

@ -34,6 +34,8 @@
#include <QDateTime> #include <QDateTime>
#include <QPoint> #include <QPoint>
#include <QFile> #include <QFile>
#include <QUrl>
#include <QRegularExpression>
#include <QDebug> #include <QDebug>
#include <stdint.h> #include <stdint.h>
@ -256,6 +258,12 @@ void Worksheet::setZeroValuesHidden(bool enable)
d->show_zeros = !enable; d->show_zeros = !enable;
} }
QStringList Worksheet::externUrlList() const
{
Q_D(const Worksheet);
return d->externUrlList;
}
int Worksheet::write(int row, int column, const QVariant &value, Format *format) int Worksheet::write(int row, int column, const QVariant &value, Format *format)
{ {
Q_D(Worksheet); Q_D(Worksheet);
@ -279,13 +287,16 @@ int Worksheet::write(int row, int column, const QVariant &value, Format *format)
ret = writeNumber(row, column, value.toDouble(), format); ret = writeNumber(row, column, value.toDouble(), format);
} }
} else if (value.type() == QMetaType::QUrl) { //url } else if (value.type() == QMetaType::QUrl) { //url
ret = writeUrl(row, column, value.toUrl(), format);
} else if (value.type() == QMetaType::QString) { //string } else if (value.type() == QMetaType::QString) { //string
QString token = value.toString(); QString token = value.toString();
QRegularExpression urlPattern(QStringLiteral("^([fh]tt?ps?://)|(mailto:)|((in|ex)ternal:)"));
if (token.startsWith(QLatin1String("="))) { if (token.startsWith(QLatin1String("="))) {
ret = writeFormula(row, column, token, format); ret = writeFormula(row, column, token, format);
} else if (token.startsWith(QLatin1String("{")) && token.endsWith(QLatin1String("}"))) { } else if (token.startsWith(QLatin1String("{")) && token.endsWith(QLatin1String("}"))) {
} else if (token.contains(urlPattern)) {
ret = writeUrl(row, column, QUrl(token));
} else { } else {
ret = writeString(row, column, token, format); ret = writeString(row, column, token, format);
} }
@ -386,6 +397,70 @@ int Worksheet::writeDateTime(int row, int column, const QDateTime &dt, Format *f
return 0; return 0;
} }
int Worksheet::writeUrl(int row, int column, const QUrl &url, Format *format, const QString &display, const QString &tip)
{
Q_D(Worksheet);
if (d->checkDimensions(row, column))
return -1;
int link_type = 1;
QString urlString = url.toString();
QString displayString = display;
if (urlString.startsWith(QLatin1String("internal:"))) {
urlString.replace(QLatin1String("internal:"), QString());
link_type = 2;
} else if (urlString.startsWith(QLatin1String("external:"))) {
urlString.replace(QLatin1String("external:"), QString());
link_type = 3;
}
if (display.isEmpty())
displayString = urlString;
//For external links, chagne the directory separator from Unix to Dos
if (link_type == 3) {
urlString.replace(QLatin1Char('/'), QLatin1String("\\"));
displayString.replace(QLatin1Char('/'), QLatin1String("\\"));
}
displayString.replace(QLatin1String("mailto:"), QString());
int error = 0;
if (displayString.size() > d->xls_strmax) {
displayString = displayString.left(d->xls_strmax);
error = -2;
}
QString locationString = displayString;
if (link_type == 1) {
locationString = QString();
} else if (link_type == 3) {
// External Workbook links need to be modified into correct format.
// The URL will look something like 'c:\temp\file.xlsx#Sheet!A1'.
// We need the part to the left of the # as the URL and the part to
//the right as the "location" string (if it exists).
if (urlString.contains(QLatin1Char('#'))) {
QStringList list = urlString.split(QLatin1Char('#'));
urlString = list[0];
locationString = list[1];
} else {
locationString = QString();
}
link_type = 1;
}
//Write the hyperlink string as normal string.
SharedStrings *sharedStrings = d->workbook->sharedStrings();
int index = sharedStrings->addSharedString(urlString);
d->cellTable[row][column] = new XlsxCellData(index, XlsxCellData::String, format);
//Store the hyperlink data in sa separate table
d->urlTable[row][column] = new XlsxUrlData(link_type, urlString, locationString, tip);
return error;
}
void Worksheet::saveToXmlFile(QIODevice *device) void Worksheet::saveToXmlFile(QIODevice *device)
{ {
Q_D(Worksheet); Q_D(Worksheet);
@ -457,6 +532,8 @@ void Worksheet::saveToXmlFile(QIODevice *device)
} }
writer.writeEndElement();//sheetData writer.writeEndElement();//sheetData
d->writeHyperlinks(writer);
writer.writeEndElement();//worksheet writer.writeEndElement();//worksheet
writer.writeEndDocument(); writer.writeEndDocument();
} }
@ -561,6 +638,49 @@ void WorksheetPrivate::writeCellData(XmlStreamWriter &writer, int row, int col,
writer.writeEndElement(); //c writer.writeEndElement(); //c
} }
void WorksheetPrivate::writeHyperlinks(XmlStreamWriter &writer)
{
if (urlTable.isEmpty())
return;
int rel_count = 0;
externUrlList.clear();
writer.writeStartElement(QStringLiteral("hyperlinks"));
QMapIterator<int, QMap<int, XlsxUrlData *> > it(urlTable);
while (it.hasNext()) {
it.next();
int row = it.key();
QMapIterator <int, XlsxUrlData *> it2(it.value());
while(it2.hasNext()) {
it2.next();
int col = it2.key();
XlsxUrlData *data = it2.value();
QString ref = xl_rowcol_to_cell(row, col);
writer.writeEmptyElement(QStringLiteral("hyperlink"));
writer.writeAttribute(QStringLiteral("ref"), ref);
if (data->linkType == 1) {
rel_count += 1;
externUrlList.append(data->url);
writer.writeAttribute(QStringLiteral("r:id"), QStringLiteral("rId%1").arg(rel_count));
if (!data->location.isEmpty())
writer.writeAttribute(QStringLiteral("location"), data->location);
// if (!data->url.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);
}
}
}
writer.writeEndElement();//hyperlinks
}
/* /*
Sets row height and format. Row height measured in point size. If format Sets row height and format. Row height measured in point size. If format
equals 0 then format is ignored. equals 0 then format is ignored.

3
src/xlsx/xlsxworksheet.h

@ -32,6 +32,7 @@
#include <QVariant> #include <QVariant>
class QIODevice; class QIODevice;
class QDateTime; class QDateTime;
class QUrl;
namespace QXlsx { namespace QXlsx {
class Package; class Package;
@ -53,6 +54,7 @@ public:
int writeBlank(int row, int column, Format *format=0); int writeBlank(int row, int column, Format *format=0);
int writeBool(int row, int column, bool value, Format *format=0); int writeBool(int row, int column, bool value, Format *format=0);
int writeDateTime(int row, int column, const QDateTime& dt, Format *format=0); int writeDateTime(int row, int column, const QDateTime& dt, Format *format=0);
int writeUrl(int row, int column, const QUrl &url, Format *format=0, const QString &display=QString(), const QString &tip=QString());
bool setRow(int row, double height, Format* format=0, bool hidden=false); bool setRow(int row, double height, Format* format=0, bool hidden=false);
bool setColumn(int colFirst, int colLast, double width, Format* format=0, bool hidden=false); bool setColumn(int colFirst, int colLast, double width, Format* format=0, bool hidden=false);
@ -73,6 +75,7 @@ private:
void setHidden(bool hidden); void setHidden(bool hidden);
void setSelected(bool select); void setSelected(bool select);
void saveToXmlFile(QIODevice *device); void saveToXmlFile(QIODevice *device);
QStringList externUrlList() const;
WorksheetPrivate * const d_ptr; WorksheetPrivate * const d_ptr;
}; };

17
src/xlsx/xlsxworksheet_p.h

@ -51,6 +51,20 @@ struct XlsxCellData
Format *format; Format *format;
}; };
struct XlsxUrlData
{
XlsxUrlData(int linkType=1, const QString &url=QString(), const QString &location=QString(), const QString &tip=QString()) :
linkType(linkType), url(url), location(location), tip(tip)
{
}
int linkType;
QString url;
QString location; //location string
QString tip;
};
struct XlsxRowInfo struct XlsxRowInfo
{ {
XlsxRowInfo(double height, Format *format, bool hidden) : XlsxRowInfo(double height, Format *format, bool hidden) :
@ -89,10 +103,13 @@ public:
void calculateSpans(); void calculateSpans();
void writeSheetData(XmlStreamWriter &writer); void writeSheetData(XmlStreamWriter &writer);
void writeCellData(XmlStreamWriter &writer, int row, int col, XlsxCellData *cell); void writeCellData(XmlStreamWriter &writer, int row, int col, XlsxCellData *cell);
void writeHyperlinks(XmlStreamWriter &writer);
Workbook *workbook; Workbook *workbook;
QMap<int, QMap<int, XlsxCellData *> > cellTable; QMap<int, QMap<int, XlsxCellData *> > cellTable;
QMap<int, QMap<int, QString> > comments; QMap<int, QMap<int, QString> > comments;
QMap<int, QMap<int, XlsxUrlData *> > urlTable;
QStringList externUrlList;
QMap<int, XlsxRowInfo *> rowsInfo; QMap<int, XlsxRowInfo *> rowsInfo;
QList<XlsxColumnInfo *> colsInfo; QList<XlsxColumnInfo *> colsInfo;
QMap<int, XlsxColumnInfo *> colsInfoHelper;//Not owns the XlsxColumnInfo QMap<int, XlsxColumnInfo *> colsInfoHelper;//Not owns the XlsxColumnInfo

Loading…
Cancel
Save