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" ;
2019-09-25 00:57:24 +01:00
import { TableCell , VMergeType , WidthType } from "./table-cell" ;
2018-10-23 23:44:50 +01:00
import { ITableFloatOptions , TableProperties } from "./table-properties" ;
2019-06-25 20:57:46 +01:00
import { TableLayoutType } from "./table-properties/table-layout" ;
2018-10-23 23:44:50 +01:00
import { TableRow } from "./table-row" ;
2019-09-13 00:51:20 +01:00
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
~ 6 in / n u m C o l s , b u t i f w e d o t h a t i t b e c o m e s v e r y h a r d
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 {
2019-09-13 00:51:20 +01:00
readonly rows : TableRow [ ] ;
2019-03-13 02:29:11 +00:00
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 ;
2019-06-25 20:57:46 +01:00
readonly layout? : TableLayoutType ;
2019-03-13 02:29:11 +00:00
}
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 ;
2017-09-19 15:49:27 +01:00
2019-03-13 02:29:11 +00:00
constructor ( {
rows ,
width = 100 ,
widthUnitType = WidthType . AUTO ,
2019-09-13 00:51:20 +01:00
columnWidths = Array < number > ( Math . max ( . . . rows . map ( ( row ) = > row . CellCount ) ) ) . 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 ,
2019-06-25 20:57:46 +01:00
layout ,
2019-03-13 02:29:11 +00:00
} : 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 ) ;
2017-09-19 15:49:27 +01:00
2019-09-13 00:51:20 +01:00
this . root . push ( new TableGrid ( columnWidths ) ) ;
2017-09-19 15:49:27 +01:00
2019-09-13 00:51:20 +01:00
for ( const row of rows ) {
this . root . push ( row ) ;
}
2019-03-13 02:29:11 +00:00
2019-09-25 00:57:24 +01:00
for ( const row of rows ) {
row . Children . forEach ( ( cell , cellIndex ) = > {
const column = rows . map ( ( r ) = > r . Children [ 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 (
new TableCell ( {
children : [ ] ,
verticalMerge : VMergeType.CONTINUE ,
} ) ,
i ,
) ;
}
}
} ) ;
}
2019-03-13 02:29:11 +00:00
if ( float ) {
this . properties . setTableFloatProperties ( float ) ;
2017-09-19 15:49:27 +01:00
}
2019-06-25 20:57:46 +01:00
if ( layout ) {
this . properties . setLayout ( layout ) ;
}
2017-09-19 15:49:27 +01:00
}
}