英文:
Formating text when text is different
问题
我正在使用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脚本主要用于获取一些数据并对其进行分组。我获取的内容取决于后端系统中的内容。我被要求将结果分开以使其更具美感。有建议在不同系统之间添加白色分隔线,或者以不同颜色显示不同系统等。这意味着我需要检查“Name”字段的开头,直到逗号,以查看它是否是具有不同状态的相同系统,还是不同的系统,需要某种分隔符。
上面的表格显然要长得多。它是通过Powershell制作的,我还使用Powershell将其转换为HTML,并使用一些CSS使其更适合非技术人员的眼睛。
关于如何按照建议的格式进行排版,有什么建议吗?
英文:
I'm makeing a table in Powershell like so :
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
The Powershell script mainly goes in and gets some data, grouping it. What I get depends on what's in the back-systems. I've been asked to seperate the results to make it more ... aesthetic. It's been suggested that we should have white lines in-between the different systems, or place the different systems in different colors etc. Which means I need to check the beginning of "Name" up to the comma to see if it's the same system with a different status, or if it's a different system which would require some kind of seperator.
The table above is alot longer obviously. It's made through Powershell, and I also use Powershell to convert it into HTML with a small CSS to make it more pleasing for the non-technical eye.
Any suggestions on how to go about formating as suggested ?
答案1
得分: 1
以下是翻译好的部分:
假设您的示例表格输出是类似以下数组的 PSObjects 的结果:
> $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'}
如果您想在分组的项目之间插入空行,可以尝试以下方法:
# 在第一次迭代中显示标题
$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
请注意,这只是一部分翻译。如果您需要更多内容的翻译,请提出具体的要求。
英文:
Assuming your example table output is the result of an array of PSObjects like this:
> $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'}
And you want an empty line between the grouped items, this might help:
# 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
}
Output:
> 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
<hr>
On re-reading the question, I understand that your table output should/could be HTML.
In that case, perhaps the below function could be of service:
$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()
}
With all that in place, you can transform your original data (again: I assume this is an array of PSObjects) like so:
# 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
Next, you can save it as html file
$html | Set-Content -Path 'D:\report.html'
Or use Send-MailMessage to send it as nice email to your colleagues.
The Blue theme gives you this output
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论