【问题标题】:Sending Formatted HTML email发送格式化的 HTML 电子邮件
【发布时间】:2013-11-08 01:12:35
【问题描述】:

我有一个文本文件 output.txt,其中包含以下内容:

OPERATINGSYSTEM     PROJECTSERVER1   PROJECTSERVER2
Windows                       1.36             4.42
Linux12                       2.78             5.76
MacOS                         3.45             6.39
Ubuntu                        4.12             0.00
Android                       0.00             3.46
FreePhysicalMemory           30.12            31.65
TotalVisibleMemorySize       48.00            48.00
CPULoadPercentage                2                4

我想在电子邮件中将 output.txt 的内容作为正文发送到 Windows server 2008 R2 中的格式化 HTML 表格中。我正在尝试使用下面的代码,但它对我不起作用..我在下面哪里弄错了?

$smtpServer = "sunny@abc.com"
$smtpFrom = "process@abc.com"
$smtpTo = "administrator@abc.com"
$messageSubject = "Servers Memory"

$message = New-Object System.Net.Mail.MailMessage $smtpfrom, $smtpto
$message.Subject = $messageSubject
$message.IsBodyHTML = $true

$message.Body = Get-Content C:\Logs\output.txt
$style = "< style>BODY{font-family: Arial; font-size: 10pt;}"
$style = $style + "TABLE{border: 1px solid black; border-collapse: collapse;}"
$style = $style + "TH{border: 1px solid black; background: #dddddd; padding: 5px; }"
$style = $style + "TD{border: 1px solid black; padding: 5px; }"
$style = $style + "< /style>"

$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($message)

EDIT1

当我修改我的代码如下:

$smtpServer = "sunny@abc.com"
$smtpFrom = "process@abc.com"
$smtpTo = "administrator@abc.com"
$messageSubject = "Servers Memory"

$message = New-Object System.Net.Mail.MailMessage $smtpfrom, $smtpto
$message.Subject = $messageSubject
$message.IsBodyHTML = $true

$style = "<style>BODY{font-family: Arial; font-size: 10pt;}"
$style = $style + "TABLE{border: 1px solid black; border-collapse: collapse;}"
$style = $style + "TH{border: 1px solid black; background: #dddddd; padding: 5px; }"
$style = $style + "TD{border: 1px solid black; padding: 5px; }"
$style = $style + "</style>"
$message.Body = "<head><pre>$style</pre></head>"
$message.Body += Get-Content C:\Logs\output.txt

$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($message)

我收到这样的邮件:

OPERATING SYSTEM SERVER1 SERVER2 Windows 1.36 4.42 Linux 2.78 5.76 MacOS 3.45 6.39 Android 0.00 3.46 Ubuntu 4.12 0.00 FreePhysicalMemory 30.12 31.65 TotalVisibleMemorySize 48.00 48.00 

注意:我使用的是 Powershell v1.0

【问题讨论】:

  • 1. “不工作”以哪种方式?您越具体,就越有可能有人能够识别问题。 2. 你对 $style 的意图是什么?您将其值设置为一堆 CSS 代码,但您没有对它做任何事情。似乎在最后一个$style = [...] 语句和$smtp = [...] 语句之间应该有类似$message.Body = '&lt;head&gt;' + $style + '&lt;/head&gt;' + $message.Body 的东西。 3. output.txt 不包含 HTML。它应该有HTML表格数据,否则格式将是错误的。这就是“不工作”吗?

标签: powershell powershell-2.0 powershell-1.0


【解决方案1】:

好的,这个问题有点不清楚,但我会根据我推断的“​​不适合你”来尝试一下。我猜你的脚本 成功发送了消息,而不能正常工作的是消息的格式完全错误,原因有两个:

  1. output.txt 是纯文本,而不是 HTML。在 HTML 中呈现时,不会保留空格,也不会有任何换行符。如果空格由空格组成,则连续空格将减少为单个空格,如果是制表符,我相信文本将全部运行在一起,根本没有空格。我认为您希望 $message.IsBodyHTML = $true 将您的纯文本输入转换为 HTML,但这不是它的作用。它只是设置消息的一个属性,指示邮件客户端将正文解释为 HTML(具体而言,它将 Content-Type 标头设置为“text/html”),但您必须实际提供 HTML 代码。
  2. 您正在将 $style 变量设置为一堆 CSS 代码,但随后您什么也不做。我想您打算将它添加到 $message.Body。这样做的问题是您不能可靠地将样式表放入电子邮件中。大多数客户会忽略它。样式必须是内联的。

output.txt 应如下所示:

