Форматирование текста, когда текст отличается - PullRequest
0 голосов
/ 06 января 2020

Я создаю таблицу в Powershell следующим образом:

Count Name                                                       
----- ----                                                       
    1 Cisco Spark Room 55, NetworkAddressMissing                 
    1 Cisco Spark Room 55, OK                                    
    2 Cisco Spark Room Kit, NetworkAddressMissing                
    2 Cisco TelePresence DX80, NetworkAddressMissing             
    1 Cisco TelePresence DX80, NoHTTPSResponse                   
    4 Cisco TelePresence DX80, OK                                
   10 Cisco TelePresence MX200 G2, OK                            
   11 Cisco TelePresence MX200, OK                               
    3 Cisco TelePresence MX300 G2, NoHTTPSResponse               
   48 Cisco TelePresence MX300 G2, OK                            
    6 Cisco TelePresence MX300, OK                               
    3 Cisco TelePresence Profile 52/55 C40, NetworkAddressMissing

Сценарий Powershell в основном входит и получает некоторые данные, группируя их. То, что я получу, зависит от того, что находится в бэк-системах. Меня попросили разделить результаты, чтобы сделать его более ... эстет c. Предполагается, что у нас должны быть белые линии между различными системами или размещать разные системы в разные цвета и т. Д. c. Это означает, что мне нужно проверить начало «Имя» до запятой, чтобы увидеть, если это та же система с другим статусом, или это другая система, которая потребует какой-то разделитель.

Таблица выше много дольше, очевидно. Он сделан с помощью Powershell, и я также использую Powershell, чтобы преобразовать его в HTML с небольшим CSS, чтобы сделать его более приятным для нетехнических глаз.

Любые предложения о том, как go о форматирование как предложено?

1 Ответ

1 голос
/ 06 января 2020

Предполагая, что ваш пример выходной таблицы является результатом массива объектов PSO:

$data = [PsCustomObject]@{ Count = 1; Name = 'Cisco Spark Room 55, NetworkAddressMissing'},
        [PsCustomObject]@{ Count = 1; Name = 'Cisco Spark Room 55, OK'},
        [PsCustomObject]@{ Count = 2; Name = 'Cisco Spark Room Kit, NetworkAddressMissing'},
        [PsCustomObject]@{ Count = 2; Name = 'Cisco TelePresence DX80, NetworkAddressMissing'},
        [PsCustomObject]@{ Count = 1; Name = 'Cisco TelePresence DX80, NoHTTPSResponse'},
        [PsCustomObject]@{ Count = 4; Name = 'Cisco TelePresence DX80, OK'},
        [PsCustomObject]@{ Count = 10; Name = 'Cisco TelePresence MX200 G2, OK'},
        [PsCustomObject]@{ Count = 11; Name = 'Cisco TelePresence MX200, OK'},
        [PsCustomObject]@{ Count = 3; Name = 'Cisco TelePresence MX300 G2, NoHTTPSResponse'},
        [PsCustomObject]@{ Count = 48; Name = 'Cisco TelePresence MX300 G2, OK'},
        [PsCustomObject]@{ Count = 6; Name = 'Cisco TelePresence MX300, OK'},
        [PsCustomObject]@{ Count = 3; Name = 'Cisco TelePresence Profile 52/55 C40, NetworkAddressMissing'}

И вам нужна пустая строка между сгруппированными элементами, это может помочь:

# show headers on the first iteration only
$hideHeaders = $false
$data | Group-Object @{ Expression = {($_.Name -split ',')[0]}} | ForEach-Object {
    ($_.Group | Format-Table -AutoSize -HideTableHeaders:$hideHeaders | Out-String).TrimEnd()
    $hideHeaders = $true
}

Вывод:

