从 .CSV 中提取表格以在电子邮件中使用

Extracting Tables from .CSV for Use in Email

我有一个 .csv 文件,其中包含我工作的公司前雇员的 1000 多个条目,我正试图按员工将其拆分为可以插入电子邮件模板的格式。雪上加霜的是,许多(但不是全部)员工都有不止一个条目,而且 .csv 包含大量信息,而这些信息对于我将向其发送电子邮件的人来说是完全不必要的。理想情况下,我想排除这些列,但我遇到了很多困难。在我看来,format-table 将是我需要的 cmdlet,但我不是 100% 确定。到目前为止我已经尝试过:

import-csv C:\filepath\xx.csv | format-table -groupby (key value)

return 信息以我想要的方式组织,但是我不知道如何从那里拆分信息,所以我只能发送特定员工的信息。如前所述,这还包括相当多的无关信息。我也试过:

import-csv C:\filepath\xx.csv | format-table -groupby (key value) -property (properties I want,separated by commas)

然而,这仍然是 returning 相同的无关信息。我还尝试使用 foreach 循环遍历 .csv,将我想要的信息存储在变量中,然后将这些变量存储在一个数组中,然后将该数组通过管道传输到 format-table,这会导致一团糟。我还尝试将 .csv 放入按我想要的键值分组的散列 table 中,但这会导致其余信息被放入字符串中。我相信我应该能够使用正则表达式拆分这个字符串,但是我一点也不熟悉正则表达式,也不知道从哪里开始。在这一点上我很困惑。任何帮助将不胜感激。

编辑

按照@4c74356b41 的建议(对此我非常感谢),我能够输出 table 的列表,其中只有相关信息。但是,我仍然无法将这个 table 列表拆分为我需要的单个 table。我目前有一个用作模板的 .txt 文件,我想为个人用户添加 table。到目前为止,我已经成功地使用 get-content 检索 .txt 的内容,-replace 从原始 .csv 中的信息(例如姓名、经理等)替换模板上的其他几个字段,然后输出-文件将编辑后的模板存储到临时文件中,然后将其保存为草稿到 outlook。我试图在之前的 foreach 循环中添加另一个 foreach 循环以将 tables 添加到模板中,但那是 returning 模板,其中行 'Microsoft.PowerShell.Commands.Internal.Format.FormatStartData' 代替了 table.它还为每个条目创建一个草稿,而不仅仅是为每个唯一的用户 ID 创建一个草稿。这是我到目前为止的所有代码:

$olFolderDrafts = 16
$ol = New-Object -comObject Outlook.Application 
$ns = $ol.GetNameSpace("MAPI")
$file= import-csv H:\filepath\term_rep.csv
$data= import-csv H:\filepath\term_rep.csv | select-object "Inactive Emp Name","User ID","Loc","Equipment Descr","Tag Number","Serial Number"
$table= $data | Format-Table -GroupBy "User ID"
foreach($i in $file)
    {$user = $i | select-object -expandproperty "Inactive Emp Name"
    $uid= $i | select-object -expandproperty "User ID"
    $manager = $i | Select-Object -expandproperty "Manager"
    $loc= $i | select -ExpandProperty "Loc"
    $tagnum= $i | select -ExpandProperty "Tag Number"
    $sernum= $i | select -ExpandProperty "Serial Number"
    $path="C:\filepath\term_email.txt"
    $newpath = [system.io.path]::GetTempFileName() 
    (Get-content $path) -replace "USER_NAME",$user `
    -replace "USER_ID",$uid | out-file $newpath
    foreach($id in $table){
        (Get-Content $newpath) -replace "EQUIPMENT_LIST", $id | out-file $newpath
    }
    $subject="Equipment for user $uid"
    $body= get-content $newpath
    $mail = $ol.CreateItem(0)
    $mail.To = $manager 
    $mail.CC = $null
    $mail.Subject = $subject  
    $mail.Body = $body -join "`n"
    $mail.save()}

假设您的 csv 有一些列:姓名、姓氏、bla-bla、bla-bla、bla-bla.

$data = import-csv C:\filepath\xx.csv | select name, surname
$data | format-table -groupby (key value)

为了减少噪音和重复,我会找到特定于用户的列,例如用户名或电子邮件。然后按此分组,select 每组中的第一项。然后您可以通过管道传输到 Select 以减少无关列的噪音。类似于:

import-csv C:\filepath\xx.csv | Group UserName | ForEach{$_.Group[0]} | Select FirstName,LastName,Email,UserName,SeparationDate 

然后你可以用它做你想做的事...通过管道传输到另一个 ForEach 循环以一次处理每条记录,或者通过管道传输到 Export-CSV 以生成新的 CSV减少您可以使用的混乱。您甚至可以让 PowerShell 为您创建电子邮件,具体取决于您的喜好。

