Fix Issue1: Add insert_image() function
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
#include "xlsxutility_p.h"
|
||||
#include "xlsxsharedstrings_p.h"
|
||||
#include "xlsxxmlwriter_p.h"
|
||||
#include "xlsxdrawing_p.h"
|
||||
|
||||
#include <QVariant>
|
||||
#include <QDateTime>
|
||||
@@ -45,6 +46,8 @@ namespace QXlsx {
|
||||
WorksheetPrivate::WorksheetPrivate(Worksheet *p) :
|
||||
q_ptr(p)
|
||||
{
|
||||
drawing = 0;
|
||||
|
||||
xls_rowmax = 1048576;
|
||||
xls_colmax = 16384;
|
||||
xls_strmax = 32767;
|
||||
@@ -264,6 +267,18 @@ QStringList Worksheet::externUrlList() const
|
||||
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)
|
||||
{
|
||||
Q_D(Worksheet);
|
||||
@@ -461,6 +476,14 @@ int Worksheet::writeUrl(int row, int column, const QUrl &url, Format *format, co
|
||||
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)
|
||||
{
|
||||
Q_D(Worksheet);
|
||||
@@ -533,6 +556,7 @@ void Worksheet::saveToXmlFile(QIODevice *device)
|
||||
writer.writeEndElement();//sheetData
|
||||
|
||||
d->writeHyperlinks(writer);
|
||||
d->writeDrawings(writer);
|
||||
|
||||
writer.writeEndElement();//worksheet
|
||||
writer.writeEndDocument();
|
||||
@@ -681,6 +705,13 @@ void WorksheetPrivate::writeHyperlinks(XmlStreamWriter &writer)
|
||||
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
|
||||
equals 0 then format is ignored.
|
||||
@@ -729,4 +760,192 @@ bool Worksheet::setColumn(int colFirst, int colLast, double width, Format *forma
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user