Count Name                                      
----- ----                                      
    1 Cisco Spark Room 55, NetworkAddressMissing
    1 Cisco Spark Room 55, OK

    2 Cisco Spark Room Kit, NetworkAddressMissing

    2 Cisco TelePresence DX80, NetworkAddressMissing
    1 Cisco TelePresence DX80, NoHTTPSResponse      
    4 Cisco TelePresence DX80, OK

   10 Cisco TelePresence MX200 G2, OK

   11 Cisco TelePresence MX200, OK

    3 Cisco TelePresence MX300 G2, NoHTTPSResponse
   48 Cisco TelePresence MX300 G2, OK

    6 Cisco TelePresence MX300, OK

    3 Cisco TelePresence Profile 52/55 C40, NetworkAddressMissing

Перечитывая вопрос, я понимаю, что вывод вашей таблицы должен / мог бы быть HTML.

В этом случае, возможно, может пригодиться функция, представленная ниже:

$style = @"
    <style type="text/css">
        body {
            font-family: Calibri, Verdana, Arial, Geneva, Helvetica, sans-serif;
            font-size: 11pt;
            color: black;
        }
        table, td, th {
            border-style: solid;
            font-family: Calibri, Verdana, Arial, Geneva, Helvetica, sans-serif;
            font-size: 11pt;
            margin: 8pt 0 8pt 0;
        }
        table {
            border-width: 0 0 1px 1px;
            border-spacing: 0;
            border-collapse: collapse;
        }
        td, th {
            margin: 0;
            padding: 4px;
            border-width: 1px 1px 0 0;
            text-align: left;
        }
        th {
            color: white;
            font-weight: bold;
        }
    </style>
"@
# HTML start
$openHtml = @"
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Report</title>
        <meta name="generator" content="PowerShell" />
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        $style
    </head>
    <body>
"@
# HTML close
$closeHtml = '</body></html>'

