如何在PowerShell邮件中嵌入基于变量数据的饼图?
实现PowerShell生成饼图并嵌入邮件的方案
方法一:用.NET绘图类生成饼图并转Base64嵌入HTML
这种方案不依赖外部服务,直接在PowerShell内生成饼图,转Base64编码后嵌入邮件正文,兼容性更强。
完整代码示例
# 定义统计数据 $pass = 20 $fail = 5 $reject = 2 # 准备饼图的基础配置 $chartData = @($pass, $fail, $reject) $chartLabels = @("Pass", "Fail", "Reject") $chartColors = @("#2ecc71", "#e74c3c", "#f39c12") # 对应成功、失败、驳回的配色 $width = 300 $height = 300 # 加载绘图类库并生成饼图 Add-Type -AssemblyName System.Drawing $bitmap = New-Object System.Drawing.Bitmap($width, $height) $graphics = [System.Drawing.Graphics]::FromImage($bitmap) $graphics.Clear([System.Drawing.Color]::White) # 计算各数据块的角度并绘制饼图 $total = $chartData | Measure-Object -Sum | Select-Object -ExpandProperty Sum $startAngle = 0 for ($i=0; $i -lt $chartData.Count; $i++) { $sliceAngle = [math]::Round(($chartData[$i] / $total) * 360) $brush = New-Object System.Drawing.SolidBrush($chartColors[$i]) $graphics.FillPie($brush, 10, 10, $width-20, $height-20, $startAngle, $sliceAngle) $startAngle += $sliceAngle } # 添加图例 $legendY = 250 for ($i=0; $i -lt $chartLabels.Count; $i++) { $brush = New-Object System.Drawing.SolidBrush($chartColors[$i]) $graphics.FillRectangle($brush, 20, $legendY, 20, 15) $graphics.DrawString("$($chartLabels[$i]) ($($chartData[$i]))", (New-Object System.Drawing.Font("Arial", 10)), [System.Drawing.Brushes]::Black, 50, $legendY) $legendY += 25 } # 将图片转为Base64编码 $memoryStream = New-Object System.IO.MemoryStream $bitmap.Save($memoryStream, [System.Drawing.Imaging.ImageFormat]::Png) $base64Image = [Convert]::ToBase64String($memoryStream.ToArray()) # 释放资源 $memoryStream.Dispose() $bitmap.Dispose() $graphics.Dispose() # 构建HTML邮件正文(包含表格和饼图) $Body = @" <html> <body> <h3>测试结果统计</h3> <table border="2"> <tr><th>状态</th><th>数量</th></tr> <tr><th>Pass</th><td>$pass</td></tr> <tr><th>Fail</th><td>$fail</td></tr> <tr><th>Reject</th><td>$reject</td></tr> </table> <br> <h3>结果分布饼图</h3> <img src="data:image/png;base64,$base64Image" alt="测试结果饼图"> </body> </html> "@ # 发送邮件(需替换为你的SMTP配置) $EmailFrom = "your-email@example.com" $EmailTo = "recipient@example.com" $Subject = "测试结果统计报告" $SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom, $EmailTo, $Subject, $Body) $SMTPMessage.IsBodyHtml = $true # 必须开启HTML格式 $SMTPClient = New-Object System.Net.Mail.SmtpClient("smtp.example.com", 587) $SMTPClient.Credentials = New-Object System.Net.NetworkCredential("your-email@example.com", "your-password") $SMTPClient.EnableSsl = $true $SMTPClient.Send($SMTPMessage)
代码说明
- 利用
System.Drawing类库直接绘制饼图,自定义尺寸、颜色和图例 - 将图片转为Base64编码嵌入HTML,无需外部图片链接
- 强制邮件正文为HTML格式,确保表格和饼图正常显示
方法二:用内嵌SVG绘制饼图(纯HTML方案)
如果不想依赖.NET绘图类,可直接用SVG代码绘制饼图,无需生成图片文件,兼容性较好。
代码片段(替换邮件正文部分)
# 计算各数据块的角度 $total = $pass + $fail + $reject $passAngle = ($pass / $total) * 360 $failAngle = ($fail / $total) * 360 $rejectAngle = ($reject / $total) * 360 # 构建SVG饼图代码 $svgPie = @" <svg width="300" height="300" viewBox="0 0 300 300"> <!-- Pass 区块 --> <path d="M150,150 L150,0 A150,150 0 0,1 $([math]::Round(150 + 150*[math]::Cos($passAngle*[math]::Pi/180))) $([math]::Round(150 + 150*[math]::Sin($passAngle*[math]::Pi/180))) Z" fill="#2ecc71"/> <!-- Fail 区块 --> <path d="M150,150 L$([math]::Round(150 + 150*[math]::Cos($passAngle*[math]::Pi/180))) $([math]::Round(150 + 150*[math]::Sin($passAngle*[math]::Pi/180))) A150,150 0 0,1 $([math]::Round(150 + 150*[math]::Cos(($passAngle+$failAngle)*[math]::Pi/180))) $([math]::Round(150 + 150*[math]::Sin(($passAngle+$failAngle)*[math]::Pi/180))) Z" fill="#e74c3c"/> <!-- Reject 区块 --> <path d="M150,150 L$([math]::Round(150 + 150*[math]::Cos(($passAngle+$failAngle)*[math]::Pi/180))) $([math]::Round(150 + 150*[math]::Sin(($passAngle+$failAngle)*[math]::Pi/180))) A150,150 0 0,1 150,0 Z" fill="#f39c12"/> <!-- 图例 --> <rect x="20" y="250" width="20" height="15" fill="#2ecc71"/> <text x="50" y="262" font-family="Arial" font-size="12">Pass ($pass)</text> <rect x="120" y="250" width="20" height="15" fill="#e74c3c"/> <text x="150" y="262" font-family="Arial" font-size="12">Fail ($fail)</text> <rect x="220" y="250" width="20" height="15" fill="#f39c12"/> <text x="250" y="262" font-family="Arial" font-size="12">Reject ($reject)</text> </svg> "@ # 构建邮件正文 $Body = @" <html> <body> <h3>测试结果统计</h3> <table border="2"> <tr><th>状态</th><th>数量</th></tr> <tr><th>Pass</th><td>$pass</td></tr> <tr><th>Fail</th><td>$fail</td></tr> <tr><th>Reject</th><td>$reject</td></tr> </table> <br> <h3>结果分布饼图</h3> $svgPie </body> </html> "@
说明
- 纯SVG代码绘制饼图,无需生成和处理图片文件
- 通过计算角度和路径坐标实现数据可视化
- 主流邮件客户端均支持SVG显示,兼容性良好
内容的提问来源于stack exchange,提问作者Kasi Raman
相关产品推荐
相关产品推荐

