-
-
Notifications
You must be signed in to change notification settings - Fork 417
Description
I need to copy a sheet from one document to another.
I've found two ways to do it:
1- write a similar method of Worksheet::copy,
2- upload and download xml data of worksheet: upload sheet from workbook A and download its xml-data to worksheet of workbook B.
1.
Method Worksheet::copy works almost fine inside one workbook, except rows and columns sizes (and maybe other properties, because I saw commented code there).
I take this method as a foundation for new method Worksheet::clone. It makes copy of current sheet with parent of another workbook.
I create a new worksheet with workbook B parent.
Copy all properties of workbook A sheet to it.
As a result all data was copied, but failed next:
- rows sizes,
- cell formats.
main.cpp
QXlsx::Document docA("docA.xlsx");
if (!docA.load())
{
qFatal("File not loaded.");
return EXIT_FAILURE;
}
QXlsx::Document docB;
auto sheetClone = docA.currentWorksheet()->clone(docB.workbook());
docB.addSheet(sheetClone);
docB.saveAs("docB.xlsx);
return EXIT_SUCCESS;
Worksheet.cpp
Worksheet *Worksheet::clone(Workbook *dstWb)
{
Q_D(const Worksheet);
auto newSheet = new Worksheet(d_func()->name, 0, dstWb, F_LoadFromExists);
WorksheetPrivate *dNewSheet = newSheet->d_func();
dNewSheet->sheetFormatProps = d->sheetFormatProps;
qInfo() << "cols info: " << dNewSheet->colsInfo.size() << d->colsInfo.size();
qInfo() << "rows info: " << dNewSheet->rowsInfo.size() << d->rowsInfo.size();
qInfo() << "rows sizes: " << dNewSheet->row_sizes.size() << d->row_sizes.size();
dNewSheet->colsInfo = d->colsInfo;
dNewSheet->colsInfoHelper = d->colsInfoHelper;
dNewSheet->rowsInfo = d->rowsInfo;
dNewSheet->row_spans = d->row_spans;
dNewSheet->row_sizes = d->row_sizes;
dNewSheet->col_sizes = d->col_sizes;
dNewSheet->dimension = d->dimension;
for (auto it = d->cellTable.cells.begin(); it != d->cellTable.cells.end(); ++it) {
int row = it.key();
// newSheet->setRowHeight(row, row, rowHeight(row));
for (auto it2 = it.value().begin(); it2 != it.value().end(); ++it2) {
int col = it2.key();
auto srcCell = it2.value();
auto srcCellFormat = srcCell->format();
if (srcCell->hasFormula())
{
newSheet->writeFormula(row, col, srcCell->formula(), srcCellFormat);
}
else
{
switch (srcCell->cellType())
{
case Cell::BooleanType:
newSheet->writeBool(row, col, srcCell->value().toBool(), srcCellFormat);
break;
case Cell::InlineStringType:
newSheet->writeInlineString(row, col, srcCell->value().toString(), srcCellFormat);
break;
case Cell::StringType:
case Cell::SharedStringType:
newSheet->writeString(row, col, srcCell->value().toString(), srcCellFormat);
break;
case Cell::CustomType:
if (!srcCell->value().isValid() || srcCell->value().isNull())
{
newSheet->writeBlank(row, col, srcCellFormat);
}
else
{
newSheet->write(row, col, srcCell->value(), srcCellFormat);
}
break;
default:
break;
}
}
}
}
dNewSheet->merges = d->merges;
return newSheet;
}
All data has copied correct. But cells formats, rows sizes missed.
Workbook A
Workbook B
And it looks like that it has random effect. Each time cells' format changes.
Workbook B
And I have a message from Excel that sheet lost data when workbook is opened.
2.
The second way I've tried is to save sheet's data of workbook A to xml and load it in sheet of workbook B. It is the smallest and convenient way, but it doesnt work too.
QXlsx::Document docA("docA.xlsx");
if (!docA.load())
{
qFatal("File not loaded.");
return EXIT_FAILURE;
}
QXlsx::Document docB;
docB.addSheet();
docB.currentWorksheet()->loadFromXmlData(docA.currentWorksheet()->saveToXmlData());
docB.saveAs("docB.xlsx");
return EXIT_SUCCESS;
What I'm doing wrong? Any advice?
Can you help to finish one of these ways, please?