Fix Issue1: Add insert_image() function
This commit is contained in:
@@ -0,0 +1,6 @@
|
|||||||
|
TARGET = image
|
||||||
|
|
||||||
|
#include(../../../src/xlsx/qtxlsx.pri)
|
||||||
|
QT += xlsx
|
||||||
|
|
||||||
|
SOURCES += main.cpp
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#include <QtGui>
|
||||||
|
#include "xlsxworkbook.h"
|
||||||
|
#include "xlsxworksheet.h"
|
||||||
|
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
# define DATA_PATH "../../../"
|
||||||
|
#else
|
||||||
|
# define DATA_PATH "./"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
QGuiApplication(argc, argv);
|
||||||
|
|
||||||
|
QXlsx::Workbook workbook;
|
||||||
|
QXlsx::Worksheet *sheet = workbook.addWorksheet();
|
||||||
|
QImage image(400, 300, QImage::Format_RGB32);
|
||||||
|
image.fill(Qt::green);
|
||||||
|
sheet->insertImage(5, 5, image);
|
||||||
|
|
||||||
|
workbook.save(DATA_PATH"Test.xlsx");
|
||||||
|
// workbook.save(DATA_PATH"Test2.zip");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
TEMPLATE = subdirs
|
TEMPLATE = subdirs
|
||||||
SUBDIRS = hello style \
|
SUBDIRS = hello style \
|
||||||
documentproperty
|
documentproperty \
|
||||||
|
image
|
||||||
|
|
||||||
|
|||||||
+4
-2
@@ -21,7 +21,8 @@ HEADERS += $$PWD/xlsxdocpropscore_p.h \
|
|||||||
$$PWD/xlsxworkbook_p.h \
|
$$PWD/xlsxworkbook_p.h \
|
||||||
$$PWD/xlsxworksheet_p.h \
|
$$PWD/xlsxworksheet_p.h \
|
||||||
$$PWD/xlsxformat_p.h \
|
$$PWD/xlsxformat_p.h \
|
||||||
$$PWD/xlsxglobal.h
|
$$PWD/xlsxglobal.h \
|
||||||
|
$$PWD/xlsxdrawing_p.h
|
||||||
|
|
||||||
SOURCES += $$PWD/xlsxdocpropscore.cpp \
|
SOURCES += $$PWD/xlsxdocpropscore.cpp \
|
||||||
$$PWD/xlsxdocpropsapp.cpp \
|
$$PWD/xlsxdocpropsapp.cpp \
|
||||||
@@ -36,4 +37,5 @@ SOURCES += $$PWD/xlsxdocpropscore.cpp \
|
|||||||
$$PWD/xlsxworkbook.cpp \
|
$$PWD/xlsxworkbook.cpp \
|
||||||
$$PWD/xlsxworksheet.cpp \
|
$$PWD/xlsxworksheet.cpp \
|
||||||
$$PWD/xlsxzipwriter.cpp \
|
$$PWD/xlsxzipwriter.cpp \
|
||||||
$$PWD/xlsxpackage.cpp
|
$$PWD/xlsxpackage.cpp \
|
||||||
|
$$PWD/xlsxdrawing.cpp
|
||||||
|
|||||||
@@ -64,6 +64,11 @@ void ContentTypes::addChartsheetName(const QString &name)
|
|||||||
addOverride(QStringLiteral("/xl/chartsheets/%1.xml").arg(name), m_document_prefix + QStringLiteral("spreadsheetml.chartsheet+xml"));
|
addOverride(QStringLiteral("/xl/chartsheets/%1.xml").arg(name), m_document_prefix + QStringLiteral("spreadsheetml.chartsheet+xml"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ContentTypes::addDrawingName(const QString &name)
|
||||||
|
{
|
||||||
|
addOverride(QStringLiteral("/xl/drawings/%1.xml").arg(name), m_document_prefix + QStringLiteral("drawing+xml"));
|
||||||
|
}
|
||||||
|
|
||||||
void ContentTypes::addChartName(const QString &name)
|
void ContentTypes::addChartName(const QString &name)
|
||||||
{
|
{
|
||||||
addOverride(QStringLiteral("/xl/charts/%1.xml").arg(name), m_document_prefix + QStringLiteral("drawingml.chart+xml"));
|
addOverride(QStringLiteral("/xl/charts/%1.xml").arg(name), m_document_prefix + QStringLiteral("drawingml.chart+xml"));
|
||||||
@@ -77,7 +82,7 @@ void ContentTypes::addCommentName(const QString &name)
|
|||||||
void ContentTypes::addImageTypes(const QStringList &imageTypes)
|
void ContentTypes::addImageTypes(const QStringList &imageTypes)
|
||||||
{
|
{
|
||||||
foreach (QString type, imageTypes)
|
foreach (QString type, imageTypes)
|
||||||
addOverride(type, QStringLiteral("image/") + type);
|
addDefault(type, QStringLiteral("image/") + type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentTypes::addTableName(const QString &name)
|
void ContentTypes::addTableName(const QString &name)
|
||||||
|
|||||||
@@ -0,0 +1,174 @@
|
|||||||
|
#include "xlsxdrawing_p.h"
|
||||||
|
#include "xlsxxmlwriter_p.h"
|
||||||
|
|
||||||
|
namespace QXlsx {
|
||||||
|
|
||||||
|
Drawing::Drawing(QObject *parent) :
|
||||||
|
QObject(parent)
|
||||||
|
{
|
||||||
|
embedded = false;
|
||||||
|
orientation = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Drawing::saveToXmlFile(QIODevice *device)
|
||||||
|
{
|
||||||
|
XmlStreamWriter writer(device);
|
||||||
|
|
||||||
|
writer.writeStartDocument(QStringLiteral("1.0"), true);
|
||||||
|
writer.writeStartElement(QStringLiteral("xdr:wsDr"));
|
||||||
|
writer.writeAttribute(QStringLiteral("xmlns:xdr"), QStringLiteral("http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"));
|
||||||
|
writer.writeAttribute(QStringLiteral("xmlns:a"), QStringLiteral("http://schemas.openxmlformats.org/drawingml/2006/main"));
|
||||||
|
|
||||||
|
if (embedded) {
|
||||||
|
int index = 1;
|
||||||
|
foreach (XlsxDrawingDimensionData *dimension, dimensionList) {
|
||||||
|
writeTwoCellAnchor(writer, index, dimension);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//write the xdr:absoluteAnchor element
|
||||||
|
writeAbsoluteAnchor(writer, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.writeEndElement();//xdr:wsDr
|
||||||
|
writer.writeEndDocument();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Drawing::writeTwoCellAnchor(XmlStreamWriter &writer, int index, XlsxDrawingDimensionData *data)
|
||||||
|
{
|
||||||
|
writer.writeStartElement(QStringLiteral("xdr:twoCellAnchor"));
|
||||||
|
if (data->drawing_type == 2)
|
||||||
|
writer.writeAttribute(QStringLiteral("editAs"), QStringLiteral("oneCell"));
|
||||||
|
// if (shape)
|
||||||
|
// writer.writeAttribute(QStringLiteral("editAs"), );
|
||||||
|
|
||||||
|
writer.writeStartElement(QStringLiteral("xdr:from"));
|
||||||
|
writer.writeTextElement(QStringLiteral("xdr:col"), QString::number(data->col_from));
|
||||||
|
writer.writeTextElement(QStringLiteral("xdr:colOff"), QString::number((int)data->col_from_offset));
|
||||||
|
writer.writeTextElement(QStringLiteral("xdr:row"), QString::number(data->row_from));
|
||||||
|
writer.writeTextElement(QStringLiteral("xdr:rowOff"), QString::number((int)data->row_from_offset));
|
||||||
|
writer.writeEndElement(); //xdr:from
|
||||||
|
|
||||||
|
writer.writeStartElement(QStringLiteral("xdr:to"));
|
||||||
|
writer.writeTextElement(QStringLiteral("xdr:col"), QString::number(data->col_to));
|
||||||
|
writer.writeTextElement(QStringLiteral("xdr:colOff"), QString::number((int)data->col_to_offset));
|
||||||
|
writer.writeTextElement(QStringLiteral("xdr:row"), QString::number(data->row_to));
|
||||||
|
writer.writeTextElement(QStringLiteral("xdr:rowOff"), QString::number((int)data->row_to_offset));
|
||||||
|
writer.writeEndElement(); //xdr:to
|
||||||
|
|
||||||
|
if (data->drawing_type == 1) {
|
||||||
|
//Graphics frame, xdr:graphicFrame
|
||||||
|
writeGraphicFrame(writer, index, data->description);
|
||||||
|
} else if (data->drawing_type == 2) {
|
||||||
|
//Image, xdr:pic
|
||||||
|
writePicture(writer, index, data->col_absolute, data->row_absolute, data->width, data->height, data->description);
|
||||||
|
} else {
|
||||||
|
//Shape, xdr:sp
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.writeEmptyElement(QStringLiteral("xdr:clientData"));
|
||||||
|
writer.writeEndElement(); //xdr:twoCellAnchor
|
||||||
|
}
|
||||||
|
|
||||||
|
void Drawing::writeAbsoluteAnchor(XmlStreamWriter &writer, int index)
|
||||||
|
{
|
||||||
|
writer.writeStartElement(QStringLiteral("xdr:absoluteAnchor"));
|
||||||
|
if (orientation == 0) {
|
||||||
|
writePos(writer, 0, 0);
|
||||||
|
writeExt(writer, 9308969, 6078325);
|
||||||
|
} else {
|
||||||
|
writePos(writer, 0, -47625);
|
||||||
|
writeExt(writer, 6162675, 6124575);
|
||||||
|
}
|
||||||
|
|
||||||
|
writeGraphicFrame(writer, index);
|
||||||
|
writer.writeEmptyElement(QStringLiteral("xdr:clientData"));
|
||||||
|
|
||||||
|
writer.writeEndElement(); //xdr:absoluteAnchor
|
||||||
|
}
|
||||||
|
|
||||||
|
void Drawing::writePos(XmlStreamWriter &writer, int x, int y)
|
||||||
|
{
|
||||||
|
writer.writeEmptyElement(QStringLiteral("xdr:pos"));
|
||||||
|
writer.writeAttribute(QStringLiteral("x"), QString::number(x));
|
||||||
|
writer.writeAttribute(QStringLiteral("y"), QString::number(y));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Drawing::writeExt(XmlStreamWriter &writer, int cx, int cy)
|
||||||
|
{
|
||||||
|
writer.writeStartElement(QStringLiteral("xdr:ext"));
|
||||||
|
writer.writeAttribute(QStringLiteral("cx"), QString::number(cx));
|
||||||
|
writer.writeAttribute(QStringLiteral("cy"), QString::number(cy));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Drawing::writeGraphicFrame(XmlStreamWriter &writer, int index, const QString &name)
|
||||||
|
{
|
||||||
|
writer.writeStartElement(QStringLiteral("xdr:graphicFrame"));
|
||||||
|
writer.writeAttribute(QStringLiteral("macro"), QString());
|
||||||
|
|
||||||
|
writer.writeStartElement(QStringLiteral("xdr:nvGraphicFramePr"));
|
||||||
|
writer.writeEmptyElement(QStringLiteral("xdr:cNvPr"));
|
||||||
|
writer.writeAttribute(QStringLiteral("id"), QString::number(index+1));
|
||||||
|
writer.writeAttribute(QStringLiteral("name"), name.isEmpty() ? QStringLiteral("Chart%1").arg(index): name);
|
||||||
|
if (embedded) {
|
||||||
|
writer.writeEmptyElement(QStringLiteral("xdr:cNvGraphicFramePr"));
|
||||||
|
} else {
|
||||||
|
writer.writeStartElement(QStringLiteral("xdr:cNvGraphicFramePr"));
|
||||||
|
writer.writeEmptyElement(QStringLiteral("a:graphicFrameLocks"));
|
||||||
|
writer.writeAttribute(QStringLiteral("noGrp"), QStringLiteral("1"));
|
||||||
|
writer.writeEndElement(); //xdr:cNvGraphicFramePr
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.writeEndElement();//xdr:nvGraphicFramePr
|
||||||
|
writer.writeEndElement(); //xdr:graphicFrame
|
||||||
|
}
|
||||||
|
|
||||||
|
void Drawing::writePicture(XmlStreamWriter &writer, int index, double col_abs, double row_abs, int width, int height, const QString &description)
|
||||||
|
{
|
||||||
|
writer.writeStartElement(QStringLiteral("xdr:pic"));
|
||||||
|
|
||||||
|
writer.writeStartElement(QStringLiteral("xdr:nvPicPr"));
|
||||||
|
writer.writeEmptyElement(QStringLiteral("xdr:cNvPr"));
|
||||||
|
writer.writeAttribute(QStringLiteral("id"), QString::number(index+1));
|
||||||
|
writer.writeAttribute(QStringLiteral("name"), QStringLiteral("Picture%1").arg(index));
|
||||||
|
if (!description.isEmpty())
|
||||||
|
writer.writeAttribute(QStringLiteral("descr"), description);
|
||||||
|
|
||||||
|
writer.writeStartElement(QStringLiteral("xdr:cNvPicPr"));
|
||||||
|
writer.writeEmptyElement(QStringLiteral("a:picLocks"));
|
||||||
|
writer.writeAttribute(QStringLiteral("noChangeAspect"), QStringLiteral("1"));
|
||||||
|
writer.writeEndElement(); //xdr:cNvPicPr
|
||||||
|
|
||||||
|
writer.writeEndElement(); //xdr:nvPicPr
|
||||||
|
|
||||||
|
writer.writeStartElement(QStringLiteral("xdr:blipFill"));
|
||||||
|
writer.writeEmptyElement(QStringLiteral("a:blip"));
|
||||||
|
writer.writeAttribute(QStringLiteral("xmlns:r"), QStringLiteral("http://schemas.openxmlformats.org/officeDocument/2006/relationships"));
|
||||||
|
writer.writeAttribute(QStringLiteral("r:embed"), QStringLiteral("rId%1").arg(index));
|
||||||
|
writer.writeStartElement(QStringLiteral("a:stretch"));
|
||||||
|
writer.writeEmptyElement(QStringLiteral("a:fillRect"));
|
||||||
|
writer.writeEndElement(); //a:stretch
|
||||||
|
writer.writeEndElement();//xdr:blipFill
|
||||||
|
|
||||||
|
writer.writeStartElement(QStringLiteral("xdr:spPr"));
|
||||||
|
|
||||||
|
writer.writeStartElement(QStringLiteral("a:xfrm"));
|
||||||
|
writer.writeEmptyElement(QStringLiteral("a:off"));
|
||||||
|
writer.writeAttribute(QStringLiteral("x"), QString::number((int)col_abs));
|
||||||
|
writer.writeAttribute(QStringLiteral("y"), QString::number((int)row_abs));
|
||||||
|
writer.writeEmptyElement(QStringLiteral("a:ext"));
|
||||||
|
writer.writeAttribute(QStringLiteral("cx"), QString::number(width));
|
||||||
|
writer.writeAttribute(QStringLiteral("cy"), QString::number(height));
|
||||||
|
writer.writeEndElement(); //a:xfrm
|
||||||
|
|
||||||
|
writer.writeStartElement(QStringLiteral("a:prstGeom"));
|
||||||
|
writer.writeAttribute(QStringLiteral("prst"), QStringLiteral("rect"));
|
||||||
|
writer.writeEmptyElement(QStringLiteral("a:avLst"));
|
||||||
|
writer.writeEndElement(); //a:prstGeom
|
||||||
|
|
||||||
|
writer.writeEndElement(); //xdr:spPr
|
||||||
|
|
||||||
|
writer.writeEndElement(); //xdr:pic
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QXlsx
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
#ifndef QXLSX_DRAWING_H
|
||||||
|
#define QXLSX_DRAWING_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
|
class QIODevice;
|
||||||
|
|
||||||
|
namespace QXlsx {
|
||||||
|
class XmlStreamWriter;
|
||||||
|
|
||||||
|
struct XlsxDrawingDimensionData
|
||||||
|
{
|
||||||
|
int drawing_type;
|
||||||
|
int col_from;
|
||||||
|
int row_from;
|
||||||
|
double col_from_offset;
|
||||||
|
double row_from_offset;
|
||||||
|
int col_to;
|
||||||
|
int row_to;
|
||||||
|
double col_to_offset;
|
||||||
|
double row_to_offset;
|
||||||
|
int col_absolute;
|
||||||
|
int row_absolute;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
QString description;
|
||||||
|
int shape;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Drawing : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit Drawing(QObject *parent = 0);
|
||||||
|
void saveToXmlFile(QIODevice *device);
|
||||||
|
|
||||||
|
bool embedded;
|
||||||
|
int orientation;
|
||||||
|
QList <XlsxDrawingDimensionData *> dimensionList;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void writeTwoCellAnchor(XmlStreamWriter &writer, int index, XlsxDrawingDimensionData *data);
|
||||||
|
void writeAbsoluteAnchor(XmlStreamWriter &writer, int index);
|
||||||
|
void writePos(XmlStreamWriter &writer, int x, int y);
|
||||||
|
void writeExt(XmlStreamWriter &writer, int cx, int cy);
|
||||||
|
void writeGraphicFrame(XmlStreamWriter &writer, int index, const QString &name=QString());
|
||||||
|
void writePicture(XmlStreamWriter &writer, int index, double col_abs, double row_abs, int width, int height, const QString &description);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QXlsx
|
||||||
|
|
||||||
|
#endif // QXLSX_DRAWING_H
|
||||||
@@ -33,6 +33,7 @@
|
|||||||
#include "xlsxstyles_p.h"
|
#include "xlsxstyles_p.h"
|
||||||
#include "xlsxrelationships_p.h"
|
#include "xlsxrelationships_p.h"
|
||||||
#include "xlsxzipwriter_p.h"
|
#include "xlsxzipwriter_p.h"
|
||||||
|
#include "xlsxdrawing_p.h"
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
@@ -93,11 +94,13 @@ bool Package::createPackage(const QString &packageName)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_workbook->styles()->clearExtraFormatInfo(); //These info will be generated when write the worksheet data.
|
m_workbook->styles()->clearExtraFormatInfo(); //These info will be generated when write the worksheet data.
|
||||||
|
m_workbook->prepareDrawings();
|
||||||
|
|
||||||
writeWorksheetFiles(zipWriter);
|
writeWorksheetFiles(zipWriter);
|
||||||
// writeChartsheetFiles(zipWriter);
|
// writeChartsheetFiles(zipWriter);
|
||||||
writeWorkbookFile(zipWriter);
|
writeWorkbookFile(zipWriter);
|
||||||
// writeChartFiles(zipWriter);
|
// writeChartFiles(zipWriter);
|
||||||
// writeDrawingFiles(zipWriter);
|
writeDrawingFiles(zipWriter);
|
||||||
// writeVmlFiles(zipWriter);
|
// writeVmlFiles(zipWriter);
|
||||||
// writeCommentFiles(zipWriter);
|
// writeCommentFiles(zipWriter);
|
||||||
// writeTableFiles(zipWriter);
|
// writeTableFiles(zipWriter);
|
||||||
@@ -110,9 +113,10 @@ bool Package::createPackage(const QString &packageName)
|
|||||||
writeThemeFile(zipWriter);
|
writeThemeFile(zipWriter);
|
||||||
writeRootRelsFile(zipWriter);
|
writeRootRelsFile(zipWriter);
|
||||||
writeWorkbookRelsFile(zipWriter);
|
writeWorkbookRelsFile(zipWriter);
|
||||||
writeWorksheetRelsFile(zipWriter);
|
writeWorksheetRelsFiles(zipWriter);
|
||||||
// writeChartsheetRelsFile(zipWriter);
|
// writeChartsheetRelsFile(zipWriter);
|
||||||
// writeImageFiles(zipWriter);
|
writeDrawingRelsFiles(zipWriter);
|
||||||
|
writeImageFiles(zipWriter);
|
||||||
// writeVbaProjectFiles(zipWriter);
|
// writeVbaProjectFiles(zipWriter);
|
||||||
|
|
||||||
zipWriter.close();
|
zipWriter.close();
|
||||||
@@ -144,6 +148,19 @@ void Package::writeWorkbookFile(ZipWriter &zipWriter)
|
|||||||
zipWriter.addFile(QStringLiteral("xl/workbook.xml"), data);
|
zipWriter.addFile(QStringLiteral("xl/workbook.xml"), data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Package::writeDrawingFiles(ZipWriter &zipWriter)
|
||||||
|
{
|
||||||
|
for (int i=0; i<m_workbook->drawings().size(); ++i) {
|
||||||
|
Drawing *drawing = m_workbook->drawings()[i];
|
||||||
|
|
||||||
|
QByteArray data;
|
||||||
|
QBuffer buffer(&data);
|
||||||
|
buffer.open(QIODevice::WriteOnly);
|
||||||
|
drawing->saveToXmlFile(&buffer);
|
||||||
|
zipWriter.addFile(QStringLiteral("xl/drawings/drawing%1.xml").arg(i+1), data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Package::writeContentTypesFiles(ZipWriter &zipWriter)
|
void Package::writeContentTypesFiles(ZipWriter &zipWriter)
|
||||||
{
|
{
|
||||||
ContentTypes content;
|
ContentTypes content;
|
||||||
@@ -158,6 +175,15 @@ void Package::writeContentTypesFiles(ZipWriter &zipWriter)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int drawing_index = 1;
|
||||||
|
foreach (Drawing *drawing, m_workbook->drawings()) {
|
||||||
|
content.addDrawingName(QStringLiteral("drawing%1").arg(drawing_index));
|
||||||
|
drawing_index += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_workbook->images().isEmpty())
|
||||||
|
content.addImageTypes(QStringList()<<QStringLiteral("png"));
|
||||||
|
|
||||||
if (m_workbook->sharedStrings()->count())
|
if (m_workbook->sharedStrings()->count())
|
||||||
content.addSharedString();
|
content.addSharedString();
|
||||||
|
|
||||||
@@ -283,7 +309,7 @@ void Package::writeWorkbookRelsFile(ZipWriter &zipWriter)
|
|||||||
zipWriter.addFile(QStringLiteral("xl/_rels/workbook.xml.rels"), data);
|
zipWriter.addFile(QStringLiteral("xl/_rels/workbook.xml.rels"), data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Package::writeWorksheetRelsFile(ZipWriter &zipWriter)
|
void Package::writeWorksheetRelsFiles(ZipWriter &zipWriter)
|
||||||
{
|
{
|
||||||
int index = 1;
|
int index = 1;
|
||||||
foreach (Worksheet *sheet, m_workbook->worksheets()) {
|
foreach (Worksheet *sheet, m_workbook->worksheets()) {
|
||||||
@@ -293,7 +319,8 @@ void Package::writeWorksheetRelsFile(ZipWriter &zipWriter)
|
|||||||
|
|
||||||
foreach (QString link, sheet->externUrlList())
|
foreach (QString link, sheet->externUrlList())
|
||||||
rels.addWorksheetRelationship(QStringLiteral("/hyperlink"), link, QStringLiteral("External"));
|
rels.addWorksheetRelationship(QStringLiteral("/hyperlink"), link, QStringLiteral("External"));
|
||||||
|
foreach (QString link, sheet->externDrawingList())
|
||||||
|
rels.addWorksheetRelationship(QStringLiteral("/drawing"), link);
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
QBuffer buffer(&data);
|
QBuffer buffer(&data);
|
||||||
buffer.open(QIODevice::WriteOnly);
|
buffer.open(QIODevice::WriteOnly);
|
||||||
@@ -302,4 +329,39 @@ void Package::writeWorksheetRelsFile(ZipWriter &zipWriter)
|
|||||||
index += 1;
|
index += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Package::writeDrawingRelsFiles(ZipWriter &zipWriter)
|
||||||
|
{
|
||||||
|
int index = 1;
|
||||||
|
foreach (Worksheet *sheet, m_workbook->worksheets()) {
|
||||||
|
if (sheet->drawingLinks().size() == 0)
|
||||||
|
continue;
|
||||||
|
Relationships rels;
|
||||||
|
|
||||||
|
typedef QPair<QString, QString> PairType;
|
||||||
|
foreach (PairType pair, sheet->drawingLinks())
|
||||||
|
rels.addDocumentRelationship(pair.first, pair.second);
|
||||||
|
|
||||||
|
QByteArray data;
|
||||||
|
QBuffer buffer(&data);
|
||||||
|
buffer.open(QIODevice::WriteOnly);
|
||||||
|
rels.saveToXmlFile(&buffer);
|
||||||
|
zipWriter.addFile(QStringLiteral("xl/drawings/_rels/drawing%1.xml.rels").arg(index), data);
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Package::writeImageFiles(ZipWriter &zipWriter)
|
||||||
|
{
|
||||||
|
for (int i=0; i<m_workbook->images().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
|
} // namespace QXlsx
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ private:
|
|||||||
// void writeChartsheetFiles(ZipWriter &zipWriter);
|
// void writeChartsheetFiles(ZipWriter &zipWriter);
|
||||||
void writeWorkbookFile(ZipWriter &zipWriter);
|
void writeWorkbookFile(ZipWriter &zipWriter);
|
||||||
// void writeChartFiles(ZipWriter &zipWriter);
|
// void writeChartFiles(ZipWriter &zipWriter);
|
||||||
// void writeDrawingFiles(ZipWriter &zipWriter);
|
void writeDrawingFiles(ZipWriter &zipWriter);
|
||||||
// void writeVmlFiles(ZipWriter &zipWriter);
|
// void writeVmlFiles(ZipWriter &zipWriter);
|
||||||
// void writeCommentFiles(ZipWriter &zipWriter);
|
// void writeCommentFiles(ZipWriter &zipWriter);
|
||||||
// void writeTableFiles(ZipWriter &zipWriter);
|
// void writeTableFiles(ZipWriter &zipWriter);
|
||||||
@@ -56,9 +56,10 @@ private:
|
|||||||
void writeThemeFile(ZipWriter &zipWriter);
|
void writeThemeFile(ZipWriter &zipWriter);
|
||||||
void writeRootRelsFile(ZipWriter &zipWriter);
|
void writeRootRelsFile(ZipWriter &zipWriter);
|
||||||
void writeWorkbookRelsFile(ZipWriter &zipWriter);
|
void writeWorkbookRelsFile(ZipWriter &zipWriter);
|
||||||
void writeWorksheetRelsFile(ZipWriter &zipWriter);
|
void writeWorksheetRelsFiles(ZipWriter &zipWriter);
|
||||||
// void writeChartsheetRelsFile(ZipWriter &zipWriter);
|
// void writeChartsheetRelsFile(ZipWriter &zipWriter);
|
||||||
// void writeImageFiles(ZipWriter &zipWriter);
|
void writeDrawingRelsFiles(ZipWriter &zipWriter);
|
||||||
|
void writeImageFiles(ZipWriter &zipWriter);
|
||||||
// void writeVbaProjectFiles(ZipWriter &zipWriter);
|
// void writeVbaProjectFiles(ZipWriter &zipWriter);
|
||||||
|
|
||||||
Workbook * m_workbook;
|
Workbook * m_workbook;
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include "xlsxformat.h"
|
#include "xlsxformat.h"
|
||||||
#include "xlsxpackage_p.h"
|
#include "xlsxpackage_p.h"
|
||||||
#include "xlsxxmlwriter_p.h"
|
#include "xlsxxmlwriter_p.h"
|
||||||
|
#include "xlsxworksheet_p.h"
|
||||||
|
|
||||||
namespace QXlsx {
|
namespace QXlsx {
|
||||||
|
|
||||||
@@ -221,6 +222,44 @@ Styles *Workbook::styles()
|
|||||||
return d->styles;
|
return d->styles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<QImage> Workbook::images()
|
||||||
|
{
|
||||||
|
Q_D(Workbook);
|
||||||
|
return d->images;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<Drawing *> Workbook::drawings()
|
||||||
|
{
|
||||||
|
Q_D(Workbook);
|
||||||
|
return d->drawings;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Workbook::prepareDrawings()
|
||||||
|
{
|
||||||
|
Q_D(Workbook);
|
||||||
|
int drawing_id = 0;
|
||||||
|
int image_ref_id = 0;
|
||||||
|
d->images.clear();
|
||||||
|
d->drawings.clear();
|
||||||
|
|
||||||
|
foreach (Worksheet *sheet, d->worksheets) {
|
||||||
|
if (sheet->images().isEmpty()) //No drawing (such as Image, ...)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sheet->clearExtraDrawingInfo();
|
||||||
|
|
||||||
|
//At present, only picture type supported
|
||||||
|
drawing_id += 1;
|
||||||
|
for (int idx = 0; idx < sheet->images().size(); ++idx) {
|
||||||
|
image_ref_id += 1;
|
||||||
|
sheet->prepareImage(idx, image_ref_id, drawing_id);
|
||||||
|
d->images.append(sheet->images()[idx]->image);
|
||||||
|
}
|
||||||
|
|
||||||
|
d->drawings.append(sheet->drawing());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Workbook::saveToXmlFile(QIODevice *device)
|
void Workbook::saveToXmlFile(QIODevice *device)
|
||||||
{
|
{
|
||||||
Q_D(Workbook);
|
Q_D(Workbook);
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include "xlsxglobal.h"
|
#include "xlsxglobal.h"
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
#include <QImage>
|
||||||
class QIODevice;
|
class QIODevice;
|
||||||
|
|
||||||
namespace QXlsx {
|
namespace QXlsx {
|
||||||
@@ -37,6 +38,7 @@ class Format;
|
|||||||
class SharedStrings;
|
class SharedStrings;
|
||||||
class Styles;
|
class Styles;
|
||||||
class Package;
|
class Package;
|
||||||
|
class Drawing;
|
||||||
|
|
||||||
class WorkbookPrivate;
|
class WorkbookPrivate;
|
||||||
class Q_XLSX_EXPORT Workbook : public QObject
|
class Q_XLSX_EXPORT Workbook : public QObject
|
||||||
@@ -73,6 +75,9 @@ private:
|
|||||||
|
|
||||||
SharedStrings *sharedStrings();
|
SharedStrings *sharedStrings();
|
||||||
Styles *styles();
|
Styles *styles();
|
||||||
|
QList<QImage> images();
|
||||||
|
QList<Drawing *> drawings();
|
||||||
|
void prepareDrawings();
|
||||||
void saveToXmlFile(QIODevice *device);
|
void saveToXmlFile(QIODevice *device);
|
||||||
|
|
||||||
WorkbookPrivate * const d_ptr;
|
WorkbookPrivate * const d_ptr;
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ public:
|
|||||||
SharedStrings *sharedStrings;
|
SharedStrings *sharedStrings;
|
||||||
QList<Worksheet *> worksheets;
|
QList<Worksheet *> worksheets;
|
||||||
Styles *styles;
|
Styles *styles;
|
||||||
|
QList<QImage> images;
|
||||||
|
QList<Drawing *> drawings;
|
||||||
|
|
||||||
bool strings_to_numbers_enabled;
|
bool strings_to_numbers_enabled;
|
||||||
bool date1904;
|
bool date1904;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "xlsxutility_p.h"
|
#include "xlsxutility_p.h"
|
||||||
#include "xlsxsharedstrings_p.h"
|
#include "xlsxsharedstrings_p.h"
|
||||||
#include "xlsxxmlwriter_p.h"
|
#include "xlsxxmlwriter_p.h"
|
||||||
|
#include "xlsxdrawing_p.h"
|
||||||
|
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
@@ -45,6 +46,8 @@ namespace QXlsx {
|
|||||||
WorksheetPrivate::WorksheetPrivate(Worksheet *p) :
|
WorksheetPrivate::WorksheetPrivate(Worksheet *p) :
|
||||||
q_ptr(p)
|
q_ptr(p)
|
||||||
{
|
{
|
||||||
|
drawing = 0;
|
||||||
|
|
||||||
xls_rowmax = 1048576;
|
xls_rowmax = 1048576;
|
||||||
xls_colmax = 16384;
|
xls_colmax = 16384;
|
||||||
xls_strmax = 32767;
|
xls_strmax = 32767;
|
||||||
@@ -264,6 +267,18 @@ QStringList Worksheet::externUrlList() const
|
|||||||
return d->externUrlList;
|
return d->externUrlList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QStringList Worksheet::externDrawingList() const
|
||||||
|
{
|
||||||
|
Q_D(const Worksheet);
|
||||||
|
return d->externDrawingList;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QPair<QString, QString> > Worksheet::drawingLinks() const
|
||||||
|
{
|
||||||
|
Q_D(const Worksheet);
|
||||||
|
return d->drawingLinks;
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
@@ -461,6 +476,14 @@ int Worksheet::writeUrl(int row, int column, const QUrl &url, Format *format, co
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Worksheet::insertImage(int row, int column, const QImage &image, const QPointF &offset, double xScale, double yScale)
|
||||||
|
{
|
||||||
|
Q_D(Worksheet);
|
||||||
|
|
||||||
|
d->imageList.append(new XlsxImageData(row, column, image, offset, xScale, yScale));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void Worksheet::saveToXmlFile(QIODevice *device)
|
void Worksheet::saveToXmlFile(QIODevice *device)
|
||||||
{
|
{
|
||||||
Q_D(Worksheet);
|
Q_D(Worksheet);
|
||||||
@@ -533,6 +556,7 @@ void Worksheet::saveToXmlFile(QIODevice *device)
|
|||||||
writer.writeEndElement();//sheetData
|
writer.writeEndElement();//sheetData
|
||||||
|
|
||||||
d->writeHyperlinks(writer);
|
d->writeHyperlinks(writer);
|
||||||
|
d->writeDrawings(writer);
|
||||||
|
|
||||||
writer.writeEndElement();//worksheet
|
writer.writeEndElement();//worksheet
|
||||||
writer.writeEndDocument();
|
writer.writeEndDocument();
|
||||||
@@ -681,6 +705,13 @@ void WorksheetPrivate::writeHyperlinks(XmlStreamWriter &writer)
|
|||||||
writer.writeEndElement();//hyperlinks
|
writer.writeEndElement();//hyperlinks
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WorksheetPrivate::writeDrawings(XmlStreamWriter &writer)
|
||||||
|
{
|
||||||
|
int index = externUrlList.size() + 1;
|
||||||
|
writer.writeEmptyElement(QStringLiteral("drawing"));
|
||||||
|
writer.writeAttribute(QStringLiteral("r:id"), QStringLiteral("rId%1").arg(index));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
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.
|
||||||
@@ -729,4 +760,192 @@ bool Worksheet::setColumn(int colFirst, int colLast, double width, Format *forma
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Drawing *Worksheet::drawing() const
|
||||||
|
{
|
||||||
|
Q_D(const Worksheet);
|
||||||
|
return d->drawing;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<XlsxImageData *> Worksheet::images() const
|
||||||
|
{
|
||||||
|
Q_D(const Worksheet);
|
||||||
|
return d->imageList;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Worksheet::clearExtraDrawingInfo()
|
||||||
|
{
|
||||||
|
Q_D(Worksheet);
|
||||||
|
if (d->drawing) {
|
||||||
|
delete d->drawing;
|
||||||
|
d->drawing = 0;
|
||||||
|
d->externDrawingList.clear();
|
||||||
|
d->drawingLinks.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Worksheet::prepareImage(int index, int image_id, int drawing_id)
|
||||||
|
{
|
||||||
|
Q_D(Worksheet);
|
||||||
|
if (!d->drawing) {
|
||||||
|
d->drawing = new Drawing(this);
|
||||||
|
d->drawing->embedded = true;
|
||||||
|
d->externDrawingList.append(QStringLiteral("../drawings/drawing%1.xml").arg(drawing_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
XlsxImageData *imageData = d->imageList[index];
|
||||||
|
|
||||||
|
XlsxDrawingDimensionData *data = new XlsxDrawingDimensionData;
|
||||||
|
data->drawing_type = 2;
|
||||||
|
|
||||||
|
double width = imageData->image.width() * imageData->xScale;
|
||||||
|
double height = imageData->image.height() * imageData->yScale;
|
||||||
|
|
||||||
|
XlsxObjectPositionData posData = d->pixelsToEMUs(d->objectPixelsPosition(imageData->col, imageData->row, imageData->offset.x(), imageData->offset.y(), width, height));
|
||||||
|
data->col_from = posData.col_start;
|
||||||
|
data->col_from_offset = posData.x1;
|
||||||
|
data->row_from = posData.row_start;
|
||||||
|
data->row_from_offset = posData.y1;
|
||||||
|
data->col_to = posData.col_end;
|
||||||
|
data->col_to_offset = posData.x2;
|
||||||
|
data->row_to = posData.row_end;
|
||||||
|
data->row_to_offset = posData.y2;
|
||||||
|
data->width = posData.width;
|
||||||
|
data->height = posData.height;
|
||||||
|
data->col_absolute = posData.x_abs;
|
||||||
|
data->row_absolute = posData.y_abs;
|
||||||
|
|
||||||
|
d->drawing->dimensionList.append(data);
|
||||||
|
|
||||||
|
d->drawingLinks.append(QPair<QString, QString>(QStringLiteral("/image"), QStringLiteral("../media/image%1.png").arg(image_id)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Convert the height of a cell from user's units to pixels. If the
|
||||||
|
height hasn't been set by the user we use the default value. If
|
||||||
|
the row is hidden it has a value of zero.
|
||||||
|
*/
|
||||||
|
int WorksheetPrivate::rowPixelsSize(int row)
|
||||||
|
{
|
||||||
|
double height;
|
||||||
|
if (row_sizes.contains(row))
|
||||||
|
height = row_sizes[row];
|
||||||
|
else
|
||||||
|
height = default_row_height;
|
||||||
|
return static_cast<int>(4.0 / 3.0 *height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Convert the width of a cell from user's units to pixels. Excel rounds
|
||||||
|
the column width to the nearest pixel. If the width hasn't been set
|
||||||
|
by the user we use the default value. If the column is hidden it
|
||||||
|
has a value of zero.
|
||||||
|
*/
|
||||||
|
int WorksheetPrivate::colPixelsSize(int col)
|
||||||
|
{
|
||||||
|
double max_digit_width = 7.0; //For Calabri 11
|
||||||
|
double padding = 5.0;
|
||||||
|
int pixels = 0;
|
||||||
|
|
||||||
|
if (col_sizes.contains(col)) {
|
||||||
|
double width = col_sizes[col];
|
||||||
|
if (width < 1)
|
||||||
|
pixels = static_cast<int>(width * (max_digit_width + padding) + 0.5);
|
||||||
|
else
|
||||||
|
pixels = static_cast<int>(width * max_digit_width + 0.5) + padding;
|
||||||
|
} else {
|
||||||
|
pixels = 64;
|
||||||
|
}
|
||||||
|
return pixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
col_start Col containing upper left corner of object.
|
||||||
|
x1 Distance to left side of object.
|
||||||
|
row_start Row containing top left corner of object.
|
||||||
|
y1 Distance to top of object.
|
||||||
|
col_end Col containing lower right corner of object.
|
||||||
|
x2 Distance to right side of object.
|
||||||
|
row_end Row containing bottom right corner of object.
|
||||||
|
y2 Distance to bottom of object.
|
||||||
|
width Width of object frame.
|
||||||
|
height Height of object frame.
|
||||||
|
x_abs Absolute distance to left side of object.
|
||||||
|
y_abs Absolute distance to top side of object.
|
||||||
|
*/
|
||||||
|
XlsxObjectPositionData WorksheetPrivate::objectPixelsPosition(int col_start, int row_start, double x1, double y1, double width, double height)
|
||||||
|
{
|
||||||
|
double x_abs = 0;
|
||||||
|
double y_abs = 0;
|
||||||
|
for (int col_id = 1; col_id < col_start; ++col_id)
|
||||||
|
x_abs += colPixelsSize(col_id);
|
||||||
|
x_abs += x1;
|
||||||
|
for (int row_id = 1; row_id < row_start; ++row_id)
|
||||||
|
y_abs += rowPixelsSize(row_id);
|
||||||
|
y_abs += y1;
|
||||||
|
|
||||||
|
// Adjust start column for offsets that are greater than the col width.
|
||||||
|
while (x1 > colPixelsSize(col_start)) {
|
||||||
|
x1 -= colPixelsSize(col_start);
|
||||||
|
col_start += 1;
|
||||||
|
}
|
||||||
|
while (y1 > rowPixelsSize(row_start)) {
|
||||||
|
y1 -= rowPixelsSize(row_start);
|
||||||
|
row_start += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int col_end = col_start;
|
||||||
|
int row_end = row_start;
|
||||||
|
double x2 = width + x1;
|
||||||
|
double y2 = height + y1;
|
||||||
|
|
||||||
|
while (x2 > colPixelsSize(col_end)) {
|
||||||
|
x2 -= colPixelsSize(col_end);
|
||||||
|
col_end += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (y2 > rowPixelsSize(row_end)) {
|
||||||
|
y2 -= rowPixelsSize(row_end);
|
||||||
|
row_end += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
XlsxObjectPositionData data;
|
||||||
|
data.col_start = col_start;
|
||||||
|
data.x1 = x1;
|
||||||
|
data.row_start = row_start;
|
||||||
|
data.y1 = y1;
|
||||||
|
data.col_end = col_end;
|
||||||
|
data.x2 = x2;
|
||||||
|
data.row_end = row_end;
|
||||||
|
data.y2 = y2;
|
||||||
|
data.x_abs = x_abs;
|
||||||
|
data.y_abs = y_abs;
|
||||||
|
data.width = width;
|
||||||
|
data.height = height;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Calculate the vertices that define the position of a graphical
|
||||||
|
object within the worksheet in EMUs.
|
||||||
|
|
||||||
|
The vertices are expressed as English Metric Units (EMUs). There are
|
||||||
|
12,700 EMUs per point. Therefore, 12,700 * 3 /4 = 9,525 EMUs per
|
||||||
|
pixel
|
||||||
|
*/
|
||||||
|
XlsxObjectPositionData WorksheetPrivate::pixelsToEMUs(const XlsxObjectPositionData &data)
|
||||||
|
{
|
||||||
|
XlsxObjectPositionData result = data;
|
||||||
|
result.x1 = static_cast<int>(data.x1 * 9525 + 0.5);
|
||||||
|
result.y1 = static_cast<int>(data.y1 * 9525 + 0.5);
|
||||||
|
result.x2 = static_cast<int>(data.x2 * 9525 + 0.5);
|
||||||
|
result.y2 = static_cast<int>(data.y2 * 9525 + 0.5);
|
||||||
|
result.x_abs = static_cast<int>(data.x_abs * 9525 + 0.5);
|
||||||
|
result.y_abs = static_cast<int>(data.y_abs * 9525 + 0.5);
|
||||||
|
result.width = static_cast<int>(data.width * 9525 + 0.5);
|
||||||
|
result.height = static_cast<int>(data.height * 9525 + 0.5);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
} //namespace
|
} //namespace
|
||||||
|
|||||||
@@ -30,15 +30,19 @@
|
|||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
#include <QPointF>
|
||||||
class QIODevice;
|
class QIODevice;
|
||||||
class QDateTime;
|
class QDateTime;
|
||||||
class QUrl;
|
class QUrl;
|
||||||
|
class QImage;
|
||||||
|
|
||||||
namespace QXlsx {
|
namespace QXlsx {
|
||||||
class Package;
|
class Package;
|
||||||
class Workbook;
|
class Workbook;
|
||||||
class XmlStreamWriter;
|
class XmlStreamWriter;
|
||||||
class Format;
|
class Format;
|
||||||
|
class Drawing;
|
||||||
|
struct XlsxImageData;
|
||||||
|
|
||||||
class WorksheetPrivate;
|
class WorksheetPrivate;
|
||||||
class Q_XLSX_EXPORT Worksheet : public QObject
|
class Q_XLSX_EXPORT Worksheet : public QObject
|
||||||
@@ -56,6 +60,8 @@ public:
|
|||||||
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());
|
int writeUrl(int row, int column, const QUrl &url, Format *format=0, const QString &display=QString(), const QString &tip=QString());
|
||||||
|
|
||||||
|
int insertImage(int row, int column, const QImage &image, const QPointF &offset=QPointF(), double xScale=1, double yScale=1);
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
@@ -76,6 +82,12 @@ private:
|
|||||||
void setSelected(bool select);
|
void setSelected(bool select);
|
||||||
void saveToXmlFile(QIODevice *device);
|
void saveToXmlFile(QIODevice *device);
|
||||||
QStringList externUrlList() const;
|
QStringList externUrlList() const;
|
||||||
|
QStringList externDrawingList() const;
|
||||||
|
QList<QPair<QString, QString> > drawingLinks() const;
|
||||||
|
Drawing *drawing() const;
|
||||||
|
QList<XlsxImageData *> images() const;
|
||||||
|
void prepareImage(int index, int image_id, int drawing_id);
|
||||||
|
void clearExtraDrawingInfo();
|
||||||
|
|
||||||
WorksheetPrivate * const d_ptr;
|
WorksheetPrivate * const d_ptr;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
#define XLSXWORKSHEET_P_H
|
#define XLSXWORKSHEET_P_H
|
||||||
#include "xlsxworksheet.h"
|
#include "xlsxworksheet.h"
|
||||||
|
|
||||||
|
#include <QImage>
|
||||||
|
|
||||||
namespace QXlsx {
|
namespace QXlsx {
|
||||||
|
|
||||||
struct XlsxCellData
|
struct XlsxCellData
|
||||||
@@ -65,6 +67,67 @@ struct XlsxUrlData
|
|||||||
QString tip;
|
QString tip;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct XlsxImageData
|
||||||
|
{
|
||||||
|
XlsxImageData(int row, int col, const QImage &image, const QPointF &offset, double xScale, double yScale) :
|
||||||
|
row(row), col(col), image(image), offset(offset), xScale(xScale), yScale(yScale)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int row;
|
||||||
|
int col;
|
||||||
|
QImage image;
|
||||||
|
QPointF offset;
|
||||||
|
double xScale;
|
||||||
|
double yScale;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
The vertices that define the position of a graphical object
|
||||||
|
within the worksheet in pixels.
|
||||||
|
|
||||||
|
+------------+------------+
|
||||||
|
| A | B |
|
||||||
|
+-----+------------+------------+
|
||||||
|
| |(x1,y1) | |
|
||||||
|
| 1 |(A1)._______|______ |
|
||||||
|
| | | | |
|
||||||
|
| | | | |
|
||||||
|
+-----+----| OBJECT |-----+
|
||||||
|
| | | | |
|
||||||
|
| 2 | |______________. |
|
||||||
|
| | | (B2)|
|
||||||
|
| | | (x2,y2)|
|
||||||
|
+---- +------------+------------+
|
||||||
|
|
||||||
|
Example of an object that covers some of the area from cell A1 to B2.
|
||||||
|
|
||||||
|
Based on the width and height of the object we need to calculate 8 vars:
|
||||||
|
|
||||||
|
col_start, row_start, col_end, row_end, x1, y1, x2, y2.
|
||||||
|
|
||||||
|
We also calculate the absolute x and y position of the top left vertex of
|
||||||
|
the object. This is required for images.
|
||||||
|
|
||||||
|
The width and height of the cells that the object occupies can be
|
||||||
|
variable and have to be taken into account.
|
||||||
|
*/
|
||||||
|
struct XlsxObjectPositionData
|
||||||
|
{
|
||||||
|
int col_start;
|
||||||
|
double x1;
|
||||||
|
int row_start;
|
||||||
|
double y1;
|
||||||
|
int col_end;
|
||||||
|
double x2;
|
||||||
|
int row_end;
|
||||||
|
double y2;
|
||||||
|
double width;
|
||||||
|
double height;
|
||||||
|
double x_abs;
|
||||||
|
double y_abs;
|
||||||
|
};
|
||||||
|
|
||||||
struct XlsxRowInfo
|
struct XlsxRowInfo
|
||||||
{
|
{
|
||||||
XlsxRowInfo(double height, Format *format, bool hidden) :
|
XlsxRowInfo(double height, Format *format, bool hidden) :
|
||||||
@@ -104,15 +167,24 @@ public:
|
|||||||
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);
|
void writeHyperlinks(XmlStreamWriter &writer);
|
||||||
|
void writeDrawings(XmlStreamWriter &writer);
|
||||||
|
int rowPixelsSize(int row);
|
||||||
|
int colPixelsSize(int col);
|
||||||
|
XlsxObjectPositionData objectPixelsPosition(int col_start, int row_start, double x1, double y1, double width, double height);
|
||||||
|
XlsxObjectPositionData pixelsToEMUs(const XlsxObjectPositionData &data);
|
||||||
|
|
||||||
Workbook *workbook;
|
Workbook *workbook;
|
||||||
|
Drawing *drawing;
|
||||||
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;
|
QMap<int, QMap<int, XlsxUrlData *> > urlTable;
|
||||||
QStringList externUrlList;
|
QStringList externUrlList;
|
||||||
|
QStringList externDrawingList;
|
||||||
|
QList<XlsxImageData *> imageList;
|
||||||
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
|
||||||
|
QList<QPair<QString, QString> > drawingLinks;
|
||||||
|
|
||||||
int xls_rowmax;
|
int xls_rowmax;
|
||||||
int xls_colmax;
|
int xls_colmax;
|
||||||
@@ -124,6 +196,8 @@ public:
|
|||||||
int previous_row;
|
int previous_row;
|
||||||
|
|
||||||
QMap<int, QString> row_spans;
|
QMap<int, QString> row_spans;
|
||||||
|
QMap<int, double> row_sizes;
|
||||||
|
QMap<int, double> col_sizes;
|
||||||
|
|
||||||
int outline_row_level;
|
int outline_row_level;
|
||||||
int outline_col_level;
|
int outline_col_level;
|
||||||
|
|||||||
Reference in New Issue
Block a user