Merge pull request #559 from wangfengming/master
:fix: `rowSpan` can't work when column index out of range
This commit is contained in:
@ -287,6 +287,7 @@ const table7 = new Table({
|
|||||||
}),
|
}),
|
||||||
new TableCell({
|
new TableCell({
|
||||||
children: [new Paragraph("0,3")],
|
children: [new Paragraph("0,3")],
|
||||||
|
rowSpan: 3,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
@ -296,9 +297,6 @@ const table7 = new Table({
|
|||||||
children: [new Paragraph("1,0")],
|
children: [new Paragraph("1,0")],
|
||||||
columnSpan: 2,
|
columnSpan: 2,
|
||||||
}),
|
}),
|
||||||
new TableCell({
|
|
||||||
children: [new Paragraph("1,3")],
|
|
||||||
}),
|
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
new TableRow({
|
new TableRow({
|
||||||
@ -311,9 +309,6 @@ const table7 = new Table({
|
|||||||
children: [new Paragraph("2,2")],
|
children: [new Paragraph("2,2")],
|
||||||
rowSpan: 2,
|
rowSpan: 2,
|
||||||
}),
|
}),
|
||||||
new TableCell({
|
|
||||||
children: [new Paragraph("2,3")],
|
|
||||||
}),
|
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
new TableRow({
|
new TableRow({
|
||||||
@ -336,6 +331,41 @@ const table7 = new Table({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const table8 = new Table({
|
||||||
|
rows: [
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({ children: [new Paragraph("1,1")] }),
|
||||||
|
new TableCell({ children: [new Paragraph("1,2")] }),
|
||||||
|
new TableCell({ children: [new Paragraph("1,3")] }),
|
||||||
|
new TableCell({ children: [new Paragraph("1,4")], rowSpan: 4, borders }),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({ children: [new Paragraph("2,1")] }),
|
||||||
|
new TableCell({ children: [new Paragraph("2,2")] }),
|
||||||
|
new TableCell({ children: [new Paragraph("2,3")], rowSpan: 3 }),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({ children: [new Paragraph("3,1")] }),
|
||||||
|
new TableCell({ children: [new Paragraph("3,2")], rowSpan: 2 }),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({ children: [new Paragraph("4,1")] }),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
width: {
|
||||||
|
size: 100,
|
||||||
|
type: WidthType.PERCENTAGE,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
doc.addSection({
|
doc.addSection({
|
||||||
children: [
|
children: [
|
||||||
table,
|
table,
|
||||||
@ -357,6 +387,8 @@ doc.addSection({
|
|||||||
table6,
|
table6,
|
||||||
new Paragraph("Merging columns 4"),
|
new Paragraph("Merging columns 4"),
|
||||||
table7,
|
table7,
|
||||||
|
new Paragraph("Merging columns 5"),
|
||||||
|
table8,
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -70,6 +70,9 @@ export class TableCell extends XmlComponent {
|
|||||||
|
|
||||||
if (options.verticalMerge) {
|
if (options.verticalMerge) {
|
||||||
this.properties.addVerticalMerge(options.verticalMerge);
|
this.properties.addVerticalMerge(options.verticalMerge);
|
||||||
|
} else if (options.rowSpan && options.rowSpan > 1) {
|
||||||
|
// if cell already have a `verticalMerge`, don't handle `rowSpan`
|
||||||
|
this.properties.addVerticalMerge(VerticalMergeType.RESTART);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.margins) {
|
if (options.margins) {
|
||||||
@ -84,10 +87,6 @@ export class TableCell extends XmlComponent {
|
|||||||
this.properties.addGridSpan(options.columnSpan);
|
this.properties.addGridSpan(options.columnSpan);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.rowSpan && options.rowSpan > 1) {
|
|
||||||
this.properties.addVerticalMerge(VerticalMergeType.RESTART);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.width) {
|
if (options.width) {
|
||||||
this.properties.setWidth(options.width.size, options.width.type);
|
this.properties.setWidth(options.width.size, options.width.type);
|
||||||
}
|
}
|
||||||
|
@ -271,7 +271,8 @@ describe("TableRow", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(tableRow.columnIndexToRootIndex(8, true)).to.equal(5);
|
expect(tableRow.columnIndexToRootIndex(8, true)).to.equal(5);
|
||||||
expect(() => tableRow.columnIndexToRootIndex(9, true)).to.throw(`cell 'columnIndex' should not great than 8`);
|
// for column 10, just place the new cell at the end of row
|
||||||
|
expect(tableRow.columnIndexToRootIndex(10, true)).to.equal(5);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -83,10 +83,14 @@ export class TableRow extends XmlComponent {
|
|||||||
let colIdx = 0;
|
let colIdx = 0;
|
||||||
// Offset because properties is also in root.
|
// Offset because properties is also in root.
|
||||||
let rootIdx = 1;
|
let rootIdx = 1;
|
||||||
const endRootIndex = allowEndNewCell ? this.root.length : this.root.length - 1;
|
|
||||||
while (colIdx <= columnIndex) {
|
while (colIdx <= columnIndex) {
|
||||||
if (rootIdx > endRootIndex) {
|
if (rootIdx >= this.root.length) {
|
||||||
throw new Error(`cell 'columnIndex' should not great than ${colIdx - 1}`);
|
if (allowEndNewCell) {
|
||||||
|
// for inserting verticalMerge CONTINUE cell at end of row
|
||||||
|
return this.root.length;
|
||||||
|
} else {
|
||||||
|
throw new Error(`cell 'columnIndex' should not great than ${colIdx - 1}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const cell = this.root[rootIdx] as TableCell;
|
const cell = this.root[rootIdx] as TableCell;
|
||||||
rootIdx += 1;
|
rootIdx += 1;
|
||||||
|
@ -79,25 +79,26 @@ export class Table extends XmlComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rows.forEach((row, rowIndex) => {
|
rows.forEach((row, rowIndex) => {
|
||||||
row.cells.forEach((cell, cellIndex) => {
|
if (rowIndex === rows.length - 1) {
|
||||||
|
// don't process the end row
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let columnIndex = 0;
|
||||||
|
row.cells.forEach((cell) => {
|
||||||
// Row Span has to be added in this method and not the constructor because it needs to know information about the column which happens after Table Cell construction
|
// Row Span has to be added in this method and not the constructor because it needs to know information about the column which happens after Table Cell construction
|
||||||
// Row Span of 1 will crash word as it will add RESTART and not a corresponding CONTINUE
|
// Row Span of 1 will crash word as it will add RESTART and not a corresponding CONTINUE
|
||||||
if (cell.options.rowSpan && cell.options.rowSpan > 1) {
|
if (cell.options.rowSpan && cell.options.rowSpan > 1) {
|
||||||
const columnIndex = row.rootIndexToColumnIndex(cellIndex + 1);
|
const continueCell = new TableCell({
|
||||||
const startRowIndex = rowIndex + 1;
|
// the inserted CONTINUE cell has rowSpan, and will be handled when process the next row
|
||||||
const endRowIndex = rowIndex + (cell.options.rowSpan - 1);
|
rowSpan: cell.options.rowSpan - 1,
|
||||||
for (let i = startRowIndex; i <= endRowIndex; i++) {
|
columnSpan: cell.options.columnSpan,
|
||||||
rows[i].addCellToColumnIndex(
|
borders: cell.options.borders,
|
||||||
new TableCell({
|
children: [],
|
||||||
columnSpan: cell.options.columnSpan,
|
verticalMerge: VerticalMergeType.CONTINUE,
|
||||||
borders: cell.options.borders,
|
});
|
||||||
children: [],
|
rows[rowIndex + 1].addCellToColumnIndex(continueCell, columnIndex);
|
||||||
verticalMerge: VerticalMergeType.CONTINUE,
|
|
||||||
}),
|
|
||||||
columnIndex,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
columnIndex += cell.options.columnSpan || 1;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user