简体   繁体   English

Shiny DT:excel中的格式日期列,通过按钮扩展名

[英]Shiny DT: format date column in excel through Buttons extensions

I have a datatable with date column that shows UTC timezone. 我有一个数据表,其日期列显示UTC时区。 Using last development version of DT one can choose to convert date column to locale string and everything shows nicely in shiny webapp. 使用DT的最后一个开发版本,可以选择将日期列转换为语言环境字符串,一切都在闪亮的webapp中很好地显示。 However, if user will download the table through Buttons extension, the date column will be exported in the UTC time zone (and unreadable format) 但是,如果用户将通过按钮扩展名下载表,则日期列将以UTC时区(并且格式不可读)导出

library(DT)
library(shiny)

df <- data.frame(a = 1:100, b = 1:100, 
             d=seq(as.POSIXct("2017-08-23 10:00:00"), as.POSIXct("2017-11-30 10:00:00"), by = "days"))

ui <- fluidPage(
  dataTableOutput("table")
)

server <- function(input, output){

  output$table <- DT::renderDataTable({
    datatable(df, 
              extensions = c("Buttons"), 
              options = list(dom = 'Bfrtip',
                             buttons = list("csv",list(extend='excel',filename="DF"))
              )) %>% formatDate(3, "toLocaleString", params = list('fr-FR'))
  })

}

shinyApp(ui, server)

So if local OS time zone is +5, it will show "23/08/2017 à 10:00:00" in a shiny webapp, but "2017-08-23T05:00:00Z" in excel file. 因此,如果本地操作系统时区是+5,它将在闪亮的webapp中显示"23/08/2017 à 10:00:00" "2017-08-23T05:00:00Z" ,但在excel文件中显示"2017-08-23T05:00:00Z" Is there any possible way to format exports? 有什么方法可以格式化出口吗?

To achieve what you want, I propose two methods, both require you to transform the data set to the user's locale. 为了达到你想要的效果,我提出了两种方法,都要求你将数据集转换为用户的语言环境。

Using an input 使用输入

In the same view as the table, provide a shiny input, which allows user selection of the locale. 在与表相同的视图中,提供闪亮的输入,允许用户选择区域设置。 Use this value to transform the UTC entries. 使用此值转换UTC条目。

library(DT)
library(shiny)
library(dplyr)

ui <- fluidPage(
  selectInput(
    "timezone", "Timezone",
    choices = c("Europe/Paris", "America/Los_Angeles", "Australia/Sydney")
  ),
  DT::dataTableOutput("table")
)

server <- function(input, output, session){

  df <- data.frame(
    a = 1:100,
    b = 1:100, 
    d = seq(
      as.POSIXct("2017-08-23 10:00:00", tz = "UTC"),
      as.POSIXct("2017-11-30 10:00:00", tz = "UTC"),
      by = "days")
  )

  df_locale <- reactive({

    df %>%
      mutate(
        local = format(d, "%d %B %Y %I:%M:%S %p %Z", tz = input$timezone)
      )

  })

  output$table <- DT::renderDataTable({

    DT::datatable(
      df_locale(),
      extensions = 'Buttons',
      options = list(
        dom = 'Bfrtip',
        buttons = list("copy", "csv", list(extend = "excel", filename = "DF"))
      )
    ) %>%
    formatDate(3, "toLocaleString", params = list("fr-FR"))

  })

}

shinyApp(ui, server)

Automatically based on the client machine 自动基于客户端计算机

This is more involved and relies on the answer to this question. 这涉及更多,并依赖于这个问题的答案。

library(DT)
library(shiny)
library(dplyr)
library(lubridate)