<body style="font-family: Arial; font-size: 10pt;">
  <table style = "border: 1px solid black; border-collapse: collapse;">
    <tr>
      <th style = "border: 1px solid black; background: #dddddd; padding: 5px;">OPERATINGSYSTEM</th>
      <th style = "border: 1px solid black; background: #dddddd; padding: 5px;">PROJECTSERVER1</th>
      <th style = "border: 1px solid black; background: #dddddd; padding: 5px;">PROJECTSERVER2</th>
    </tr>
    <tr>
      <td style = "border: 1px solid black; padding: 5px;">Windows</td>
      <td style = "border: 1px solid black; padding: 5px;">1.36</td>
      <td style = "border: 1px solid black; padding: 5px;">4.42</td>
    </tr>
    <tr>
      <td style = "border: 1px solid black; padding: 5px;">Linux12</td>
      <td style = "border: 1px solid black; padding: 5px;">2.78</td>
      <td style = "border: 1px solid black; padding: 5px;">5.76</td>
    </tr>
    <tr>
      <td style = "border: 1px solid black; padding: 5px;">MacOS</td>
      <td style = "border: 1px solid black; padding: 5px;">3.45</td>
      <td style = "border: 1px solid black; padding: 5px;">6.39</td>
    </tr>
    <tr>
      <td style = "border: 1px solid black; padding: 5px;">Ubuntu</td>
      <td style = "border: 1px solid black; padding: 5px;">4.12</td>
      <td style = "border: 1px solid black; padding: 5px;">0.00</td>
    </tr>
    <tr>
      <td style = "border: 1px solid black; padding: 5px;">Android</td>
      <td style = "border: 1px solid black; padding: 5px;">0.00</td>
      <td style = "border: 1px solid black; padding: 5px;">3.46</td>
    </tr>
    <tr>
      <td style = "border: 1px solid black; padding: 5px;">FreePhysicalMemory</td>
      <td style = "border: 1px solid black; padding: 5px;">30.12</td>
      <td style = "border: 1px solid black; padding: 5px;">31.65</td>
    </tr>
    <tr>
      <td style = "border: 1px solid black; padding: 5px;">TotalVisibleMemorySize</td>
      <td style = "border: 1px solid black; padding: 5px;">48.00</td>
      <td style = "border: 1px solid black; padding: 5px;">48.00</td>
    </tr>
    <tr>
      <td style = "border: 1px solid black; padding: 5px;">CPULoadPercentage</td>
      <td style = "border: 1px solid black; padding: 5px;">2</td>
      <td style = "border: 1px solid black; padding: 5px;">4</td>
    </tr>
  </table>
</body>

PowerShell 脚本应如下所示:

$smtpServer = "sunny@abc.com"
$smtpFrom = "process@abc.com"
$smtpTo = "administrator@abc.com"
$messageSubject = "Servers Memory"

$message = New-Object System.Net.Mail.MailMessage $smtpfrom, $smtpto
$message.Subject = $messageSubject
$message.IsBodyHTML = $true
$message.Body = Get-Content C:\Logs\output.txt

$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($message)

如果您无法在 HTML 中提供 output.txt,因为它是在纯文本中自动生成的,那么您的脚本将需要对其进行转换。如果格式与您的示例中显示的一致,那并不太复杂。将$message.Body = 行替换为:

$body = Get-Content C:\Logs\output.txt | Out-String
$body = $body -replace '^(\S+)\s+(\S+)\s+(\S+)', '<tr><th style = "border: 1px solid black; background: #dddddd; padding: 5px;">$1</th><th style = "border: 1px solid black; background: #dddddd; padding: 5px;">$2</th><th style = "border: 1px solid black; background: #dddddd; padding: 5px;">$3</th></tr>'
$body = $body -replace '\n(\S+)\s+(\S+)\s+(\S+)', '<tr><td style = "border: 1px solid black; padding: 5px;">$1</td><td style = "border: 1px solid black; padding: 5px;">$2</td><td style = "border: 1px solid black; padding: 5px;">$3</td></tr>'
$body = '<body><table style = "border: 1px solid black; border-collapse: collapse;">' + $body + '</table></body>'
$message.Body = $body

【讨论】:

  • & output.txt 将始终为纯文本格式..因为它是通过批处理脚本生成的..我无法更改..:)跨度>
  • 尽管如此,但这并不能改变这样一个事实,即如果您不提供 HTML 输入,您将无法获得 HTML 输出(您知道……GIGO 原则)。 IsBodyHTML 属性所做的只是将 Content-Type 标头设置为text/html,它指示客户端将正文解释为 HTML。您在更新中发布的结果正是我所描述的通过将 output.txt 呈现为 HTML 获得的结果——没有换行符,并且空白减少为单个空格。如果您无法更改生成 output.txt 的脚本,则必须让 PowerShell 脚本将其转换为 HTML。
  • 实际上,我发现您无法可靠地在电子邮件中包含样式表。样式必须是内联的,否则大多数客户端会忽略它们。