Link to home
Start Free TrialLog in
Avatar of Éric Moreau
Éric MoreauFlag for Canada

asked on

Generic way of formatting groups in a HTML table in Powershell

I am looking for a generic way of removing duplicates in my HTML output generated by Powershell scripts.

For example, say I have this data in a PS script:
cls

$convertParams = @{ 
 PreContent = "<H1>HTML Format test</H1>" 
 PostContent = "<p class='footer'>$(get-date)</p>"
 head = @"
 <Title>Event Log Report</Title>
<style>

td, th { border:0px solid black; 
         border-collapse:collapse;
         white-space:pre; }
th { color:white;
     background-color:black; }
table, tr, td, th { padding: 2px; margin: 0px ;white-space:pre; }
tr:nth-child(odd) {background-color: lightgray}
table { width:95%;margin-left:5px; margin-bottom:20px;}
h2 {
 font-family:Tahoma;
 color:#6D7B8D;
}
.footer 
{ color:green; 
  margin-left:10px; 
  font-family:Tahoma;
  font-size:8pt;
  font-style:italic;
}
</style>
"@
}

function CreateCollectionItem
{
    param([int]$pvalue, [string]$pValue2, [string]$pValue3)

    $newItem = New-Object System.Object
    $newItem | Add-Member -MemberType NoteProperty -Name "Col1" -Value $pvalue
    $newItem | Add-Member -MemberType NoteProperty -Name "Col2" -Value $pValue2
    $newItem | Add-Member -MemberType NoteProperty -Name "Col3" -Value $pValue3

    return $newItem
}

$data = New-Object System.Collections.ArrayList

$data.Add((CreateCollectionItem 1 "abc" "aaaaaaaa")) | Out-Null
$data.Add((CreateCollectionItem 2 "def" "ddddddddddddddddddddddddd")) | Out-Null
$data.Add((CreateCollectionItem 2 "ghi" "gg")) | Out-Null
$data.Add((CreateCollectionItem 3 "jkl" "jj")) | Out-Null

$data | ConvertTo-Html @convertParams  | Out-File C:\temp\htmloutput.htm 

Open in new window


The result shows like this:
User generated image
Is there a generic way of merging duplicate values in Col1 for example? I don't want to see repeating values. It is easier to read when values are grouped.
Avatar of Sam Jacobs
Sam Jacobs
Flag of United States of America image

In your example above, what should the merged line look like?
Avatar of Éric Moreau

ASKER

The value 2 in col1 is the one I am looking to merge.

It could me either that the 2 cells are merged (preferred) or a new line for the group is inserted.
So, for the value 2 in Col1, you are looking to see defghi in Col2 and ddddd....ddddgg in Col3?
I have more something like a rowspan in mind:
User generated image
Maybe not the most elegant, but you could cache and loop through the generated duplicate <tr> / <td> elements for col1 cells, increment the colspan for each duplicate, and output the set when the value of col1 changes.
you have a snippet of code that would do that? I am looking for results, not only "elegance"!
I don't have a snippet of code handy, but give me a bit of time to put something together.
ASKER CERTIFIED SOLUTION
Avatar of Sam Jacobs
Sam Jacobs
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
thanks Sam. Now need to integrate that into my scripts!
Any reason why if I modify the first column of the array list to a string that the column is not shown at all on the output?

function CreateCollectionItem
{
    param([string]$pvalue, [string]$pValue2, [string]$pValue3)

    $newItem = New-Object System.Object
    $newItem | Add-Member -MemberType NoteProperty -Name "Col1" -Value $pvalue
    $newItem | Add-Member -MemberType NoteProperty -Name "Col2" -Value $pValue2
    $newItem | Add-Member -MemberType NoteProperty -Name "Col3" -Value $pValue3

    return $newItem
}

$data = New-Object System.Collections.ArrayList

$data.Add((CreateCollectionItem "item 1" "abc" "aaaa")) | Out-Null
$data.Add((CreateCollectionItem "item 2" "def" "dddd")) | Out-Null
$data.Add((CreateCollectionItem "item 2" "ghi" "ffff")) | Out-Null
$data.Add((CreateCollectionItem "item 2" "lmn" "gggg")) | Out-Null
$data.Add((CreateCollectionItem "item 3" "jkl" "jjjj")) | Out-Null

Open in new window

I have done further tests. The error is not coming from the fact that the column is now a string. It seems to be due to the space it contains. Any way to fix that?
found it. I changed the regex pattern for
-Pattern "<td>([A-Za-z0-9 ]+)</td>"

Open in new window

Sorry ... didn't see your earlier emails ... glad you found it.
Sorry to bug you but I have another issue.

if the value of a column contains any character not in the pattern (ie .,@_ ...), the field is completely skipped from the output. Is there a way to just dump the value as is?
No problem at all ... Try the following pattern:
-Pattern "<td>(.*?)</td>"
All good now. I found a couple of other issues (like aligning text to the right) but that has nothing to do with the original question. Thanks again.
Cool … Sorry it took so long. It took a while to find the correct RegEx that was non-greedy …
You should be able to handle alignment issues with CSS.
I have tried the style, it kinda work when you look at the generated output in a browser but Outlook has limited capabilities and doesn't seem to use the style. And I say "kinda" because even the browser, on rows that have one column less because of the grouping, the attribute is applied to the wrong column.
Yep … It's been my experience as well that Outlook doesn't always comply with the full CSS. :(