简体   繁体   English

发送 email 附件 - 将 CSV 文件转换为字节删除换行符

[英]Sending email attachment - Converting CSV file to bytes removes line breaks

I'm trying to use the MS Graph cmdlet Send-MgUserMail to send an email and include a CSV attachment.我正在尝试使用 MS Graph cmdlet Send-MgUserMail发送一个 email 并包含一个 CSV 附件。

If I do it like this, it works fine, and the attachment is fine.如果我这样做,效果很好,附件也很好。

Sample CSV attachment样本CSV附件

"App","AppId","Date","User"
"App1","43a9087d-8551-47d5-9869-3287736ce7c3","2023/01/26","me@email.com"
"App2","f33750cd-c79b-43be-8e55-ee14d163e2b3","2024/01/26","me@email.com"

Working code工作代码

$attachment   = "C:\Users\Me\Downloads\SampleFile.csv"
$base64string = [Convert]::ToBase64String([IO.File]::ReadAllBytes($attachment))

$params = @{
    UserId = "me@email.com"
    BodyParameter = @{
        Message = @{
            Subject = "Test Email"
            Body    = @{
                ContentType = "Html"
                Content     = "This is sample text."
            }
            ToRecipients = @(
                @{
                    EmailAddress = @{
                        Address = "toAddress@email.com"
                    }
                }
            )
            Attachments = @(
                @{
                    "@odata.type" = "#microsoft.graph.fileAttachment"
                    Name         = "SampleFile.csv"
                    ContentType  = "text/csv"
                    ContentBytes = $base64string
                }
            )
        }
        SaveToSentItems = "false"
    }
}
 
Send-MgUserMail @params

Objective客观的

What I would like is to attach the CSV, without having an actual saved file.我想要的是附加 CSV,但没有实际保存的文件。 The content would be from memory, like so.内容将来自 memory,像这样。

$output = @(
    [PSCustomObject] @{
        App = "App1"
        AppId = "43a9087d-8551-47d5-9869-3287736ce7c3"
        Date  = "2023/01/26"
        User  = "me@email.com"
    },
    [PSCustomObject] @{
        App = "App2"
        AppId = "f33750cd-c79b-43be-8e55-ee14d163e2b3"
        Date  = "2024/01/26"
        User  = "me@email.com"
    }
)

$attachment = $output | ConvertTo-Csv -NoTypeInformation

$bytes         = [System.Text.Encoding]::UTF8.GetBytes($attachment)
$base64string  = [Convert]::ToBase64String($bytes)

My issue when I do this is the CSV content is entirely on 1 line, there's no more line breaks.当我这样做时,我的问题是 CSV 内容完全在 1 行上,没有更多的换行符。

Issue Sample CSV Output发行样品 CSV Output

"App","AppId","Date","User" "App1","43a9087d-8551-47d5-9869-3287736ce7c3","2023/01/26","me@email.com" "App2","f33750cd-c79b-43be-8e55-ee14d163e2b3","2024/01/26","me@email.com"

How can I convert this properly?我怎样才能正确转换它?

Answer was given in comments but to give it closure, what happens is that ConvertTo-Csv outputs an array of strings and they don't have new line characters (CRLF in Windows, LF in Linux), before getting the bytes of your Csv you need to convert this array into a single multi-line string, for this you can use Out-String :评论中给出了答案,但要关闭它,在获取 Csv 的字节之前, ConvertTo-Csv会输出一个字符串数组并且它们没有换行符(Windows 中的 CRLF,Linux 中的 LF)需要将此数组转换为单个多行字符串,为此您可以使用Out-String

$attachment = $output | ConvertTo-Csv -NoTypeInformation | Out-String

Or join them by a new line character to preserve the structure:或者通过换行符加入它们以保留结构:

$attachment = ($output | ConvertTo-Csv -NoTypeInformation) -join [Environment]::NewLine

Also, [System.Text.Encoding]::UTF8.GetBytes(...) which has a string type argument is coercing your array into a string and when you coerce an array into a string in PowerShell, it is joined by $OFS (a white space character by default) hence why you get a single line joined by whitespaces when decoding the base64 string.此外,具有字符串类型参数的[System.Text.Encoding]::UTF8.GetBytes(...)将您的数组强制转换为字符串,当您将数组强制转换为 PowerShell 中的字符串时,它由$OFS加入(默认情况下是一个空白字符)因此,为什么在解码 base64 字符串时会得到一行由空白字符连接的原因。


Another way this could've been done is by assigning $OFS the value of a new line character:另一种可以做到这一点的方法是为$OFS分配换行符的值:

$attachment = $output | ConvertTo-Csv -NoTypeInformation
$OFS = [System.Environment]::NewLine
$bytes         = [System.Text.Encoding]::UTF8.GetBytes($attachment)
$base64string  = [Convert]::ToBase64String($bytes)
$OFS = ' '

# Decoding should look as expected
[System.Text.Encoding]::UTF8.GetString(
    [Convert]::FromBase64String($base64string)
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM