Skip to content

Commit daee588

Browse files
committed
chore(table): WIP improve table cell cloning / expansion
1 parent ac9ac33 commit daee588

File tree

5 files changed

+77
-26
lines changed

5 files changed

+77
-26
lines changed

src/helper/modify-table-helper.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export default class ModifyTableHelper {
3333
});
3434
}
3535

36-
modTable.modify();
36+
modTable.modify(params);
3737

3838
if (params?.setHeight) {
3939
modTable.setSize('cy', params.setHeight);

src/helper/modify-text-helper.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Color, TextStyle } from '../types/modify-types';
22
import ModifyColorHelper from './modify-color-helper';
33
import ModifyXmlHelper from './modify-xml-helper';
44
import { XmlElement } from '../types/xml-types';
5+
import { vd } from './general-helper';
56

67
export default class ModifyTextHelper {
78
/**

src/helper/modify-xml-helper.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { XmlDocument, XmlElement } from '../types/xml-types';
77

88
export default class ModifyXmlHelper {
99
root: XmlDocument | XmlElement;
10-
templates: { [key: string]: Node };
10+
templates: { [key: string]: XmlElement };
1111

1212
constructor(root: XmlDocument | XmlElement) {
1313
this.root = root;
@@ -84,21 +84,30 @@ export default class ModifyXmlHelper {
8484
if (collection[collection.length - 1] === undefined) {
8585
this.createElement(parent, tag);
8686
} else {
87-
const previousSibling = collection[collection.length - 1];
87+
const lastSibling = collection[collection.length - 1];
8888

89-
const newChild =
90-
this.templates[tag] && !modifier.fromPrevious
91-
? this.templates[tag].cloneNode(true)
92-
: previousSibling.cloneNode(true);
89+
let sourceSibling = lastSibling;
90+
if (modifier.fromIndex && collection.item(modifier.fromIndex)) {
91+
sourceSibling = collection.item(modifier.fromIndex);
92+
} else if (modifier.fromPrevious && collection.item(index - 1)) {
93+
sourceSibling = collection.item(index - 1);
94+
}
95+
96+
if ((!sourceSibling || modifier.forceCreate) && this.templates[tag]) {
97+
sourceSibling = this.templates[tag];
98+
}
99+
100+
const newChild = sourceSibling.cloneNode(true);
93101

94-
XmlHelper.insertAfter(newChild, previousSibling);
102+
XmlHelper.insertAfter(newChild, lastSibling);
95103
}
96104
}
97105

98106
const element = parent.getElementsByTagName(tag)[index];
99107

100108
if (element) {
101-
this.templates[tag] = this.templates[tag] || element.cloneNode(true);
109+
this.templates[tag] =
110+
this.templates[tag] || (element.cloneNode(true) as XmlElement);
102111
return element;
103112
}
104113

src/modify/modify-table.ts

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import { XmlHelper } from '../helper/xml-helper';
22
import ModifyXmlHelper from '../helper/modify-xml-helper';
3-
import { TableData, TableRow, TableRowStyle } from '../types/table-types';
3+
import {
4+
ModifyTableParams,
5+
TableData,
6+
TableRow,
7+
TableRowStyle,
8+
} from '../types/table-types';
49
import { Border, Modification, ModificationTags } from '../types/modify-types';
510
import ModifyTextHelper from '../helper/modify-text-helper';
611
import { ModifyColorHelper } from '../index';
@@ -11,25 +16,38 @@ export class ModifyTable {
1116
data: TableData;
1217
table: ModifyXmlHelper;
1318
xml: XmlDocument | XmlElement;
19+
maxCols: number = 0;
20+
params: ModifyTableParams;
1421

1522
constructor(table: XmlDocument | XmlElement, data?: TableData) {
1623
this.data = data;
1724

1825
this.table = new ModifyXmlHelper(table);
1926
this.xml = table;
27+
28+
this.data.body.forEach((row) => {
29+
this.maxCols =
30+
row.values.length > this.maxCols ? row.values.length : this.maxCols;
31+
});
2032
}
2133

22-
modify(): ModifyTable {
34+
modify(params?: ModifyTableParams): ModifyTable {
35+
this.params = params;
36+
2337
this.setRows();
2438
this.setGridCols();
2539

26-
// this.sliceRows();
27-
// this.sliceCols();
40+
this.sliceRows();
41+
this.sliceCols();
2842

2943
return this;
3044
}
3145

3246
setRows() {
47+
const alreadyExpanded = this.params?.expand?.find(
48+
(expand) => expand.mode === 'column',
49+
);
50+
3351
this.data.body.forEach((row: TableRow, r: number) => {
3452
row.values.forEach((cell: number | string, c: number) => {
3553
const rowStyles = row.styles && row.styles[c] ? row.styles[c] : {};
@@ -42,12 +60,29 @@ export class ModifyTable {
4260
modify: ModifyXmlHelper.attribute('val', r),
4361
},
4462
});
63+
64+
if (!alreadyExpanded) {
65+
this.expandOtherMergedCellsInColumn(c, r);
66+
}
4567
});
4668
});
4769
}
4870

71+
expandOtherMergedCellsInColumn(c: number, r: number) {
72+
const rows = this.xml.getElementsByTagName('a:tr');
73+
for (let rs = 0; rs < rows.length; rs++) {
74+
// Skip current row
75+
if (r !== rs) {
76+
const row = rows.item(r);
77+
const columns = row.getElementsByTagName('a:tc');
78+
const sourceCell = columns.item(c);
79+
this.expandGridSpan(sourceCell);
80+
}
81+
}
82+
}
83+
4984
setGridCols() {
50-
this.data.body[0]?.values.forEach((cell, c: number) => {
85+
for (let c = 0; c <= this.maxCols; c++) {
5186
this.table.modify({
5287
'a:gridCol': {
5388
index: c,
@@ -57,7 +92,7 @@ export class ModifyTable {
5792
modify: ModifyXmlHelper.attribute('val', c),
5893
},
5994
});
60-
});
95+
}
6196
}
6297

6398
sliceRows() {
@@ -68,7 +103,7 @@ export class ModifyTable {
68103

69104
sliceCols() {
70105
this.table.modify({
71-
'a:tblGrid': this.slice('a:gridCol', this.data.body[0]?.values.length),
106+
'a:tblGrid': this.slice('a:gridCol', this.maxCols),
72107
});
73108
}
74109

@@ -86,6 +121,7 @@ export class ModifyTable {
86121
'a:tc': {
87122
index: index,
88123
children: children,
124+
fromPrevious: true,
89125
},
90126
};
91127
};
@@ -270,25 +306,20 @@ export class ModifyTable {
270306
sourceCell: XmlElement,
271307
colId: number,
272308
): XmlElement {
273-
const gridSpan = sourceCell.getAttribute('gridSpan');
274-
const hMerge = sourceCell.getAttribute('hMerge');
275-
276-
if (gridSpan) {
277-
const incrementGridSpan = Number(gridSpan) + 1;
278-
sourceCell.setAttribute('gridSpan', String(incrementGridSpan));
309+
const hasGridSpan = this.expandGridSpan(sourceCell);
310+
if (hasGridSpan) {
279311
return columns.item(colId + 1).cloneNode(true) as XmlElement;
280312
}
281313

314+
const hMerge = sourceCell.getAttribute('hMerge');
282315
if (hMerge) {
283316
for (let findCol = colId - 1; colId >= 0; colId--) {
284317
const previousSibling = columns.item(findCol);
285318
if (!previousSibling) {
286319
break;
287320
}
288-
const hasSpan = previousSibling.getAttribute('gridSpan');
289-
if (hasSpan) {
290-
const incrementGridSpan = Number(hasSpan) + 1;
291-
previousSibling.setAttribute('gridSpan', String(incrementGridSpan));
321+
const siblingHasSpan = this.expandGridSpan(previousSibling);
322+
if (siblingHasSpan) {
292323
break;
293324
}
294325
}
@@ -297,6 +328,15 @@ export class ModifyTable {
297328
return sourceCell.cloneNode(true) as XmlElement;
298329
}
299330

331+
expandGridSpan(sourceCell: XmlElement) {
332+
const gridSpan = sourceCell.getAttribute('gridSpan');
333+
if (gridSpan) {
334+
const incrementGridSpan = Number(gridSpan) + 1;
335+
sourceCell.setAttribute('gridSpan', String(incrementGridSpan));
336+
return true;
337+
}
338+
}
339+
300340
expandGrid = (count: number, colId: number, gridSpan: number) => {
301341
const tblGrid = this.xml.getElementsByTagName('a:tblGrid').item(0);
302342
for (let cs = 1; cs <= count; cs++) {

src/types/modify-types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export type Modification = {
2121
create?: any;
2222
isRequired?: boolean;
2323
fromPrevious?: boolean;
24+
fromIndex?: number;
2425
forceCreate?: boolean;
2526
};
2627
/**

0 commit comments

Comments
 (0)