Add Download Buttons in Dt::Renderdatatable

Add download buttons in DT::renderDataTable

As Stephan said in comment, the way to add buttons is the following:

output$mytable1  <- DT::renderDataTable(
DT::datatable(
{ plots.dfs()[[1]] },

extensions = 'Buttons',

options = list(
paging = TRUE,
searching = TRUE,
fixedColumns = TRUE,
autoWidth = TRUE,
ordering = TRUE,
dom = 'tB',
buttons = c('copy', 'csv', 'excel')
),

class = "display"
))

Adjust place of downloading buttons of a DT table in Shiny

You can do dom = 'l<"sep">Bfrtip' and this will add a div between l and B having class sep. Then in your shiny app define the CSS for the sep class:

.sep {
width: 20px;
height: 1px;
float: left;
}

You can set this CSS in the Shiny UI as below:

tags$head(
tags$style(HTML("
.sep {
width: 20px;
height: 1px;
float: left;
}
"))
)

How to have a single download button for all datatables in R shiny webpage

(a) If you only want "one downloadButton visible in the header common to all pages that downloads the table in the active page or tab", it needs firstly to know the active page and tab based on the page / tab IDs. (b) If you only need a single button to download all the tables, you can download them into a .xlsx file (see download data onto multiple sheets from shiny). (c)If you need a button for each tab, place the button in each tab and you can simply save table as .csv.
Here is the code for situation (a).

library(shiny)
library(shinydashboard)
library(DT)

ui <- dashboardPage(
dashboardHeader(title = "Header",
dropdownMenuOutput("updatedTimeOutput"),
dropdownMenu(type = "notifications",
badgeStatus = "warning",
icon = icon("bullhorn", "fa-lg"),
notificationItem(icon = icon("bullhorn", "fa-1x"),
status = "info",
text = tags$span(
tags$b("Please notice!")
)
))),
dashboardSidebar( sidebarMenu(id = "pages", # use unique id for pages
menuItem("Page1", tabName = "page1"),
menuItem("Page2", tabName = "page2"))),
dashboardBody(

# Add download button
downloadButton('downloadData', 'Download Table',
style="font-weight:bold;"
),
helpText(
hr(style = "border-top: 1px solid #000000;"),
),

tabItems(
tabItem(
tabName = "page1",

tabsetPanel(id="tabs",

tabPanel("tab1",

column(12,
DT::dataTableOutput("table1")
)),

tabPanel( "tab2",

column(12,
DT::dataTableOutput("table2")
))
)
)
,
tabItem(
tabName = "page2",
fluidRow(
column(12,
DT::dataTableOutput("table3")
))
)
)
)
)

server <- function(input, output) {

# table1
tbl1 <- mtcars[1:30, ] # tables 1, 2, 3 use different rows of mtcars to differentiate tables

output$table1 <- DT::renderDataTable({
datatable( tbl1,
# options = DToptions, # no such object called "DToptions"
extensions = 'Buttons',
rownames = TRUE,
selection = 'none'
)
})


# table2
tbl2 <- mtcars[5:45, ]

output$table2 <- DT::renderDataTable({
datatable( tbl2,
# options = DToptions,
extensions = 'Buttons',
rownames = TRUE,
selection = 'none'
)
})

# table3
tbl3 <- mtcars[11:35, ]

output$table3 <- DT::renderDataTable({
datatable( tbl3,
# options = DToptions,
extensions = 'Buttons',
rownames = TRUE,
selection = 'none'
)
})


page_name <- reactive({
input$pages
})

# select table on the active page / tab
selected_table <- reactive({
if(page_name() == "page1"){
tbl.list <- list("tab1" = tbl1, "tab2" = tbl2)
select_tbl <- tbl.list[input$tabs]
}else{
select_tbl <- tbl3
}
return(select_tbl)
})

# download table
output$downloadData <- downloadHandler(
filename = function() {"table.csv"},
content = function(file) {write.csv(selected_table(), file, row.names=TRUE)}
)
}

shinyApp(ui, server)

Button extension to download all data or only visible data

See this answer: Buttons: download button with scroller downloads only few rows

Whether the buttons export all data or only visible data is determined by the server argument in the DT::renderDT function call. If server=FALSE then the buttons will export all data in the table, while if server=TRUE they will only export visible data.

You could set the server argument with a variable to make this a selectable option.

output$table <- DT::renderDT(server = input$download_all, {
DT::datatable( ... )
}

The other option you might want to look at is the exportOptions: modifier: selected option that determines whether to download only selected rows (the default) or all rows. You can read about that option here: https://datatables.net/extensions/buttons/examples/print/select.html

Note that your users might run into performance and memory issues using server=FALSE if your data table is very large.

Shiny DT unable to add buttons to download as csv/excel

Your first argument to renderDataTable is indeed an expression, as it should be, but ... your expression is not doing much.

  1. First, it retrieves some data from dbGetQuery, but since it isn't stored anywhere, it is immediately lost.
  2. Then it creates a local variable named extensions and assigned the value "Buttons".
  3. Last, it creates a local variable named options that is list(..).

Since the default behavior in R is for an expression with { ... } is for it to "return" the last expression within it, that means that it doesn't return the value from dbGetQuery, it doesn't return extensions, it instead returns the value of options, which is not 2-dimensional.

Perhaps you meant:

  observeEvent(input$executeSQL, {
if (input$selection == "CL7D") {
output$mytable = DT::renderDataTable( # remove the '{'
dbGetQuery(conn, "select * from dummy"), # add a ','
extensions = "Buttons", # add a ','
options = list(paging = TRUE,
scrollX=TRUE,
searching = TRUE,
ordering = TRUE,
dom = 'Bfrtip',
buttons = c('copy', 'csv', 'excel', 'pdf'),
pageLength=5,
lengthMenu=c(3,5,10) )
) # remove the '}'
}

})

Side notes:

  1. I tend to prefer to keep data-creating/querying actions as simple reactive components that then may be used elsewhere. For example, let's say you wanted a banner at top of your shiny app to display the number of rows returned. With your current code, you would need to run dbGetQuery twice.

    Instead, make it reactive and then use it later; that way, if you need to use the data for any other component in your shiny app, you'll have it available separately.

      mydata <- eventReactive(input$executeSQL, {
    dbGetQuery(conn, "select * from dummy")
    })
    observeEvent(mydata(), {
    if (input$selection == "CL7D") {
    output$mytable = DT::renderDataTable(
    mydata(),
    extensions = "Buttons",
    options = list(paging = TRUE,
    scrollX=TRUE,
    searching = TRUE,
    ordering = TRUE,
    dom = 'Bfrtip',
    buttons = c('copy', 'csv', 'excel', 'pdf'),
    pageLength=5,
    lengthMenu=c(3,5,10) )
    )
    }

    })
  2. I've yet to see one working example of shiny where having a reactive component nested within another made sense. I have not tested your code here (lacking data and ui and such), but I suspect that your code would operate better, more-cleanly as

      mydata <- eventReactive(input$executeSQL, {
    dbGetQuery(conn, "select * from dummy")
    })
    output$mytable <- DT::renderDataTable(
    if (input$selection == "CL7D") mydata(),
    extensions = "Buttons",
    options = list(paging = TRUE,
    scrollX=TRUE,
    searching = TRUE,
    ordering = TRUE,
    dom = 'Bfrtip',
    buttons = c('copy', 'csv', 'excel', 'pdf'),
    pageLength=5,
    lengthMenu=c(3,5,10) )
    )

    If that doesn't work, move the if conditional out,

      mydata <- eventReactive(input$executeSQL, {
    dbGetQuery(conn, "select * from dummy")
    })
    data_CL7D <- reactive({
    if (input$selection == "CL7D") mydata()
    })
    output$mytable <- DT::renderDataTable(
    data_CL7D(),
    extensions = "Buttons",
    options = list(paging = TRUE,
    scrollX=TRUE,
    searching = TRUE,
    ordering = TRUE,
    dom = 'Bfrtip',
    buttons = c('copy', 'csv', 'excel', 'pdf'),
    pageLength=5,
    lengthMenu=c(3,5,10) )
    )

DT::datatable download buttons download only the -visible in app- part of the data

ok server=F makes it

renderDT(server=FALSE,{
# Load data
data <- mtcars
# Show data
datatable(data, extensions = 'Buttons',
options = list(scrollX=TRUE, lengthMenu = c(5,10,15),
paging = TRUE, searching = TRUE,
fixedColumns = TRUE, autoWidth = TRUE,
ordering = TRUE, dom = 'tB',
buttons = c('copy', 'csv', 'excel','pdf')))
})

Rmarkdown Download data with download button for that row

Here is a way with the downloadthis package.

---
title: "DT download row"
author: "Stéphane Laurent"
date: "21/03/2022"
output: html_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(DT)
library(downloadthis)
htmltools::tagList( # for the icons
rmarkdown::html_dependency_font_awesome()
)
```

```{r}
dat <- mtcars
dat[["Download"]] <- vapply(1L:nrow(mtcars), function(i){
as.character(
download_this(
.data = mtcars[i, ],
output_name = paste0("mtcars - row ", i),
output_extension = ".csv",
button_label = "Download",
button_type = "primary",
icon = "fa fa-save",
csv2 = FALSE,
self_contained = TRUE
)
)
}, character(1L))
```

```{r}
datatable(
dat,
escape = FALSE,
options = list(
columnDefs = list(
list(targets = ncol(dat), orderable = FALSE),
list(targets = "_all", className = "dt-center")
)
)
)
```

Sample Image

Of course that won't work if you edit the table.

R Shiny DT datatable change buttons export encoding

Try this:

buttons = list(
"copy",
"excel",
list(
extend = "csv",
charset = "utf-8",
bom = TRUE
)
)

Now, is the CSV export ok?

DT Package: DataTable Download CSV Button Not Working

Some times strange errors start showing up. While restarting R and/or Rstudio will work in many instances, sometimes you may need to re-install R-Studio or upgrade the RStudio version. My Rstudio stopped displaying plotly outputs a few months ago. Once I upgraded the RStudio version, it started working again.



Related Topics



Leave a reply



Submit