Golang邮件模板正文格式不正确问题如何解决
Golang邮件模板正文格式不正确问题如何解决 大家好,
我编写了这段使用模板发送邮件的Go代码,以便将来如果需要添加更多变量或让他人查看时,只需修改模板即可,这样会更方便。
package main
import (
"bytes"
"strings"
"text/template"
"net/smtp"
"log"
)
type Email_struct struct {
Status string
App string
Project string
TargetEnv string
AppVersion string
Url string
}
func SendmaiL(emailTo string, e Email_struct) bool {
from := "noreply@domain.com"
to := []string{
emailTo,
}
var tmplFile = "email.tmpl"
tmpl, err := template.New(tmplFile).ParseFiles(tmplFile)
if err != nil {
panic(err)
}
var tpl bytes.Buffer
if err := tmpl.Execute(&tpl, e); err != nil {
panic(err)
}
message := tpl.Bytes()
log.Print(string(message[:])) // print
// Sending email.
errs := smtp.SendMail("mail.domain.com:25", nil, from, to, message)
if errs != nil {
log.Println(errs)
return false
}
return true
}
func main() {
// nl := "\r"
em := Email_struct{}
em.Status = "Synced"
app := "pipeline-gitops-notification-sit"
em.App = app
// em.Project = app + nl
em.Project = app
GitopsFolder := "gitops/sit"
extractTargetEnv := strings.Split(GitopsFolder, "/")
// em.TargetEnv = extractTargetEnv[1] + nl
em.TargetEnv = extractTargetEnv[1]
mes := "Manifest-63db30e: qa-0.0.110 by user@domain.com"
extractVersion1 := strings.Split(mes, "-")
extractVersion2 := strings.Split(extractVersion1[2], ".")
extractVersion3 := strings.Split(extractVersion2[2], " ")
// em.AppVersion = extractVersion2[0]+"."+extractVersion2[1]+"."+extractVersion3[0] + nl
em.AppVersion = extractVersion2[0]+"."+extractVersion2[1]+"."+extractVersion3[0]
RepoUrl := "https://cd.toronto.ca:6443/devops/pipeline/gitops-notification.git"
em.Url = RepoUrl
success := SendmaiL("user@domain.com", em)
if success {
log.Println("Email SUCCESS to sent!")
} else {
log.Println("Email FAILED to send!")
}
}
使用一个模板文件 email.tmpl,
Subject: [{{ .Status }}] app {{ .App }} has been synced by argoCD
Project: {{ .Project }}
Target : {{ .TargetEnv }}
Version: {{ .AppVersion }}
URL: {{ .Url }}
Best regards,
Devops Team
期望的邮件正文应该是(主题没问题),
Project: PPPPPPPPPPPPPPPPP
Target : TTTTTTTTTTTTTTTTT
Version: VVVVVVVVVVVVVVVVV
URL: UUUUUUUUUUUUUUUUUUUU
Best regards,
Devops Team
但它却变成了一行,
Project: PPPPPPPPPPPPPPPPP Target : TTTTTTTTTTTTTTTTT Version: VVVVVVVVVVVVVVVVV URL: UUUUUUUUUUUUUUUUUUUU
Best regards,
Devops Team
如果我启用 nl := “\r” 或 nl := “\n” 甚至两者都用。输出会是,
Project: PPPPPPPPPPPPPPPPP
Target : TTTTTTTTTTTTTTTTT
Version: VVVVVVVVVVVVVVVVV
URL: UUUUUUUUUUUUUUUUUUUU
Best regards,
Devops Team
这样看起来不美观。
请帮忙。
谢谢, Ric
更多关于Golang邮件模板正文格式不正确问题如何解决的实战教程也可以访问 https://www.itying.com/category-94-b0.html
Ricky_V:
Project: PPPPPPPPPPPPPPPPP Target : TTTTTTTTTTTTTTTTT Version: VVVVVVVVVVVVVVVVV URL: UUUUUUUUUUUUUUUUUUUU Best regards, Devops Team
实际上这工作得很好,只是在我实际使用时,目标是“Target Env”,但当我把它写成“Target-Env”时,它就能正常工作了。
问题出在模板文件中的换行符被 text/template 解析时处理掉了。text/template 默认会去除模板标签周围的空白字符,导致换行丢失。
以下是解决方案:
方案1:在模板中使用显式换行符
修改模板文件,在每行末尾添加 {{"\n"}}:
Subject: [{{ .Status }}] app {{ .App }} has been synced by argoCD
Project: {{ .Project }}{{"\n"}}
Target : {{ .TargetEnv }}{{"\n"}}
Version: {{ .AppVersion }}{{"\n"}}
URL: {{ .Url }}{{"\n"}}
Best regards,
Devops Team
方案2:使用 template 包的 {{- 和 -}} 语法控制空白
修改模板文件,在模板标签前后添加空白控制符:
Subject: [{{ .Status }}] app {{ .App }} has been synced by argoCD
Project: {{ .Project -}}
Target : {{ .TargetEnv -}}
Version: {{ .AppVersion -}}
URL: {{ .Url -}}
Best regards,
Devops Team
方案3:在代码中处理换行 保持模板文件不变,在结构体字段值中直接包含换行符:
em.Project = app + "\n"
em.TargetEnv = extractTargetEnv[1] + "\n"
em.AppVersion = extractVersion2[0]+"."+extractVersion2[1]+"."+extractVersion3[0] + "\n"
方案4:使用 HTML 模板
如果需要更复杂的格式控制,可以使用 html/template:
package main
import (
"bytes"
"html/template"
"net/smtp"
"log"
)
// ... 其他代码保持不变 ...
func SendmaiL(emailTo string, e Email_struct) bool {
// ... 前面的代码保持不变 ...
var tmplFile = "email.html.tmpl"
tmpl, err := template.New(tmplFile).ParseFiles(tmplFile)
if err != nil {
panic(err)
}
// ... 后面的代码保持不变 ...
}
创建 email.html.tmpl 文件:
Subject: [{{ .Status }}] app {{ .App }} has been synced by argoCD
<p>Project: {{ .Project }}</p>
<p>Target : {{ .TargetEnv }}</p>
<p>Version: {{ .AppVersion }}</p>
<p>URL: {{ .Url }}</p>
<p>Best regards,<br>
Devops Team</p>
方案5:使用原始字符串模板 在代码中直接定义模板字符串:
func SendmaiL(emailTo string, e Email_struct) bool {
// ... 前面的代码保持不变 ...
tmplStr := `Subject: [{{ .Status }}] app {{ .App }} has been synced by argoCD
Project: {{ .Project }}
Target : {{ .TargetEnv }}
Version: {{ .AppVersion }}
URL: {{ .Url }}
Best regards,
Devops Team`
tmpl, err := template.New("email").Parse(tmplStr)
if err != nil {
panic(err)
}
// ... 后面的代码保持不变 ...
}
推荐使用方案1或方案5,这两种方法能保持模板的清晰性和可维护性。方案1通过 {{"\n"}} 显式添加换行符,方案5将模板内嵌在代码中,避免了外部文件依赖。


