2018-09-12 21:01:52 +01:00
// http://officeopenxml.com/WPtableGrid.php
2023-01-23 14:14:05 +00:00
import { FileChild } from "@file/file-child" ;
2019-11-24 01:22:17 +00:00
import { AlignmentType } from "../paragraph" ;
2017-09-19 15:49:27 +01:00
import { TableGrid } from "./grid" ;
2021-05-23 21:17:20 +03:00
import { TableCell , VerticalMergeType } from "./table-cell" ;
2019-11-18 01:04:31 +00:00
import { ITableBordersOptions , ITableFloatOptions , TableProperties } from "./table-properties" ;
2021-05-23 21:17:20 +03:00
import { ITableCellMarginOptions } from "./table-properties/table-cell-margin" ;
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" ;
2021-05-23 21:17:20 +03:00
import { ITableWidthProperties } from "./table-width" ;
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 {
2022-09-15 20:00:50 +01:00
readonly rows : readonly TableRow [ ] ;
2021-05-23 21:17:20 +03:00
readonly width? : ITableWidthProperties ;
2022-09-15 20:00:50 +01:00
readonly columnWidths? : readonly number [ ] ;
2021-05-23 21:17:20 +03:00
readonly margins? : ITableCellMarginOptions ;
readonly indent? : ITableWidthProperties ;
2019-03-13 02:29:11 +00:00
readonly float? : ITableFloatOptions ;
2019-06-25 20:57:46 +01:00
readonly layout? : TableLayoutType ;
2019-10-21 11:40:05 -05:00
readonly style? : string ;
2019-11-18 01:04:31 +00:00
readonly borders? : ITableBordersOptions ;
2019-11-24 01:22:17 +00:00
readonly alignment? : AlignmentType ;
2021-03-04 02:02:28 +00:00
readonly visuallyRightToLeft? : boolean ;
2019-03-13 02:29:11 +00:00
}
2023-01-23 14:14:05 +00:00
export class Table extends FileChild {
2022-08-31 07:52:27 +01:00
public constructor ( {
2019-03-13 02:29:11 +00:00
rows ,
2019-09-26 02:03:17 +01:00
width ,
2022-09-15 20:00:50 +01:00
// eslint-disable-next-line functional/immutable-data
2019-09-13 00:51:20 +01:00
columnWidths = Array < number > ( Math . max ( . . . rows . map ( ( row ) = > row . CellCount ) ) ) . fill ( 100 ) ,
2021-05-23 21:17:20 +03:00
margins ,
indent ,
2019-03-13 02:29:11 +00:00
float ,
2019-06-25 20:57:46 +01:00
layout ,
2019-10-21 11:40:05 -05:00
style ,
2019-11-18 01:04:31 +00:00
borders ,
2019-11-24 01:22:17 +00:00
alignment ,
2021-03-04 02:02:28 +00:00
visuallyRightToLeft ,
2019-03-13 02:29:11 +00:00
} : ITableOptions ) {
2017-09-19 15:49:27 +01:00
super ( "w:tbl" ) ;
2019-09-26 02:03:17 +01:00
2021-03-04 01:42:58 +00:00
this . root . push (
new TableProperties ( {
borders : borders ? ? { } ,
width : width ? ? { size : 100 } ,
2021-05-23 21:17:20 +03:00
indent ,
2021-03-04 01:42:58 +00:00
float ,
layout ,
2021-03-07 21:40:42 +00:00
style ,
2021-03-04 01:42:58 +00:00
alignment ,
2021-05-23 21:17:20 +03:00
cellMargin : margins ,
2021-03-04 02:02:28 +00:00
visuallyRightToLeft ,
2021-03-04 01:42:58 +00:00
} ) ,
) ;
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
2020-06-20 19:47:46 +08:00
rows . forEach ( ( row , rowIndex ) = > {
2020-07-08 12:32:01 +08:00
if ( rowIndex === rows . length - 1 ) {
// don't process the end row
return ;
}
let columnIndex = 0 ;
row . cells . forEach ( ( cell ) = > {
2019-09-25 00:57:24 +01:00
// 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 ) {
2020-07-08 12:32:01 +08:00
const continueCell = new TableCell ( {
// the inserted CONTINUE cell has rowSpan, and will be handled when process the next row
rowSpan : cell.options.rowSpan - 1 ,
columnSpan : cell.options.columnSpan ,
borders : cell.options.borders ,
children : [ ] ,
verticalMerge : VerticalMergeType.CONTINUE ,
} ) ;
rows [ rowIndex + 1 ] . addCellToColumnIndex ( continueCell , columnIndex ) ;
2019-09-25 00:57:24 +01:00
}
2020-07-08 12:32:01 +08:00
columnIndex += cell . options . columnSpan || 1 ;
2019-09-25 00:57:24 +01:00
} ) ;
2020-06-20 19:47:46 +08:00
} ) ;
2017-09-19 15:49:27 +01:00
}
}