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.
- First, it retrieves some data from
dbGetQuery
, but since it isn't stored anywhere, it is immediately lost. - Then it creates a local variable named
extensions
and assigned the value"Buttons"
. - Last, it creates a local variable named
options
that islist(..)
.
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:
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 rundbGetQuery
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) )
)
}
})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 asmydata <- 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")
)
)
)
```
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
Remove Spacing Around Plotting Area in R
Differences in Heatmap/Clustering Defaults in R (Heatplot Versus Heatmap.2)
How to Replicate a Ddply Behavior That Uses a Custom Function with Dplyr
Adding Custom Image to Geom_Polygon Fill in Ggplot
How to Save a Data Frame as CSV to a User Selected Location Using Tcltk
Avoid Rbind()/Cbind() Conversion from Numeric to Factor
R - Common Title and Legend for Combined Plots
What Is a Fast Way to Set Debugging Code at a Given Line in a Function
Plot a Legend and Well-Spaced Universal Y-Axis and Main Titles in Grid.Arrange
Methods for Doing Heatmaps, Level/Contour Plots, and Hexagonal Binning
Compare If Two Dataframe Objects in R Are Equal
Creating a Pareto Chart with Ggplot2 and R
How to Change the Background Color of the Shiny Dashboard Body
How to Check If a Sequence of Numbers Is Monotonically Increasing (Or Decreasing)
How to Create a Continuous Density Heatmap of 2D Scatter Data in R