docx
Advanced tools
Comparing version 5.2.0 to 5.2.1
@@ -19,3 +19,7 @@ import { HeightRule } from "../../../file/table/table-row/table-row-height"; | ||
readonly Children: TableCell[]; | ||
readonly cells: TableCell[]; | ||
addCellToIndex(cell: TableCell, index: number): void; | ||
addCellToColumnIndex(cell: TableCell, columnIndex: number): void; | ||
rootIndexToColumnIndex(rootIndex: number): number; | ||
columnIndexToRootIndex(columnIndex: number, allowEndNewCell?: boolean): number; | ||
} |
{ | ||
"name": "docx", | ||
"version": "5.2.0", | ||
"version": "5.2.1", | ||
"description": "Easily generate .docx files with JS/TS with a nice declarative API. Works for Node and on the Browser.", | ||
@@ -5,0 +5,0 @@ "main": "build/index.js", |
@@ -185,2 +185,94 @@ import { expect } from "chai"; | ||
}); | ||
describe("#rootIndexToColumnIndex", () => { | ||
it("should get the correct virtual column index by root index", () => { | ||
const tableRow = new TableRow({ | ||
children: [ | ||
new TableCell({ | ||
children: [new Paragraph("test")], | ||
columnSpan: 3, | ||
}), | ||
new TableCell({ | ||
children: [new Paragraph("test")], | ||
}), | ||
new TableCell({ | ||
children: [new Paragraph("test")], | ||
}), | ||
new TableCell({ | ||
children: [new Paragraph("test")], | ||
columnSpan: 3, | ||
}), | ||
], | ||
}); | ||
expect(tableRow.rootIndexToColumnIndex(1)).to.equal(0); | ||
expect(tableRow.rootIndexToColumnIndex(2)).to.equal(3); | ||
expect(tableRow.rootIndexToColumnIndex(3)).to.equal(4); | ||
expect(tableRow.rootIndexToColumnIndex(4)).to.equal(5); | ||
expect(() => tableRow.rootIndexToColumnIndex(0)).to.throw(`cell 'rootIndex' should between 1 to 4`); | ||
expect(() => tableRow.rootIndexToColumnIndex(5)).to.throw(`cell 'rootIndex' should between 1 to 4`); | ||
}); | ||
}); | ||
describe("#columnIndexToRootIndex", () => { | ||
it("should get the correct root index by virtual column index", () => { | ||
const tableRow = new TableRow({ | ||
children: [ | ||
new TableCell({ | ||
children: [new Paragraph("test")], | ||
columnSpan: 3, | ||
}), | ||
new TableCell({ | ||
children: [new Paragraph("test")], | ||
}), | ||
new TableCell({ | ||
children: [new Paragraph("test")], | ||
}), | ||
new TableCell({ | ||
children: [new Paragraph("test")], | ||
columnSpan: 3, | ||
}), | ||
], | ||
}); | ||
expect(tableRow.columnIndexToRootIndex(0)).to.equal(1); | ||
expect(tableRow.columnIndexToRootIndex(1)).to.equal(1); | ||
expect(tableRow.columnIndexToRootIndex(2)).to.equal(1); | ||
expect(tableRow.columnIndexToRootIndex(3)).to.equal(2); | ||
expect(tableRow.columnIndexToRootIndex(4)).to.equal(3); | ||
expect(tableRow.columnIndexToRootIndex(5)).to.equal(4); | ||
expect(tableRow.columnIndexToRootIndex(6)).to.equal(4); | ||
expect(tableRow.columnIndexToRootIndex(7)).to.equal(4); | ||
expect(() => tableRow.columnIndexToRootIndex(-1)).to.throw(`cell 'columnIndex' should not less than zero`); | ||
expect(() => tableRow.columnIndexToRootIndex(8)).to.throw(`cell 'columnIndex' should not great than 7`); | ||
}); | ||
it("should allow end new cell index", () => { | ||
const tableRow = new TableRow({ | ||
children: [ | ||
new TableCell({ | ||
children: [new Paragraph("test")], | ||
columnSpan: 3, | ||
}), | ||
new TableCell({ | ||
children: [new Paragraph("test")], | ||
}), | ||
new TableCell({ | ||
children: [new Paragraph("test")], | ||
}), | ||
new TableCell({ | ||
children: [new Paragraph("test")], | ||
columnSpan: 3, | ||
}), | ||
], | ||
}); | ||
expect(tableRow.columnIndexToRootIndex(8, true)).to.equal(5); | ||
expect(() => tableRow.columnIndexToRootIndex(9, true)).to.throw(`cell 'columnIndex' should not great than 8`); | ||
}); | ||
}); | ||
}); |
@@ -49,2 +49,6 @@ import { HeightRule } from "file/table/table-row/table-row-height"; | ||
public get cells(): TableCell[] { | ||
return this.root.filter((xmlComponent) => xmlComponent instanceof TableCell); | ||
} | ||
public addCellToIndex(cell: TableCell, index: number): void { | ||
@@ -54,2 +58,42 @@ // Offset because properties is also in root. | ||
} | ||
public addCellToColumnIndex(cell: TableCell, columnIndex: number): void { | ||
const rootIndex = this.columnIndexToRootIndex(columnIndex, true); | ||
this.addCellToIndex(cell, rootIndex - 1); | ||
} | ||
public rootIndexToColumnIndex(rootIndex: number): number { | ||
// convert the root index to the virtual column index | ||
if (rootIndex < 1 || rootIndex >= this.root.length) { | ||
throw new Error(`cell 'rootIndex' should between 1 to ${this.root.length - 1}`); | ||
} | ||
let colIdx = 0; | ||
// Offset because properties is also in root. | ||
for (let rootIdx = 1; rootIdx < rootIndex; rootIdx++) { | ||
const cell = this.root[rootIdx] as TableCell; | ||
colIdx += cell.options.columnSpan || 1; | ||
} | ||
return colIdx; | ||
} | ||
public columnIndexToRootIndex(columnIndex: number, allowEndNewCell: boolean = false): number { | ||
// convert the virtual column index to the root index | ||
// `allowEndNewCell` for get index to inert new cell | ||
if (columnIndex < 0) { | ||
throw new Error(`cell 'columnIndex' should not less than zero`); | ||
} | ||
let colIdx = 0; | ||
// Offset because properties is also in root. | ||
let rootIdx = 1; | ||
const endRootIndex = allowEndNewCell ? this.root.length : this.root.length - 1; | ||
while (colIdx <= columnIndex) { | ||
if (rootIdx > endRootIndex) { | ||
throw new Error(`cell 'columnIndex' should not great than ${colIdx - 1}`); | ||
} | ||
const cell = this.root[rootIdx] as TableCell; | ||
rootIdx += 1; | ||
colIdx += (cell && cell.options.columnSpan) || 1; | ||
} | ||
return rootIdx - 1; | ||
} | ||
} |
@@ -191,2 +191,68 @@ /* tslint:disable:no-unused-expression */ | ||
it("creates a table with the correct columnSpan and rowSpan", () => { | ||
const table = new Table({ | ||
rows: [ | ||
new TableRow({ | ||
children: [ | ||
new TableCell({ | ||
children: [new Paragraph("hello")], | ||
columnSpan: 2, | ||
}), | ||
], | ||
}), | ||
new TableRow({ | ||
children: [ | ||
new TableCell({ | ||
children: [new Paragraph("hello")], | ||
rowSpan: 2, | ||
}), | ||
new TableCell({ | ||
children: [new Paragraph("hello")], | ||
}), | ||
], | ||
}), | ||
new TableRow({ | ||
children: [ | ||
new TableCell({ | ||
children: [new Paragraph("hello")], | ||
}), | ||
], | ||
}), | ||
], | ||
}); | ||
const tree = new Formatter().format(table); | ||
const cellP = { "w:p": [{ "w:r": [{ "w:t": [{ _attr: { "xml:space": "preserve" } }, "hello"] }] }] }; | ||
expect(tree).to.deep.equal({ | ||
"w:tbl": [ | ||
{ "w:tblPr": [DEFAULT_TABLE_PROPERTIES, BORDERS, WIDTHS] }, | ||
{ | ||
"w:tblGrid": [{ "w:gridCol": { _attr: { "w:w": 100 } } }, { "w:gridCol": { _attr: { "w:w": 100 } } }], | ||
}, | ||
{ | ||
"w:tr": [ | ||
{ | ||
"w:tc": [{ "w:tcPr": [{ "w:gridSpan": { _attr: { "w:val": 2 } } }] }, cellP], | ||
}, | ||
], | ||
}, | ||
{ | ||
"w:tr": [ | ||
{ | ||
"w:tc": [{ "w:tcPr": [{ "w:vMerge": { _attr: { "w:val": "restart" } } }] }, cellP], | ||
}, | ||
{ "w:tc": [cellP] }, | ||
], | ||
}, | ||
{ | ||
"w:tr": [ | ||
{ | ||
"w:tc": [{ "w:tcPr": [{ "w:vMerge": { _attr: { "w:val": "continue" } } }] }, { "w:p": {} }], | ||
}, | ||
{ "w:tc": [cellP] }, | ||
], | ||
}, | ||
], | ||
}); | ||
}); | ||
it("sets the table to fixed width layout", () => { | ||
@@ -193,0 +259,0 @@ const table = new Table({ |
@@ -81,18 +81,19 @@ // http://officeopenxml.com/WPtableGrid.php | ||
for (const row of rows) { | ||
row.Children.forEach((cell, cellIndex) => { | ||
const column = rows.map((r) => r.Children[cellIndex]); | ||
rows.forEach((row, rowIndex) => { | ||
row.cells.forEach((cell, cellIndex) => { | ||
// 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 | ||
if (cell.options.rowSpan && cell.options.rowSpan > 1) { | ||
const thisCellsColumnIndex = column.indexOf(cell); | ||
const endColumnIndex = thisCellsColumnIndex + (cell.options.rowSpan - 1); | ||
for (let i = thisCellsColumnIndex + 1; i <= endColumnIndex; i++) { | ||
rows[i].addCellToIndex( | ||
const columnIndex = row.rootIndexToColumnIndex(cellIndex + 1); | ||
const startRowIndex = rowIndex + 1; | ||
const endRowIndex = rowIndex + (cell.options.rowSpan - 1); | ||
for (let i = startRowIndex; i <= endRowIndex; i++) { | ||
rows[i].addCellToColumnIndex( | ||
new TableCell({ | ||
columnSpan: cell.options.columnSpan, | ||
borders: cell.options.borders, | ||
children: [], | ||
verticalMerge: VerticalMergeType.CONTINUE, | ||
}), | ||
i, | ||
columnIndex, | ||
); | ||
@@ -102,3 +103,3 @@ } | ||
}); | ||
} | ||
}); | ||
@@ -105,0 +106,0 @@ if (float) { |
Sorry, the diff of this file is too big to display
1772054
47820