2018-09-12 21:01:52 +01:00
|
|
|
// http://officeopenxml.com/WPtableGrid.php
|
2018-10-23 23:44:50 +01:00
|
|
|
import { XmlComponent } from "file/xml-components";
|
|
|
|
|
2017-09-19 15:49:27 +01:00
|
|
|
import { TableGrid } from "./grid";
|
2018-10-23 23:44:50 +01:00
|
|
|
import { TableCell, WidthType } from "./table-cell";
|
2019-03-04 22:50:04 +00:00
|
|
|
import { TableColumn } from "./table-column";
|
2018-10-23 23:44:50 +01:00
|
|
|
import { ITableFloatOptions, TableProperties } from "./table-properties";
|
|
|
|
import { TableRow } from "./table-row";
|
2019-03-08 01:09:21 +00:00
|
|
|
/*
|
|
|
|
0-width columns don't get rendered correctly, so we need
|
|
|
|
to give them some value. A reasonable default would be
|
|
|
|
~6in / numCols, but if we do that it becomes very hard
|
|
|
|
to resize the table using setWidth, unless the layout
|
|
|
|
algorithm is set to 'fixed'. Instead, the approach here
|
|
|
|
means even in 'auto' layout, setting a width on the
|
|
|
|
table will make it look reasonable, as the layout
|
|
|
|
algorithm will expand columns to fit its content
|
|
|
|
*/
|
2019-03-13 02:29:11 +00:00
|
|
|
export interface ITableOptions {
|
|
|
|
readonly rows: number;
|
|
|
|
readonly columns: number;
|
|
|
|
readonly width?: number;
|
|
|
|
readonly widthUnitType?: WidthType;
|
|
|
|
readonly columnWidths?: number[];
|
2019-04-18 13:55:18 +10:00
|
|
|
readonly margins?: {
|
|
|
|
readonly marginUnitType?: WidthType;
|
2019-03-13 02:29:11 +00:00
|
|
|
readonly top?: number;
|
|
|
|
readonly bottom?: number;
|
|
|
|
readonly right?: number;
|
|
|
|
readonly left?: number;
|
|
|
|
};
|
|
|
|
readonly float?: ITableFloatOptions;
|
|
|
|
}
|
|
|
|
|
2017-09-19 15:49:27 +01:00
|
|
|
export class Table extends XmlComponent {
|
2018-01-29 01:55:25 +00:00
|
|
|
private readonly properties: TableProperties;
|
|
|
|
private readonly rows: TableRow[];
|
2017-09-19 15:49:27 +01:00
|
|
|
|
2019-03-13 02:29:11 +00:00
|
|
|
constructor({
|
|
|
|
rows,
|
|
|
|
columns,
|
|
|
|
width = 100,
|
|
|
|
widthUnitType = WidthType.AUTO,
|
|
|
|
columnWidths = Array<number>(columns).fill(100),
|
2019-04-18 13:55:18 +10:00
|
|
|
margins: { marginUnitType, top, bottom, right, left } = { marginUnitType: WidthType.AUTO, top: 0, bottom: 0, right: 0, left: 0 },
|
2019-03-13 02:29:11 +00:00
|
|
|
float,
|
|
|
|
}: ITableOptions) {
|
2017-09-19 15:49:27 +01:00
|
|
|
super("w:tbl");
|
|
|
|
this.properties = new TableProperties();
|
|
|
|
this.root.push(this.properties);
|
2018-03-22 23:04:46 +00:00
|
|
|
this.properties.setBorder();
|
2019-03-13 02:29:11 +00:00
|
|
|
this.properties.setWidth(width, widthUnitType);
|
2019-04-18 13:55:18 +10:00
|
|
|
this.properties.CellMargin.addBottomMargin(bottom || 0, marginUnitType);
|
|
|
|
this.properties.CellMargin.addTopMargin(top || 0, marginUnitType);
|
|
|
|
this.properties.CellMargin.addLeftMargin(left || 0, marginUnitType);
|
|
|
|
this.properties.CellMargin.addRightMargin(right || 0, marginUnitType);
|
2019-03-13 02:29:11 +00:00
|
|
|
const grid = new TableGrid(columnWidths);
|
2017-09-19 15:49:27 +01:00
|
|
|
|
2019-03-08 01:09:21 +00:00
|
|
|
this.root.push(grid);
|
2017-09-19 15:49:27 +01:00
|
|
|
|
2019-03-13 02:29:11 +00:00
|
|
|
this.rows = Array(rows)
|
|
|
|
.fill(0)
|
|
|
|
.map(() => {
|
|
|
|
const cells = Array(columns)
|
|
|
|
.fill(0)
|
|
|
|
.map(() => new TableCell());
|
|
|
|
const row = new TableRow(cells);
|
|
|
|
return row;
|
|
|
|
});
|
|
|
|
|
|
|
|
this.rows.forEach((x) => this.root.push(x));
|
|
|
|
|
|
|
|
if (float) {
|
|
|
|
this.properties.setTableFloatProperties(float);
|
2017-09-19 15:49:27 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-04 22:50:04 +00:00
|
|
|
public getRow(index: number): TableRow {
|
|
|
|
const row = this.rows[index];
|
2018-09-12 21:01:52 +01:00
|
|
|
|
|
|
|
if (!row) {
|
|
|
|
throw Error("Index out of bounds when trying to get row on table");
|
|
|
|
}
|
|
|
|
|
|
|
|
return row;
|
2017-09-19 15:49:27 +01:00
|
|
|
}
|
|
|
|
|
2019-03-04 22:50:04 +00:00
|
|
|
public getColumn(index: number): TableColumn {
|
|
|
|
// This is a convinence method for people who like to work with columns
|
|
|
|
const cells = this.rows.map((row) => row.getCell(index));
|
|
|
|
return new TableColumn(cells);
|
|
|
|
}
|
|
|
|
|
2017-09-19 15:49:27 +01:00
|
|
|
public getCell(row: number, col: number): TableCell {
|
|
|
|
return this.getRow(row).getCell(col);
|
|
|
|
}
|
|
|
|
|
2018-08-07 01:25:28 +01:00
|
|
|
public setFixedWidthLayout(): Table {
|
|
|
|
this.properties.setFixedWidthLayout();
|
2017-09-19 15:49:27 +01:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
}
|