Skip to content

Commit 1ee2018

Browse files
committed
[FIX] figures: fix xlsx export
closes #7025 Task: 4755779 X-original-commit: 1e3d0ff Signed-off-by: Pierre Rousseau (pro) <pro@odoo.com> Signed-off-by: Florian Damhaut (flda) <flda@odoo.com>
1 parent 497c818 commit 1ee2018

File tree

6 files changed

+67
-11
lines changed

6 files changed

+67
-11
lines changed

src/xlsx/conversion/figure_conversion.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { DEFAULT_WINDOW_SIZE } from "../../constants";
1+
import { DEFAULT_WINDOW_SIZE, FIGURE_BORDER_WIDTH } from "../../constants";
22
import {
33
getFullReference,
44
isDefined,
@@ -163,8 +163,8 @@ function convertExcelTrendline(
163163

164164
function convertAnchor(XLSXanchor: XLSXFigureAnchor): AnchorOffset {
165165
const offset = {
166-
x: convertEMUToDotValue(XLSXanchor.colOffset),
167-
y: convertEMUToDotValue(XLSXanchor.rowOffset),
166+
x: convertEMUToDotValue(XLSXanchor.colOffset) - FIGURE_BORDER_WIDTH,
167+
y: convertEMUToDotValue(XLSXanchor.rowOffset) - FIGURE_BORDER_WIDTH,
168168
};
169169
return { col: XLSXanchor.col, row: XLSXanchor.row, offset };
170170
}

src/xlsx/conversion/sheet_conversion.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,13 @@ function getSheetDims(sheet: XLSXWorksheet): number[] {
237237
dims[1] = Math.max(dims[1], row.index);
238238
}
239239

240-
dims[0] = Math.max(dims[0], EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS);
241-
dims[1] = Math.max(dims[1], EXCEL_IMPORT_DEFAULT_NUMBER_OF_ROWS);
240+
for (const fig of sheet.figures) {
241+
dims[0] = Math.max(dims[0], fig.anchors[fig.anchors.length - 1]?.col ?? 0);
242+
dims[1] = Math.max(dims[1], fig.anchors[fig.anchors.length - 1]?.row ?? 0);
243+
}
244+
245+
dims[0] = Math.max(dims[0] + 5, EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS);
246+
dims[1] = Math.max(dims[1] + 5, EXCEL_IMPORT_DEFAULT_NUMBER_OF_ROWS);
242247

243248
return dims;
244249
}

src/xlsx/functions/drawings.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ function figureCoordinates(
108108
for (const [headerIndex, header] of headers.slice(anchor).entries()) {
109109
if (currentPosition <= offset && offset < currentPosition + header.size!) {
110110
return {
111-
index: headerIndex,
111+
index: anchor + headerIndex,
112112
offset: convertDotValueToEMU(offset - currentPosition + FIGURE_BORDER_WIDTH),
113113
};
114114
} else if (headerIndex < headers.length - 1) {

src/xlsx/helpers/content_helpers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ export function getColPosition(colIndex: number, sheetData: XLSXWorksheet): numb
335335
export function getRowPosition(rowIndex: number, sheetData: XLSXWorksheet) {
336336
let position = 0;
337337
for (let i = 0; i < rowIndex; i++) {
338-
const rowAtIndex = sheetData.rows[i];
338+
const rowAtIndex = sheetData.rows.find((row) => row.index - 1 === i);
339339
if (rowAtIndex?.height) {
340340
position += rowAtIndex.height;
341341
} else if (sheetData.sheetFormat?.defaultRowHeight) {

src/xlsx/xlsx_reader.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import { getXLSXFilesOfType } from "./helpers/xlsx_helper";
2626
import { XLSXImportWarningManager } from "./helpers/xlsx_parser_error_manager";
2727
import { escapeTagNamespaces, parseXML } from "./helpers/xml_helpers";
2828

29-
const EXCEL_IMPORT_VERSION = "18.4.1";
29+
const EXCEL_IMPORT_VERSION = "18.4.2";
3030

3131
export class XlsxReader {
3232
warningManager: XLSXImportWarningManager;

tests/xlsx/xlsx_import_export.test.ts

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { Model } from "../../src";
2-
import { FIGURE_BORDER_WIDTH } from "../../src/constants";
32
import { buildSheetLink, toZone } from "../../src/helpers";
43
import {
54
Align,
@@ -280,8 +279,8 @@ describe("Export data to xlsx then import it", () => {
280279
expect(importedFigure.height).toEqual(figure.height);
281280
expect(importedFigure.width).toBeBetween(figure.width - 1, figure.width + 1);
282281
expect(importedFigure.offset).toEqual({
283-
x: figure.offset.x + FIGURE_BORDER_WIDTH,
284-
y: figure.offset.y + FIGURE_BORDER_WIDTH,
282+
x: figure.offset.x,
283+
y: figure.offset.y,
285284
});
286285
});
287286

@@ -401,4 +400,56 @@ describe("Export data to xlsx then import it", () => {
401400
expect(newFigure.width).toBe(300);
402401
expect(newFigure.height).toBe(400);
403402
});
403+
404+
test.each([
405+
{ offset: { x: 0, y: 0 }, col: 5, row: 5 },
406+
{ offset: { x: 10, y: 10 }, col: 10, row: 10 },
407+
{ offset: { x: 0, y: 10 }, col: 5, row: 0 },
408+
{ offset: { x: 10, y: 0 }, col: 0, row: 5 },
409+
])("Figure Position", (position) => {
410+
createImage(model, {
411+
figureId: "1",
412+
size: {
413+
width: 300,
414+
height: 400,
415+
},
416+
...position,
417+
});
418+
419+
const figure = model.getters.getFigures(sheetId)[0];
420+
const importedModel = exportToXlsxThenImport(model);
421+
const newFigure = importedModel.getters.getFigures(sheetId)[0];
422+
expect(newFigure).toMatchObject(figure);
423+
});
424+
425+
test.each([
426+
{ offset: { x: 0, y: 0 }, col: 5, row: 5 },
427+
{ offset: { x: 10, y: 10 }, col: 10, row: 10 },
428+
{ offset: { x: 0, y: 10 }, col: 5, row: 0 },
429+
{ offset: { x: 10, y: 0 }, col: 0, row: 5 },
430+
])("Figure Position with custom row length", (position) => {
431+
createChart(
432+
model,
433+
{
434+
dataSets: [{ dataRange: "Sheet1!B1:B4" }, { dataRange: "Sheet1!C1:C4" }],
435+
labelRange: "Sheet1!A2:A4",
436+
type: "line",
437+
},
438+
"1",
439+
sheetId,
440+
{
441+
figureId: "1",
442+
size: {
443+
width: 300,
444+
height: 400,
445+
},
446+
...position,
447+
}
448+
);
449+
resizeRows(model, [50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60], 100);
450+
const figure = model.getters.getFigures(sheetId)[0];
451+
const importedModel = exportToXlsxThenImport(model);
452+
const newFigure = importedModel.getters.getFigures(sheetId)[0];
453+
expect(newFigure.height).toBe(figure.height);
454+
});
404455
});

0 commit comments

Comments
 (0)