Public/Add-VellumPdfTable.ps1
|
function Add-VellumPdfTable { <# .SYNOPSIS Adds a table to a VellumPdf document. .DESCRIPTION Wraps Document.Add(TableElement). Builds a TableElement from a jagged array of row data, an optional header row, optional column widths, border styling, and a default cell text style. The document flows through the pipeline for chaining with other Add-VellumPdf* functions. Each inner array in -Row represents one data row; each element is converted to a string with ToString() and added as a cell. The optional -Header array produces a header row via AddHeaderRow(). The -BorderColor and -HeaderBackground parameters accept a three-element array of [double] values in the 0..1 range (R, G, B). NOTE: -Row is a jagged array (array of rows). For a SINGLE row use the unary comma operator so PowerShell does not flatten the outer array: -Row @(,@('Cell1','Cell2')). A flat array like -Row @('a','b') is treated as two one-cell rows. -MarginTop and -MarginBottom apply spacing above and below the table without affecting the left/right margins already set on the element. Objects from Import-Csv (PSCustomObject) are rejected with a hint; convert them to value arrays first: $rows = Import-Csv data.csv | ForEach-Object { [object[]]($_.PSObject.Properties.Value) } .PARAMETER Document The live VellumPdf document flowing through the pipeline. The same instance is returned after the table is added, enabling chaining. .PARAMETER Header An optional string array of column header labels. When supplied, a styled header row is prepended to the table via AddHeaderRow(). The count of header cells determines the expected column count for -ColumnWidth mismatch warnings. .PARAMETER Row A jagged array of data rows (array of arrays). Each inner array element is converted to a string via ToString() and added as a cell. PSCustomObject elements are rejected with a conversion hint. For a single data row, use the unary comma operator to prevent PowerShell from flattening the outer array: -Row @(,@('Cell1','Cell2')). .PARAMETER ColumnWidth Column widths in points, each between 0.01 and 100000. The count should match the number of columns determined by the -Header or first -Row; a mismatch emits a warning and extra widths are ignored. .PARAMETER BorderWidth Border line width in points applied to all cell borders, between 0 and 100. When omitted the VellumPdf library default is used. .PARAMETER BorderColor Border line colour as three doubles representing Red, Green, and Blue channels, each in the 0.0..1.0 range. Exactly three values must be supplied. When omitted the library default border colour is used. .PARAMETER HeaderBackground Background fill colour for the header row as three doubles representing Red, Green, and Blue channels, each in the 0.0..1.0 range. Exactly three values must be supplied. Only applied when -Header is also supplied. .PARAMETER Font A base-14 font name applied as the default cell style for all data cells. When omitted the document default font is used. .PARAMETER FontSize Font size in points for all data cells, between 1 and 1000. When omitted the document default size is used. .PARAMETER Alignment Horizontal text alignment for all cells (header and data). Accepts Left, Center, Right, or Justify. Defaults to Left. .PARAMETER MarginTop Extra spacing in points above the table element. Does not affect the left/right page margins. .PARAMETER MarginBottom Extra spacing in points below the table element. Does not affect the left/right page margins. .EXAMPLE $headers = @('Name', 'Score', 'Grade') $rows = @( @('Alice', '95', 'A'), @('Bob', '82', 'B') ) New-VellumPdfDocument | Add-VellumPdfTable -Header $headers -Row $rows -BorderWidth 0.5 | Save-VellumPdfDocument -Path ./report.pdf .EXAMPLE $doc | Add-VellumPdfTable -Row @(@('Cell1','Cell2')) ` -ColumnWidth @(100, 200) -Font Helvetica -FontSize 10 -Alignment Center .OUTPUTS VellumPdf.Layout.Document (the same instance, for chaining) #> [CmdletBinding()] [OutputType([VellumPdf.Layout.Document])] param( [Parameter(Mandatory, ValueFromPipeline)] [VellumPdf.Layout.Document]$Document, [string[]]$Header, [Parameter(Mandatory)] [object[][]]$Row, [ValidateRange(0.01, 100000)] [double[]]$ColumnWidth, [ValidateRange(0, 100)] [double]$BorderWidth, [ValidateCount(3, 3)] [ValidateRange(0.0, 1.0)] [double[]]$BorderColor, [ValidateCount(3, 3)] [ValidateRange(0.0, 1.0)] [double[]]$HeaderBackground, [ValidateSet('Courier', 'CourierBold', 'CourierBoldOblique', 'CourierOblique', 'Helvetica', 'HelveticaBold', 'HelveticaBoldOblique', 'HelveticaOblique', 'Symbol', 'TimesBold', 'TimesBoldItalic', 'TimesItalic', 'TimesRoman', 'ZapfDingbats')] [string]$Font, [ValidateRange(1, 1000)] [double]$FontSize, [ValidateSet('Left', 'Center', 'Right', 'Justify')] [string]$Alignment = 'Left', [ValidateRange(0, 10000)] [double]$MarginTop, [ValidateRange(0, 10000)] [double]$MarginBottom ) process { Assert-VellumPdfDocumentOpen -Document $Document -CommandName 'Add-VellumPdfTable' # Objects from Import-Csv / Select-Object bind as one PSCustomObject per # row, which would stringify into a single mangled cell. Fail fast with # a conversion hint instead of producing a silently wrong table. foreach ($r in $Row) { foreach ($v in $r) { if ($v -is [System.Management.Automation.PSCustomObject]) { throw ('Add-VellumPdfTable: -Row received a PSCustomObject (e.g. from Import-Csv). ' + 'Convert rows to value arrays first: ' + '$rows = $data | ForEach-Object { [object[]]($_.PSObject.Properties.Value) }') } } } $cellText = @($Header) + @($Row | ForEach-Object { $_ | ForEach-Object { [string]$_ } }) Write-VellumPdfEncodingWarning -Text $cellText -CommandName 'Add-VellumPdfTable' $table = [VellumPdf.Layout.Elements.Table.TableElement]::new() # Apply default cell style when font or size is requested. Gaps are # filled from the document defaults: a style without a font renders in # the library-global Helvetica, not the document default. $wantsStyle = [bool]$Font -or $PSBoundParameters.ContainsKey('FontSize') if ($wantsStyle) { $default = Resolve-VellumPdfDefault -Document $Document $effFont = if ($Font) { $Font } else { $default.Font } $effSize = if ($PSBoundParameters.ContainsKey('FontSize')) { $FontSize } else { $default.FontSize } $table.DefaultCellStyle = New-VellumTextStyle -Font $effFont -FontSize $effSize } # Apply border width. if ($PSBoundParameters.ContainsKey('BorderWidth')) { $table.BorderWidth = $BorderWidth } # Apply border color. if ($BorderColor) { $table.BorderColor = [VellumPdf.Layout.Core.ColorRgb]::new( $BorderColor[0], $BorderColor[1], $BorderColor[2]) } # Apply column widths. if ($ColumnWidth) { $columnCount = if ($Header) { $Header.Count } else { $Row[0].Count } if ($ColumnWidth.Count -ne $columnCount) { Write-Warning ("Add-VellumPdfTable: -ColumnWidth has $($ColumnWidth.Count) value(s) " + "but the table has $columnCount column(s); extra widths are ignored and " + 'missing ones fall back to the library default.') } [void]$table.SetColumnWidths($ColumnWidth) } # Add optional header row. if ($Header) { $headerRow = $table.AddHeaderRow() if ($HeaderBackground) { $headerRow.Background = [VellumPdf.Layout.Core.ColorRgb]::new( $HeaderBackground[0], $HeaderBackground[1], $HeaderBackground[2]) } foreach ($text in $Header) { $cell = [VellumPdf.Layout.Elements.Table.Cell]::new([string]$text) $cell.Alignment = [VellumPdf.Layout.Core.HorizontalAlignment]::$Alignment [void]$headerRow.AddCell($cell) } } # Add data rows. foreach ($dataRow in $Row) { $tableRow = $table.AddRow($false) foreach ($value in $dataRow) { $cell = [VellumPdf.Layout.Elements.Table.Cell]::new([string]$value) $cell.Alignment = [VellumPdf.Layout.Core.HorizontalAlignment]::$Alignment [void]$tableRow.AddCell($cell) } } Set-VellumPdfElementMargin -Element $table -Top $MarginTop -Bottom $MarginBottom ` -BoundParameters $PSBoundParameters [void]$Document.Add($table) $Document } } |