diff --git a/addons/spreadsheet/static/src/o_spreadsheet/o_spreadsheet.js b/addons/spreadsheet/static/src/o_spreadsheet/o_spreadsheet.js
index f22e7d64b64..63b418a1203 100644
--- a/addons/spreadsheet/static/src/o_spreadsheet/o_spreadsheet.js
+++ b/addons/spreadsheet/static/src/o_spreadsheet/o_spreadsheet.js
@@ -3172,8 +3172,8 @@
LAYERS[LAYERS["Clipboard"] = 2] = "Clipboard";
LAYERS[LAYERS["Search"] = 3] = "Search";
LAYERS[LAYERS["Chart"] = 4] = "Chart";
- LAYERS[LAYERS["Selection"] = 5] = "Selection";
- LAYERS[LAYERS["Autofill"] = 6] = "Autofill";
+ LAYERS[LAYERS["Autofill"] = 5] = "Autofill";
+ LAYERS[LAYERS["Selection"] = 6] = "Selection";
LAYERS[LAYERS["Headers"] = 7] = "Headers";
})(LAYERS || (LAYERS = {}));
@@ -22108,18 +22108,6 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
z-index: ${ComponentsImportance.ScrollBar};
background-color: ${BACKGROUND_GRAY_COLOR};
- // &.vertical {
- // right: 0;
- // bottom: ${SCROLLBAR_WIDTH$1}px;
- // width: ${SCROLLBAR_WIDTH$1}px;
- // overflow-x: hidden;
- // }
- // &.horizontal {
- // bottom: 0;
- // height: ${SCROLLBAR_WIDTH$1}px;
- // right: ${SCROLLBAR_WIDTH$1}px;
- // overflow-y: hidden;
- // }
&.corner {
right: 0px;
bottom: 0px;
@@ -23124,6 +23112,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
worksheet: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
workbook: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
drawing: "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing",
+ table: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
+ revision: "http://schemas.microsoft.com/office/spreadsheetml/2014/revision",
+ revision3: "http://schemas.microsoft.com/office/spreadsheetml/2016/revision3",
+ markupCompatibility: "http://schemas.openxmlformats.org/markup-compatibility/2006",
};
const DRAWING_NS_A = "http://schemas.openxmlformats.org/drawingml/2006/main";
const DRAWING_NS_C = "http://schemas.openxmlformats.org/drawingml/2006/chart";
@@ -23139,6 +23131,17 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
pivot: "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml",
externalLink: "application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml",
};
+ const XLSX_RELATION_TYPE = {
+ document: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
+ sheet: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet",
+ sharedStrings: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings",
+ styles: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",
+ drawing: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing",
+ chart: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart",
+ theme: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme",
+ table: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table",
+ hyperlink: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
+ };
const RELATIONSHIP_NSR = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
const HEIGHT_FACTOR = 0.75; // 100px => 75 u
const WIDTH_FACTOR = 0.1317; // 100px => 13.17 u
@@ -24724,12 +24727,22 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
/**
* Convert the imported XLSX tables.
*
- * As we don't support a concept similar to the XLSX tables, we will settle for applying a style in all
- * the cells of the table and converting the table-specific formula references into standard reference.
+ * We will create a FilterTable if the imported table have filters, then apply a style in all the cells of the table
+ * and convert the table-specific formula references into standard references.
*
* Change the converted data in-place.
*/
function convertTables(convertedData, xlsxData) {
+ for (const xlsxSheet of xlsxData.sheets) {
+ for (const table of xlsxSheet.tables) {
+ const sheet = convertedData.sheets.find((sheet) => sheet.name === xlsxSheet.sheetName);
+ if (!sheet || !table.autoFilter)
+ continue;
+ if (!sheet.filterTables)
+ sheet.filterTables = [];
+ sheet.filterTables.push({ range: table.ref });
+ }
+ }
applyTableStyle(convertedData, xlsxData);
convertTableFormulaReferences(convertedData.sheets, xlsxData.sheets);
}
@@ -24748,6 +24761,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
for (let xlsxSheet of xlsxData.sheets) {
for (let table of xlsxSheet.tables) {
const sheet = convertedData.sheets.find((sheet) => sheet.name === xlsxSheet.sheetName);
+ if (!sheet)
+ continue;
const tableZone = toZone(table.ref);
// Table style
for (let i = 0; i < table.headerRowCount; i++) {
@@ -25636,6 +25651,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
}).asNum(),
cols: this.extractTableCols(tableElement),
style: this.extractTableStyleInfo(tableElement),
+ autoFilter: this.extractTableAutoFilter(tableElement),
};
})[0];
}
@@ -25660,6 +25676,32 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
};
})[0];
}
+ extractTableAutoFilter(tableElement) {
+ return this.mapOnElements({ query: "autoFilter", parent: tableElement }, (autoFilterElement) => {
+ return {
+ columns: this.extractFilterColumns(autoFilterElement),
+ zone: this.extractAttr(autoFilterElement, "ref", { required: true }).asString(),
+ };
+ })[0];
+ }
+ extractFilterColumns(autoFilterElement) {
+ return this.mapOnElements({ query: "tableColumn", parent: autoFilterElement }, (filterColumnElement) => {
+ return {
+ colId: this.extractAttr(autoFilterElement, "colId", { required: true }).asNum(),
+ hiddenButton: this.extractAttr(autoFilterElement, "hiddenButton", {
+ default: false,
+ }).asBool(),
+ filters: this.extractSimpleFilter(filterColumnElement),
+ };
+ });
+ }
+ extractSimpleFilter(filterColumnElement) {
+ return this.mapOnElements({ query: "filter", parent: filterColumnElement }, (filterColumnElement) => {
+ return {
+ val: this.extractAttr(filterColumnElement, "val", { required: true }).asString(),
+ };
+ });
+ }
}
class XlsxSheetExtractor extends XlsxBaseExtractor {
@@ -30576,7 +30618,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
}
}
}
- AutofillPlugin.layers = [6 /* LAYERS.Autofill */];
+ AutofillPlugin.layers = [5 /* LAYERS.Autofill */];
AutofillPlugin.getters = ["getAutofillTooltip"];
class AutomaticSumPlugin extends UIPlugin {
@@ -32731,6 +32773,58 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
const value = (_a = this.getters.getCell(sheetId, col, row)) === null || _a === void 0 ? void 0 : _a.formattedValue;
return (value === null || value === void 0 ? void 0 : value.toLowerCase()) || "";
}
+ exportForExcel(data) {
+ var _a;
+ for (const sheetData of data.sheets) {
+ for (const tableData of sheetData.filterTables) {
+ const tableZone = toZone(tableData.range);
+ const filters = [];
+ const headerNames = [];
+ for (const i of range(0, zoneToDimension(tableZone).width)) {
+ const filteredValues = this.getFilterValues(sheetData.id, tableZone.left + i, tableZone.top);
+ const filter = this.getters.getFilter(sheetData.id, tableZone.left + i, tableZone.top);
+ if (!filter)
+ continue;
+ const valuesInFilterZone = filter.filteredZone
+ ? positions(filter.filteredZone)
+ .map((pos) => { var _a; return (_a = this.getters.getCell(sheetData.id, pos.col, pos.row)) === null || _a === void 0 ? void 0 : _a.formattedValue; })
+ .filter(isDefined$1)
+ : [];
+ // In xlsx, filtered values = values that are displayed, not values that are hidden
+ const xlsxFilteredValues = valuesInFilterZone.filter((val) => !filteredValues.includes(val));
+ filters.push({ colId: i, filteredValues: [...new Set(xlsxFilteredValues)] });
+ // In xlsx, filter header should ALWAYS be a string and should be unique
+ const headerPosition = { col: filter.col, row: filter.zoneWithHeaders.top };
+ const headerString = (_a = this.getters.getCell(sheetData.id, headerPosition.col, headerPosition.row)) === null || _a === void 0 ? void 0 : _a.formattedValue;
+ const headerName = this.getUniqueColNameForExcel(i, headerString, headerNames);
+ headerNames.push(headerName);
+ sheetData.cells[toXC(headerPosition.col, headerPosition.row)] = {
+ ...sheetData.cells[toXC(headerPosition.col, headerPosition.row)],
+ content: headerName,
+ value: headerName,
+ isFormula: false,
+ };
+ }
+ tableData.filters = filters;
+ }
+ }
+ }
+ /**
+ * Get an unique column name for the column at colIndex. If the column name is already in the array of used column names,
+ * concatenate a number to the name until we find a new unique name (eg. "ColName" => "ColName1" => "ColName2" ...)
+ */
+ getUniqueColNameForExcel(colIndex, colName, usedColNames) {
+ if (!colName) {
+ colName = `Column${colIndex}`;
+ }
+ let currentColName = colName;
+ let i = 2;
+ while (usedColNames.includes(currentColName)) {
+ currentColName = colName + String(i);
+ i++;
+ }
+ return currentColName;
+ }
}
FilterEvaluationPlugin.getters = [
"getCellBorderWithFilterBorder",
@@ -33104,6 +33198,14 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
}
return undefined;
}
+ exportForExcel(data) {
+ for (const sheetData of data.sheets) {
+ for (const [row, rowData] of Object.entries(sheetData.rows)) {
+ const isHidden = this.isRowHidden(sheetData.id, Number(row));
+ rowData.isHidden = isHidden;
+ }
+ }
+ }
}
HeaderVisibilityUIPlugin.getters = [
"getNextVisibleCellPosition",
@@ -34330,10 +34432,11 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
ctx.fillStyle = onlyOneCell ? "#f3f7fe" : "#e9f0ff";
ctx.strokeStyle = SELECTION_BORDER_COLOR;
ctx.lineWidth = 1.5 * thinLineWidth;
- ctx.globalCompositeOperation = "multiply";
for (const zone of zones) {
const { x, y, width, height } = this.getters.getVisibleRect(zone);
+ ctx.globalCompositeOperation = "multiply";
ctx.fillRect(x, y, width, height);
+ ctx.globalCompositeOperation = "source-over";
ctx.strokeRect(x, y, width, height);
}
ctx.globalCompositeOperation = "source-over";
@@ -34360,7 +34463,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
}
}
}
- GridSelectionPlugin.layers = [5 /* LAYERS.Selection */];
+ GridSelectionPlugin.layers = [6 /* LAYERS.Selection */];
GridSelectionPlugin.getters = [
"getActiveSheet",
"getActiveSheetId",
@@ -35238,7 +35341,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
}
}
SelectionMultiUserPlugin.getters = ["getClientsToDisplay"];
- SelectionMultiUserPlugin.layers = [5 /* LAYERS.Selection */];
+ SelectionMultiUserPlugin.layers = [6 /* LAYERS.Selection */];
class InternalViewport {
constructor(getters, sheetId, boundaries, sizeInGrid, options, offsets) {
@@ -37487,7 +37590,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
.o-dropdown-content {
position: absolute;
- top: calc(100% + 5px);
+ top: 100%;
left: 0;
z-index: ${ComponentsImportance.Dropdown};
box-shadow: 1px 2px 5px 2px rgba(51, 51, 51, 0.15);
@@ -37883,8 +37986,6 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
return `grid-template-rows: ${TOPBAR_HEIGHT}px auto ${BOTTOMBAR_HEIGHT + 1}px`;
}
setup() {
- var _a, _b;
- (_b = (_a = this.props).exposeSpreadsheet) === null || _b === void 0 ? void 0 : _b.call(_a, this);
this.sidePanel = owl.useState({ isOpen: false, panelProps: {} });
this.composer = owl.useState({
topBarFocus: "inactive",
@@ -38036,7 +38137,6 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
Spreadsheet._t = t;
Spreadsheet.props = {
model: Object,
- exposeSpreadsheet: { type: Function, optional: true },
};
class LocalTransportService {
@@ -40658,14 +40758,14 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
return { attrs, node };
}
}
- function addContent(content, sharedStrings) {
+ function addContent(content, sharedStrings, forceString = false) {
let value = content;
const attrs = [];
- if (["TRUE", "FALSE"].includes(value.trim())) {
+ if (!forceString && ["TRUE", "FALSE"].includes(value.trim())) {
value = value === "TRUE" ? "1" : "0";
attrs.push(["t", "b"]);
}
- else if (!isNumber(value)) {
+ else if (forceString || !isNumber(value)) {
const { id } = pushElement(content, sharedStrings);
value = id.toString();
attrs.push(["t", "s"]);
@@ -41262,6 +41362,80 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
`;
}
+ const TABLE_DEFAULT_STYLE = escapeXml /*xml*/ `