Can read .xlsx files with cols and rows info
This commit is contained in:
+67
-19
@@ -75,12 +75,6 @@ WorksheetPrivate::WorksheetPrivate(Worksheet *p) :
|
|||||||
|
|
||||||
WorksheetPrivate::~WorksheetPrivate()
|
WorksheetPrivate::~WorksheetPrivate()
|
||||||
{
|
{
|
||||||
foreach (XlsxRowInfo *row, rowsInfo)
|
|
||||||
delete row;
|
|
||||||
|
|
||||||
foreach (XlsxColumnInfo *col, colsInfo)
|
|
||||||
delete col;
|
|
||||||
|
|
||||||
if (drawing)
|
if (drawing)
|
||||||
delete drawing;
|
delete drawing;
|
||||||
}
|
}
|
||||||
@@ -621,7 +615,8 @@ void Worksheet::saveToXmlFile(QIODevice *device)
|
|||||||
|
|
||||||
if (!d->colsInfo.isEmpty()) {
|
if (!d->colsInfo.isEmpty()) {
|
||||||
writer.writeStartElement(QStringLiteral("cols"));
|
writer.writeStartElement(QStringLiteral("cols"));
|
||||||
foreach (XlsxColumnInfo *col_info, d->colsInfo) {
|
for (int i=0; i<d->colsInfo.size(); ++i) {
|
||||||
|
QSharedPointer<XlsxColumnInfo> col_info = d->colsInfo[i];
|
||||||
writer.writeStartElement(QStringLiteral("col"));
|
writer.writeStartElement(QStringLiteral("col"));
|
||||||
writer.writeAttribute(QStringLiteral("min"), QString::number(col_info->column_min + 1));
|
writer.writeAttribute(QStringLiteral("min"), QString::number(col_info->column_min + 1));
|
||||||
writer.writeAttribute(QStringLiteral("max"), QString::number(col_info->column_max));
|
writer.writeAttribute(QStringLiteral("max"), QString::number(col_info->column_max));
|
||||||
@@ -675,7 +670,7 @@ void WorksheetPrivate::writeSheetData(XmlStreamWriter &writer)
|
|||||||
writer.writeAttribute(QStringLiteral("spans"), span);
|
writer.writeAttribute(QStringLiteral("spans"), span);
|
||||||
|
|
||||||
if (rowsInfo.contains(row_num)) {
|
if (rowsInfo.contains(row_num)) {
|
||||||
XlsxRowInfo *rowInfo = rowsInfo[row_num];
|
QSharedPointer<XlsxRowInfo> rowInfo = rowsInfo[row_num];
|
||||||
if (rowInfo->format) {
|
if (rowInfo->format) {
|
||||||
writer.writeAttribute(QStringLiteral("s"), QString::number(rowInfo->format->xfIndex()));
|
writer.writeAttribute(QStringLiteral("s"), QString::number(rowInfo->format->xfIndex()));
|
||||||
writer.writeAttribute(QStringLiteral("customFormat"), QStringLiteral("1"));
|
writer.writeAttribute(QStringLiteral("customFormat"), QStringLiteral("1"));
|
||||||
@@ -836,13 +831,7 @@ bool Worksheet::setRow(int row, double height, Format *format, bool hidden)
|
|||||||
if (d->checkDimensions(row, min_col))
|
if (d->checkDimensions(row, min_col))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (d->rowsInfo.contains(row)) {
|
d->rowsInfo[row] = QSharedPointer<XlsxRowInfo>(new XlsxRowInfo(height, format, hidden));
|
||||||
d->rowsInfo[row]->height = height;
|
|
||||||
d->rowsInfo[row]->format = format;
|
|
||||||
d->rowsInfo[row]->hidden = hidden;
|
|
||||||
} else {
|
|
||||||
d->rowsInfo[row] = new XlsxRowInfo(height, format, hidden);
|
|
||||||
}
|
|
||||||
d->workbook->styles()->addFormat(format);
|
d->workbook->styles()->addFormat(format);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -867,10 +856,10 @@ bool Worksheet::setColumn(int colFirst, int colLast, double width, Format *forma
|
|||||||
if (d->checkDimensions(0, colFirst, ignore_row, ignore_col))
|
if (d->checkDimensions(0, colFirst, ignore_row, ignore_col))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
XlsxColumnInfo *info = new XlsxColumnInfo(colFirst, colLast, width, format, hidden);
|
QSharedPointer<XlsxColumnInfo> info(new XlsxColumnInfo(colFirst, colLast, width, format, hidden));
|
||||||
d->colsInfo.append(info);
|
d->colsInfo.append(info);
|
||||||
|
|
||||||
for (int col=colFirst; col<=colLast; ++col)
|
for (int col=colFirst; col<colLast; ++col)
|
||||||
d->colsInfoHelper[col] = info;
|
d->colsInfoHelper[col] = info;
|
||||||
|
|
||||||
d->workbook->styles()->addFormat(format);
|
d->workbook->styles()->addFormat(format);
|
||||||
@@ -1084,7 +1073,29 @@ void WorksheetPrivate::readSheetData(XmlStreamReader &reader)
|
|||||||
reader.readNextStartElement();
|
reader.readNextStartElement();
|
||||||
|
|
||||||
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||||
if (reader.name() == QLatin1String("c")) {
|
if (reader.name() == QLatin1String("row")) {
|
||||||
|
QXmlStreamAttributes attributes = reader.attributes();
|
||||||
|
|
||||||
|
if (attributes.hasAttribute(QLatin1String("customFormat"))
|
||||||
|
|| attributes.hasAttribute(QLatin1String("customHeight"))
|
||||||
|
|| attributes.hasAttribute(QLatin1String("hidden"))) {
|
||||||
|
|
||||||
|
QSharedPointer<XlsxRowInfo> info(new XlsxRowInfo);
|
||||||
|
if (attributes.hasAttribute(QLatin1String("customFormat")) && attributes.hasAttribute(QLatin1String("s"))) {
|
||||||
|
int idx = attributes.value(QLatin1String("s")).toInt();
|
||||||
|
info->format = workbook->styles()->xfFormat(idx);
|
||||||
|
}
|
||||||
|
if (attributes.hasAttribute(QLatin1String("customHeight")) && attributes.hasAttribute(QLatin1String("ht"))) {
|
||||||
|
info->height = attributes.value(QLatin1String("ht")).toDouble();
|
||||||
|
}
|
||||||
|
if (attributes.hasAttribute(QLatin1String("hidden")))
|
||||||
|
info->hidden = true;
|
||||||
|
|
||||||
|
int row = attributes.value(QLatin1String("r")).toInt();
|
||||||
|
rowsInfo[row] = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (reader.name() == QLatin1String("c")) {
|
||||||
QXmlStreamAttributes attributes = reader.attributes();
|
QXmlStreamAttributes attributes = reader.attributes();
|
||||||
QString r = attributes.value(QLatin1String("r")).toString();
|
QString r = attributes.value(QLatin1String("r")).toString();
|
||||||
QPoint pos = xl_cell_to_rowcol(r);
|
QPoint pos = xl_cell_to_rowcol(r);
|
||||||
@@ -1124,6 +1135,43 @@ void WorksheetPrivate::readSheetData(XmlStreamReader &reader)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WorksheetPrivate::readColumnsInfo(XmlStreamReader &reader)
|
||||||
|
{
|
||||||
|
Q_ASSERT(reader.name() == QLatin1String("cols"));
|
||||||
|
|
||||||
|
while(!(reader.name() == QLatin1String("cols") && reader.tokenType() == QXmlStreamReader::EndElement)) {
|
||||||
|
reader.readNextStartElement();
|
||||||
|
if (reader.tokenType() == QXmlStreamReader::StartElement) {
|
||||||
|
if (reader.name() == QLatin1String("col")) {
|
||||||
|
QSharedPointer<XlsxColumnInfo> info(new XlsxColumnInfo);
|
||||||
|
|
||||||
|
QXmlStreamAttributes colAttrs = reader.attributes();
|
||||||
|
int min = colAttrs.value(QLatin1String("min")).toInt();
|
||||||
|
int max = colAttrs.value(QLatin1String("max")).toInt();
|
||||||
|
info->column_min = min - 1;
|
||||||
|
info->column_max = max;
|
||||||
|
|
||||||
|
if (colAttrs.hasAttribute(QLatin1String("customWidth"))) {
|
||||||
|
double width = colAttrs.value(QLatin1String("width")).toDouble();
|
||||||
|
info->width = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colAttrs.hasAttribute(QLatin1String("hidden")))
|
||||||
|
info->hidden = true;
|
||||||
|
|
||||||
|
if (colAttrs.hasAttribute(QLatin1String("style"))) {
|
||||||
|
int idx = colAttrs.value(QLatin1String("style")).toInt();
|
||||||
|
info->format = workbook->styles()->xfFormat(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
colsInfo.append(info);
|
||||||
|
for (int col=min; col<max; ++col)
|
||||||
|
colsInfoHelper[col] = info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Worksheet::loadFromXmlFile(QIODevice *device)
|
bool Worksheet::loadFromXmlFile(QIODevice *device)
|
||||||
{
|
{
|
||||||
Q_D(Worksheet);
|
Q_D(Worksheet);
|
||||||
@@ -1154,7 +1202,7 @@ bool Worksheet::loadFromXmlFile(QIODevice *device)
|
|||||||
} else if (reader.name() == QLatin1String("sheetFormatPr")) {
|
} else if (reader.name() == QLatin1String("sheetFormatPr")) {
|
||||||
|
|
||||||
} else if (reader.name() == QLatin1String("cols")) {
|
} else if (reader.name() == QLatin1String("cols")) {
|
||||||
|
d->readColumnsInfo(reader);
|
||||||
} else if (reader.name() == QLatin1String("sheetData")) {
|
} else if (reader.name() == QLatin1String("sheetData")) {
|
||||||
d->readSheetData(reader);
|
d->readSheetData(reader);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ struct XlsxObjectPositionData
|
|||||||
|
|
||||||
struct XlsxRowInfo
|
struct XlsxRowInfo
|
||||||
{
|
{
|
||||||
XlsxRowInfo(double height, Format *format, bool hidden) :
|
XlsxRowInfo(double height=0, Format *format=0, bool hidden=false) :
|
||||||
height(height), format(format), hidden(hidden)
|
height(height), format(format), hidden(hidden)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -165,7 +165,7 @@ struct XlsxRowInfo
|
|||||||
|
|
||||||
struct XlsxColumnInfo
|
struct XlsxColumnInfo
|
||||||
{
|
{
|
||||||
XlsxColumnInfo(int column_min, int column_max, double width, Format *format, bool hidden) :
|
XlsxColumnInfo(int column_min=0, int column_max=1, double width=0, Format *format=0, bool hidden=false) :
|
||||||
column_min(column_min), column_max(column_max), width(width), format(format), hidden(hidden)
|
column_min(column_min), column_max(column_max), width(width), format(format), hidden(hidden)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -197,6 +197,7 @@ public:
|
|||||||
XlsxObjectPositionData pixelsToEMUs(const XlsxObjectPositionData &data);
|
XlsxObjectPositionData pixelsToEMUs(const XlsxObjectPositionData &data);
|
||||||
|
|
||||||
void readSheetData(XmlStreamReader &reader);
|
void readSheetData(XmlStreamReader &reader);
|
||||||
|
void readColumnsInfo(XmlStreamReader &reader);
|
||||||
|
|
||||||
Workbook *workbook;
|
Workbook *workbook;
|
||||||
Drawing *drawing;
|
Drawing *drawing;
|
||||||
@@ -207,9 +208,9 @@ public:
|
|||||||
QStringList externUrlList;
|
QStringList externUrlList;
|
||||||
QStringList externDrawingList;
|
QStringList externDrawingList;
|
||||||
QList<XlsxImageData *> imageList;
|
QList<XlsxImageData *> imageList;
|
||||||
QMap<int, XlsxRowInfo *> rowsInfo;
|
QMap<int, QSharedPointer<XlsxRowInfo> > rowsInfo;
|
||||||
QList<XlsxColumnInfo *> colsInfo;
|
QList<QSharedPointer<XlsxColumnInfo> > colsInfo;
|
||||||
QMap<int, XlsxColumnInfo *> colsInfoHelper;//Not owns the XlsxColumnInfo
|
QMap<int, QSharedPointer<XlsxColumnInfo> > colsInfoHelper;
|
||||||
QList<QPair<QString, QString> > drawingLinks;
|
QList<QPair<QString, QString> > drawingLinks;
|
||||||
|
|
||||||
int xls_rowmax;
|
int xls_rowmax;
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ private Q_SLOTS:
|
|||||||
void testUnMerge();
|
void testUnMerge();
|
||||||
|
|
||||||
void testReadSheetData();
|
void testReadSheetData();
|
||||||
|
void testReadColsInfo();
|
||||||
|
void testReadRowsInfo();
|
||||||
};
|
};
|
||||||
|
|
||||||
WorksheetTest::WorksheetTest()
|
WorksheetTest::WorksheetTest()
|
||||||
@@ -74,6 +76,41 @@ void WorksheetTest::testReadSheetData()
|
|||||||
QCOMPARE(sheet.d_ptr->cellTable.size(), 2);
|
QCOMPARE(sheet.d_ptr->cellTable.size(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WorksheetTest::testReadColsInfo()
|
||||||
|
{
|
||||||
|
const QByteArray xmlData = "<cols>"
|
||||||
|
"<col min=\"9\" max=\"15\" width=\"5\" style=\"4\" customWidth=\"1\"/>"
|
||||||
|
"</cols>";
|
||||||
|
QXlsx::XmlStreamReader reader(xmlData);
|
||||||
|
reader.readNextStartElement();//current node is cols
|
||||||
|
|
||||||
|
QXlsx::Worksheet sheet("", 0);
|
||||||
|
sheet.d_ptr->readColumnsInfo(reader);
|
||||||
|
|
||||||
|
QCOMPARE(sheet.d_ptr->colsInfo.size(), 1);
|
||||||
|
QCOMPARE(sheet.d_ptr->colsInfo[0]->width, 5.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorksheetTest::testReadRowsInfo()
|
||||||
|
{
|
||||||
|
const QByteArray xmlData = "<sheetData>"
|
||||||
|
"<row r=\"1\" spans=\"1:6\">"
|
||||||
|
"<c r=\"A1\" s=\"1\" t=\"s\"><v>0</v></c>"
|
||||||
|
"</row>"
|
||||||
|
"<row r=\"3\" spans=\"1:6\" s=\"3\" customFormat=\"1\" ht=\"40\" customHeight=\"1\">"
|
||||||
|
"<c r=\"B3\" s=\"3\"><v>12345</v></c>"
|
||||||
|
"</row>"
|
||||||
|
"</sheetData>";
|
||||||
|
QXlsx::XmlStreamReader reader(xmlData);
|
||||||
|
reader.readNextStartElement();//current node is sheetData
|
||||||
|
|
||||||
|
QXlsx::Worksheet sheet("", 0);
|
||||||
|
sheet.d_ptr->readSheetData(reader);
|
||||||
|
|
||||||
|
QCOMPARE(sheet.d_ptr->rowsInfo.size(), 1);
|
||||||
|
QCOMPARE(sheet.d_ptr->rowsInfo[3]->height, 40.0);
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_APPLESS_MAIN(WorksheetTest)
|
QTEST_APPLESS_MAIN(WorksheetTest)
|
||||||
|
|
||||||
#include "tst_worksheet.moc"
|
#include "tst_worksheet.moc"
|
||||||
|
|||||||
Reference in New Issue
Block a user