function ConvertTo-HTMLTable {
    # Converts an object to a themed HTML table, mimicking the Excel "Table Style Normal"
    # Accepts a System.Data.DataTable object or an array of PSObjects and converts to styled HTML table
    [CmdletBinding(DefaultParameterSetName = 'ByTheme')]  
    Param (
        [parameter(Mandatory = $true, Position = 0)] 
        [object[]]$Data,

        [parameter(ParameterSetName = 'ByTheme')]
        [ValidateSet('Black', 'LightBlue', 'Orange', 'Gray', 'Gold', 'Blue', 'Green')]
        [string]$ThemeColor,

        [parameter(ParameterSetName = 'ByCustomColors')]
        [string]$HeaderColor,

        [parameter(ParameterSetName = 'ByCustomColors')]
        [string]$OddRowColor,

        [parameter(ParameterSetName = 'ByCustomColors')]
        [string]$EvenRowColor,

        [parameter(ParameterSetName = 'ByCustomColors')]
        [string]$BorderColor
    )
    # add type needed to replace HTML special characters into entities
    Add-Type -AssemblyName System.Web

    # define theme colors as array of hashtables
    $colors = switch($ThemeColor) {
        'Black'     { @{ 'header' = '#D9D9D9'; 'oddrow' = '#000000'; 'evenrow' = $null; 'border' = '#000000'} }
        'LightBlue' { @{ 'header' = '#5B9BD5'; 'oddrow' = '#DDEBF7'; 'evenrow' = $null; 'border' = '#000000'} }
        'Orange'    { @{ 'header' = '#ED7D31'; 'oddrow' = '#FCE4D6'; 'evenrow' = $null; 'border' = '#F4B084'} }
        'Gray'      { @{ 'header' = '#A5A5A5'; 'oddrow' = '#EDEDED'; 'evenrow' = $null; 'border' = '#C9C9C9'} }
        'Gold'      { @{ 'header' = '#FFC000'; 'oddrow' = '#FFF2CC'; 'evenrow' = $null; 'border' = '#FFD966'} }
        'Blue'      { @{ 'header' = '#4472C4'; 'oddrow' = '#D9E1F2'; 'evenrow' = $null; 'border' = '#8EA9DB'} }
        'Green'     { @{ 'header' = '#70AD47'; 'oddrow' = '#E2EFDA'; 'evenrow' = $null; 'border' = '#A9D08E'} }
        default     { @{ 'header' = $HeaderColor; 'oddrow' = $OddRowColor; 'evenrow' = $EvenRowColor; 'border' = $BorderColor} }
    }

    $sb = New-Object -TypeName System.Text.StringBuilder
    [void]$sb.AppendLine('<table style="border-color: {0};">' -f $colors['border'])
    if ($null -ne $Data) {
        if (([object]$Data).GetType().FullName -eq 'System.Data.DataTable'){
            # it is a DataTable; convert to array of PSObjects
            $Data = $Data | Select-Object * -ExcludeProperty ItemArray, Table, RowError, RowState, HasErrors
        }
        $headers = $Data[0].PSObject.Properties | Select -ExpandProperty Name
        [void]$sb.AppendLine(('<thead><tr style="background-color: {0};">' -f $colors['header']))
        foreach ($column in $headers) {
            $th = [System.Web.HttpUtility]::HtmlEncode($column)
            [void]$sb.AppendFormat('<th style="border-color: {0};">{1}</th>', $colors['border'], $th)
        }
        [void]$sb.AppendLine('</tr></thead><tbody>')

        $currentName  = $Data[0].Name
        $rowcolor = $colors['evenrow']
        $Data | ForEach-Object {
            # add inline style for different colored rows on each Name change
            if ($_.Name -ne $currentName) {
                if ($rowcolor -eq $colors['evenrow']) {
                    $rowcolor = $colors['oddrow']
                }
                else {
                    $rowcolor = $colors['evenrow']
                }
                $currentName = $_.Name
            }
            if ([string]::IsNullOrWhiteSpace($rowcolor)) {
                $tr = '<tr>'
            } 
            else {
                $tr = '<tr style="background-color: {0};">' -f $rowcolor
            }
            [void]$sb.AppendLine($tr)

            # now add the data cells
            foreach ($column in $headers) {
                [string]$val = $($_.$column)
                if ([string]::IsNullOrWhiteSpace($val)) { 
                    $td = '<td style="border-color: {0};">&nbsp;</td>' -f $colors['border']
                } 
                else { 
                    # if it's a number, align to the right
                    [double]$num = 0
                    if ([double]::TryParse($val,[ref]$num)) {
                        $td = '<td style="border-color: {0}; text-align: right;">{1}</td>' -f $colors['border'], $val
                    }
                    else {
                        $val = [System.Web.HttpUtility]::HtmlEncode($val)
                        $td = '<td style="border-color: {0};">{1}</td>' -f $colors['border'], $val
                    }
                }
                [void]$sb.Append($td)
            }
            [void]$sb.AppendLine('</tr>')
        }
        [void]$sb.AppendLine('</tbody>')
    }
    [void]$sb.AppendLine('</table>')

    return $sb.ToString()
}

Имея все это на своем месте, вы можете преобразовать свои исходные данные (опять же: я предполагаю, что это массив PSObjects ) примерно так:

# split the Name property into Name and Status and update the objects
$data | ForEach-Object {
    $name, $status = ($_.Name -split ',', 2).Trim()
    $_.Name = $name
    $_ | Add-Member -MemberType NoteProperty -Name 'Status' -Value $status
}

# convert the data to styled HTML table
$table = ConvertTo-HTMLTable -Data ($data | Sort-Object Name) -ThemeColor Blue

# complete the HTML
$html  = '{0}{1}{2}' -f $openHtml, $table, $closeHtml

Далее вы можете сохранить его как html file

$html | Set-Content -Path 'D:\report.html'

Или использовать Send-MailMessage , чтобы отправить его как приятное письмо вашим коллегам.

Синяя тема дает вам этот вывод

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...