ui <- fluidPage(

  HTML('<input type="text" id="client_time" name="client_time" style="display: none;"> '),
  HTML('<input type="text" id="client_time_zone_offset" name="client_time_zone_offset" style="display: none;"> '),
  tags$script('
  $(function() {
    var time_now = new Date()
    $("input#client_time").val(time_now.getTime())
    $("input#client_time_zone_offset").val(time_now.getTimezoneOffset())
  });    
  '),
  DT::dataTableOutput("table")
)

server <- function(input, output, session){

  df <- data.frame(
    a = 1:100,
    b = 1:100, 
    d = seq(
      as.POSIXct("2017-08-23 10:00:00", tz = "UTC"),
      as.POSIXct("2017-11-30 10:00:00", tz = "UTC"),
      by = "days")
  )

  client_time <- reactive({as.numeric(input$client_time) / 1000})
  time_zone_offset <- reactive({-as.numeric(input$client_time_zone_offset) * 60})

  df_locale <- reactive({

    df %>%
      mutate(
        local = format(d + seconds(time_zone_offset()), "%d %B %Y %I:%M:%S %p")
      )

  })  

  output$table <- DT::renderDataTable({

    DT::datatable(
      df_locale(),
      extensions = 'Buttons',
      options = list(
        dom = 'Bfrtip',
        buttons = list("copy", "csv", list(extend = "excel", filename = "DF"))
      )
    ) %>%
      formatDate(3, "toLocaleString", params = list("fr-FR"))

  })

}

shinyApp(ui, server)

NB While the advantage of the automated option is that no user interaction is required, I have not tried to determine the Olson Name location of the client and therefore not resolving the time zone beyond a time offset from UTC . 注意虽然自动选项的优点是不需要用户交互,但我没有尝试确定客户端的Olson Name位置,因此没有解决超出UTC时间偏移的时区。 There are likely options available to improve using alternate javascript . 有可能选择使用备用javascript来改进。

Update using download button 使用下载按钮更新

If you want to download something different to what is available in the DT::datatable via the Buttons extension, you have the option to use the standard downloadHandler and associated button. 如果您想通过Buttons扩展downloadHandlerDT::datatable可用内容不同的内容,您可以选择使用标准的downloadHandler和相关按钮。 In the code below I demonstrate how you can combine your original code to display the table and offer a csv download of the data transformed to suit the client time zone offset shown in the previous two approaches. 在下面的代码中,我将演示如何组合原始代码以显示表格,并提供转换后的数据的csv下载,以适应前两种方法中显示的客户端时区偏移。

library(DT)
library(shiny)
library(dplyr)
library(readr)
library(lubridate)

ui <- fluidPage(

  HTML('<input type="text" id="client_time" name="client_time" style="display: none;"> '),
  HTML('<input type="text" id="client_time_zone_offset" name="client_time_zone_offset" style="display: none;"> '),
  tags$script('
              $(function() {
              var time_now = new Date()
              $("input#client_time").val(time_now.getTime())
              $("input#client_time_zone_offset").val(time_now.getTimezoneOffset())
              });    
              '),
  downloadButton("download_data", "Get Data"),
  DT::dataTableOutput("table")
  )

server <- function(input, output, session){

  df <- data.frame(
    a = 1:100,
    b = 1:100, 
    d = seq(
      as.POSIXct("2017-08-23 10:00:00", tz = "UTC"),
      as.POSIXct("2017-11-30 10:00:00", tz = "UTC"),
      by = "days")
  )

  client_time <- reactive({as.numeric(input$client_time) / 1000})
  time_zone_offset <- reactive({-as.numeric(input$client_time_zone_offset) * 60})

  df_locale <- reactive({

    df %>%
      mutate(
        d = format(d + seconds(time_zone_offset()), "%d %B %Y %I:%M:%S %p")
      )

  })

  output$download_data <- downloadHandler(
    filename <- function() {
      paste0(format(Sys.Date(), "%Y%m%d"), "-data.csv")
    },
    content <- function(file) {
      write_csv(df_locale(), file)
    },
    contentType = "text/csv"
  )

  output$table <- DT::renderDataTable({

    DT::datatable(df) %>%
      formatDate(3, "toLocaleString")

  })

}

shinyApp(ui, server)

The Buttons extention for DT does not currently have the ability to be customised with R. Changing the behaviour may be possible with javascript , you can read here about the API. DT按钮扩展目前无法使用R进行自定义。使用javascript可以更改行为,您可以在此处阅读有关API的信息。

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

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