如何解决Golang AWS SES xlsx 附件已损坏
在 golang 中,我试图发送一封附有 XLSX 文件的电子邮件。
我使用 github.com/tealeg/xlsx/v3
将 XLSX 文件生成为字节数组,并且在与这样的网络服务器(此处为 gin)一起使用时运行良好:
c.Header("Content-Description","File Transfer")
c.Header("Content-Type","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
c.Header("Content-disposition","attachment; filename="+time.Now().UTC().Format("daily-alerts-20060102.xlsx"))
c.Data(http.StatusOK,"application/octet-stream",fileContent)
但是,当使用 SES 发送时,虽然 CSV 文件可以正确提供,但 6ko XLSX 文件会变成 10ko XLSX 文件,并且无法使用 Excel 打开它:
func (s *EmailSenderParams) SendEmailWithAttachment(content string,data *models.RawEmailData,attachment []byte,attachmentFilename string) error {
sess,err := session.NewSession(&aws.Config{
Region: aws.String(s.awsRegion)},)
creds := credentials.NewStaticCredentials(s.apiID,s.apiKey,"")
// Create an SES session.
svc := ses.New(sess,&aws.Config{Credentials: creds})
// Assemble the email.
buf := new(bytes.Buffer)
writer := multipart.NewWriter(buf)
// email main header:
h := make(textproto.MIMEHeader)
//h.Set("From",source)
h.Set("To",data.ReceiverMail)
//h.Set("Return-Path",source)
h.Set("Subject",data.Subject)
h.Set("Content-Language","en-US")
h.Set("Content-Type","multipart/mixed; boundary=\""+writer.Boundary()+"\"")
h.Set("MIME-Version","1.0")
_,err = writer.CreatePart(h)
if err != nil {
return err
}
// body:
h = make(textproto.MIMEHeader)
h.Set("Content-transfer-encoding","7bit")
h.Set("Content-Type","text/plain; charset=us-ascii")
part,err := writer.CreatePart(h)
if err != nil {
return err
}
_,err = part.Write([]byte(content))
if err != nil {
return err
}
// file attachment:
h = make(textproto.MIMEHeader)
h.Set("Content-disposition","attachment; filename="+attachmentFilename)
h.Set("Content-Type","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; x-unix-mode=0644; name=\""+attachmentFilename+"\"")
h.Set("Content-transfer-encoding","7bit")
part,err = writer.CreatePart(h)
if err != nil {
return err
}
_,err = part.Write(attachment)
if err != nil {
return err
}
err = writer.Close()
if err != nil {
return err
}
// Strip boundary line before header (doesn't work with it present)
st := buf.String()
if strings.Count(st,"\n") < 2 {
return fmt.Errorf("invalid e-mail content")
}
st = strings.SplitN(st,"\n",2)[1]
raw := ses.RawMessage{
Data: []byte(st),}
input := &ses.SendRawEmailInput{
Destinations: []*string{aws.String(data.ReceiverMail)},Source: aws.String(s.senderEmail),RawMessage: &raw,}
// Attempt to send the email.
_,err = svc.SendRawEmail(input)
// display error messages if they occur.
if err != nil {
if aerr,ok := err.(awserr.Error); ok {
switch aerr.Code() {
case ses.ErrCodeMessageRejected:
logrus.Warnln(ses.ErrCodeMessageRejected,aerr.Error())
case ses.ErrCodeMailFromDomainNotVerifiedException:
logrus.Warnln(ses.ErrCodeMailFromDomainNotVerifiedException,aerr.Error())
case ses.ErrCodeConfigurationSetDoesNotExistException:
logrus.Warnln(ses.ErrCodeConfigurationSetDoesNotExistException,aerr.Error())
default:
logrus.Warnln(aerr.Error())
}
} else {
logrus.Warnln(err.Error())
}
logrus.Warnln(err)
return err
}
logrus.Infoln("SES Email Sent to " + data.ReceiverName + " at address: " + data.ReceiverMail)
return nil
}
我认为 MIMEHeaders、多部分或编码可能有问题,但我正在努力寻找什么。 您知道发送带有 AWS SES 附件的 XLSX 文件的电子邮件的任何成功方法吗?
解决方法
解决方案是对文件进行 base64 编码,并将 Content-Transfer-Encoding
标头设置为 base64
h.Set("Content-Transfer-Encoding","base64")
part,err = writer.CreatePart(h)
if err != nil {
return err
}
b := make([]byte,base64.StdEncoding.EncodedLen(len(attachment)))
base64.StdEncoding.Encode(b,attachment)
_,err = part.Write(b)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。