如果您需要进一步的帮助,请更新您的问题,举例说明您想要的输出是什么,或者您希望通过每个条目完成什么。

编辑: 好吧,归根结底,你想要插入一个 table 的东西,用于匹配特定用户的任何记录到电子邮件中,所以他们离开公司后,你可以从他们的经理那里拿回他们的东西。太棒了,我们可以做到。首先,您正在使用 Outlook ComObject,并以此方式生成您的电子邮件。太棒了,我自己做过,你可以那样做一些很棒的事情!我强烈建议在这里使用 HTML。它使电子邮件看起来更专业,并让我们在电子邮件中插入一个漂亮的 table,而不是一些格式化的文本,因为一旦在电子邮件中留有空格,这些文本看起来会很有趣。

所以,让我们暂时从问题上退一步,重做您的电子邮件模板。弹出打开 MS Word 并打开您的模板。现在,转到文件并另存为。 Select 'Web Page, Filtered' 作为您的文档类型,并使用您已有的名称命名。

所以,与其加载列表两次,然后导出,等等,等等,等等,我们将稍微缩短一些。我们加载您的 CSV 一次。就此而言,我们不需要为每个用户读取一次电子邮件正文,因此我们也只需在循环之前在此处加载一次。然后我们使用 -Unique 开关将用户 ID 字段通过管道传输到 Select-Object,这样我们只为每个用户生成一封电子邮件。所以,到那里的脚本看起来像这样:

$olFolderDrafts = 16
$ol = New-Object -comObject Outlook.Application 
$ns = $ol.GetNameSpace("MAPI")
$file= import-csv H:\filepath\term_rep.csv
$path="C:\filepath\term_email.txt"
$body = (Get-content $path) -join "`n"
foreach($i in ($file.'User ID'|Select -Unique))
    {

现在,没有必要像您一样分配所有这些变量,所以我跳过了那部分。所以我们将找到当前用户的第一个实例,并将其保存到一个变量中。

    $User = $File|Where{$_.'User ID' -eq $i}|Select -First 1

一旦我们得到了,我们将在列表中找到他们的所有记录,select 只有您感兴趣的属性,并将输出转换为 HTML table 使用 ConvertTo-HTML.

    $Equip = $File|Where{$_.'User ID' -eq $i}|select-object "Inactive Emp Name","User ID","Loc","Equipment Descr","Tag Number","Serial Number"|ConvertTo-Html -Property '*' -As Table -Fragment

这是一条很长的线,但其中大部分只是 select 正确的属性。魔术发生在我们告诉它将数据转换为 HTML 的最后一位。具体来说,我们希望所有内容(由 -Property '*' 指定),我们希望将其转换为 table,并且这只是一个片段,因此它不会尝试将所有前后那里的标签(所以没有 <HTML></HTML> 类型的标签,因为它被注入到现有 HTML 的中间。)

然后我们进行替换,制作电子邮件,分配属性,yada,yada,yada,你几乎已经拥有了所有这些......

    $HTMLbody = $body -replace "USER_NAME",$user.'Inactive Emp Name' -replace "USER_ID",$user.'User ID' -replace "EQUIPMENT_LIST", $Equip
    $subject="Equipment for user " + $User.'User ID'
    $mail = $ol.CreateItem(0)
    $mail.To = $User.Manager 
    $mail.Subject = $subject  
    $mail.HTMLBody = $HTMLbody
    $mail.save()
    }

保存,大功告成!循环到下一个用户,然后重复。所以把它们放在一起你会得到:

$olFolderDrafts = 16
$ol = New-Object -comObject Outlook.Application 
$ns = $ol.GetNameSpace("MAPI")
$file= import-csv H:\filepath\term_rep.csv
$path="C:\temp\email.htm"
$body = (Get-content $path) -join "`n"
foreach($i in ($file.'User ID'|Select -Unique))
    {
    $User = $File|Where{$_.'User ID' -eq $i}|Select -First 1
    $Equip = $File|Where{$_.'User ID' -eq $i}|select-object "Inactive Emp Name","User ID","Loc","Equipment Descr","Tag Number","Serial Number"|ConvertTo-Html -Property '*' -As Table -Fragment
    $HTMLbody = $body -replace "USER_NAME",$user.'Inactive Emp Name' -replace "USER_ID",$user.'User ID' -replace "EQUIPMENT_LIST", $Equip
    $subject="Equipment for user " + $User.'User ID'
    $mail = $ol.CreateItem(0)
    $mail.To = $User.Manager 
    $mail.Subject = $subject  
    $mail.HTMLBody = $HTMLbody
    $mail.save()
    }