【问题标题】:how do you convert a data frame to a table to send as an email body如何将数据框转换为表格以作为电子邮件正文发送
【发布时间】:2014-05-05 14:42:22
【问题描述】:

我有这个数据框:

library(sendmailR)
library(pander)

dput(s)
structure(list(Description = c("ServerA", "ServerB", "ServerC", 
"ServerD", "ServerE", "ServerF"), Value = c("2", "2", "100", 
"100", "80", "20")), .Names = c("Description", "Value"), row.names = c(NA, 
6L), class = "data.frame")

我想把这个数据框放在一个漂亮的表格中,然后通过电子邮件发送给一些人。

我用 pandoc 试过,但表格看起来很简单:

 t<-pandoc.table.return(s, caption="Server CPU Utilization")

    from <- "user@example.com"
    to <- c("end_users@example.com")
    subject <- paste(Sys.time()," Servers CPU utilization")
    body <- t                
    mailControl=list(smtpServer="mailhost.example.net")

    sendmail(from=from,to=to,subject=subject,msg=body,control=mailControl)

还有其他方法可以将数据框格式化为漂亮的表格以作为电子邮件发送吗?表格必须在电子邮件正文中,而不是作为附件。

【问题讨论】:

    标签: r pander sendmailr


    【解决方案1】:

    下面是什么意思?

    桌子看起来很朴素

    如果您不喜欢默认的multiline format,您还可以为表格选择其他一些降价格式,例如将style = 'grid' 传递给pandoc.table.return。或者你的意思是桌子分崩离析/用非等宽字体看起来很丑?结果将取决于电子邮件客户端,因此我宁愿选择发送 HTML 邮件并指定等宽字体系列,或者以 HTML 呈现表格。


    HTML 版本的快速演示:

    1. 初始化所需的 R 包:

      library(sendmailR)
      library(xtable)
      
    2. 通过将静态部分与动态创建的 HTML 表连接起来构建 HTML 正文:

      msg <- mime_part(paste('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
      Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
      </head>
      <body>', print(xtable(s), type = 'html'), ',</body>
      </html>'))
      
    3. undocumented hack 覆盖content-type

      msg[["headers"]][["Content-Type"]] <- "text/html"
      
    4. 使用给定的主题将邮件发送给您指定的收件人:

      from    <- '<foo@example.com>'
      to      <- '<bar@example.com>'
      subject <- 'HTML table in the body'
      body    <- list(msg)
      sendmail(from, to, subject, body)
      

    结合 Markdown 和 HTML 版本:

    msg <- mime_part(paste('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
    Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    </head>
    <body><div style="font-family: monospace;">', gsub(' ', '&nbsp;', paste(pander.return(s, caption = "Server CPU Utilization", style = 'grid'), collapse = '<br>')), '</div></body>
    </html>'))
    msg[["headers"]][["Content-Type"]] <- "text/html"
    sendmail(from, to, subject, list(msg))
    

    这里的技巧是使用内联 CSS 将 font-family 设置为 monospace,同时用不间断空格替换文档中的所有空格。另一个(而且更优雅)的解决方法可能是将降价放在pre HTML 标签之间:

    msg <- mime_part(paste('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
    Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    </head>
    <body><pre>', paste(pander.return(s, caption = "Server CPU Utilization", style = 'grid'), collapse = '\n'), '</pre></body>
    </html>'))
    msg[["headers"]][["Content-Type"]] <- "text/html"
    sendmail(from, to, subject, list(msg))
    

    【讨论】:

    • 我执行了您在此处发布的确切代码。我收到此错误:wait_for(code) 中的错误:SMTP 错误:5.7.1 无法中继
    • @user1471980 您可能必须将一些自定义选项传递给control,就像您在原始示例中所做的那样:mailControl=list(smtpServer="mailhost.example.net") 作为sendmail 的进一步参数。错误信息与正文的内容或格式无关。
    • 我尝试在上面的 html 的 head 部分中使用 css 来格式化我的表格,由于某种原因,当我收到邮件时,表格看起来还是一样的。是否可以插入一些 css 用于表格格式并在您收到电子邮件时看到它。例如 tr 的背景颜色等。
    • @user1471980 电子邮件客户端倾向于忽略标题部分中的 CSS,您必须使用内联 CSS 样式为单元格着色。
    • 根据您提供的上述代码,这一行创建了表格:print(xtable(s), type = 'html')。你会如何放置内联样式?一个简单的例子真的会非常有用。
    【解决方案2】:

    如果 dput 是您的 data.frame。

    我用这个。

    Date=sys.Date()-1
    date2 <- paste("My subject of mail", Date, sep = " - ")
    setwd("/xyz")
    newdir <- paste("output", Sys.time(), sep = "_")
    dir.create(newdir)#, showWarnings = FALSE)
    setwd(newdir)
    
    ######
    mydoc = bsdoc( title = 'my document')
    options( "ReporteRs-fontsize" = 8 )
    mydoc = addParagraph(mydoc, value = "Hi All, \n\nPlease check attached summary.")
    mydoc = addParagraph(mydoc, value = "Summary:")
    MyFTable = FlexTable( data = dput, add.rownames = FALSE, header.cell.props = cellProperties( background.color = "#FAEBD7" )
                          , header.par.props = parProperties(text.align = "center" ))
    MyFTable = setColumnsColors( MyFTable, j=1, colors = '#F0F8FF' )
    MyFTable[ , ] = parProperties( text.align = 'center')
    MyFTable = setColumnsColors( MyFTable, j=ncol(dput), colors = '#F0F8FF' )
    mydoc = addFlexTable( mydoc, MyFTable )
    writeDoc( mydoc, file = "op2.html" )
    
    send.mail(from = "abc@xyz.com",
              to = c("abc@xyz.com"),
              subject = date2,
              body = "op2.html",
              html = TRUE,
              smtp = list(host.name = "smtp.gmail.com", port = 465, user.name = "abc@xyz.com", passwd = "xyz@123", ssl = TRUE),
              authenticate = TRUE,
              send = TRUE)
    

    但我正在寻找发送邮件的更好选择,例如邮件正文中的图像或格式良好/紧凑的图像。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-01
      • 2018-05-06
      • 1970-01-01
      • 2012-01-05
      相关资源
      最近更新 更多