In my shiny app, I'm using:
# server.R
output$out_table = DT::renderDataTable(
func_to_creat_dataframe(),
rownames= FALSE,
extensions = c('Buttons'),
options = list(
pageLength = 96,
lengthMenu = c(96, 384, 1536),
dom = 'Blfrtip',
buttons = c('copy', 'csv', 'excel', 'pdf', 'print')
)
)
# UI.R
DT::dataTableOutput('out_table')
...and when I use the "Excel" button to export the table, the exported table has a "title" row directly above the header row. This title row consists of one merged cell that spans across the entire header. How do I remove this? This title row interferes with downstream processing of the file, and it's completely unnecessary, so I don't see why it appears to be default for the datatable file export buttons.
Try that:
DT::datatable(
iris,
rownames= FALSE,
extensions = c('Buttons'),
options = list(
pageLength = 96,
lengthMenu = c(96, 384, 1536),
dom = 'Blfrtip',
buttons = list(
'copy',
'csv',
list(extend = 'excel', title = NULL),
'pdf',
'print'
)
)
)
Related
I am using the button colvis from the DT package to select which columns I would like to show in the table. Here you have more info about the button colvis.
It works perfectly fine, it hides the columns that I don't want to select and the result is shown to the user.
However, it seems that this info is not updated when I download the file.
If I only select "Petal.Width" and "Species":
Then, I download the file... and I open it. I still have all the columns and not the selected ones.
I have been trying to find a solution, but I haven't found anything.
Does anyone know how to fix it?
Thanks in advance.
Here is my code:
library(shiny)
library(DT)
ui <- fluidPage(
dataTableOutput("table")
)
server <- function(input, output, session) {
output$table <- renderDataTable({
datatable(
iris,
filter = list(position = 'top', clear = FALSE),
selection = "none", #this is to avoid select rows if you click on the rows
rownames = FALSE,
extensions = 'Buttons',
options = list(
scrollX = TRUE,
dom = 'Blrtip',
buttons =
list(I('colvis'),'copy', 'print', list(
extend = 'collection',
buttons = list(
list(extend = 'csv', filename = paste0("iris"), title = NULL),
list(extend = 'excel', filename = paste0("iris"), title = NULL)),
text = 'Download'
)),
lengthMenu = list(c(10, 30, 50, -1),
c('10', '30', '50', 'All'))
),
class = "display"
)
})
}
shinyApp(ui, server)
library(DT)
datatable(
iris,
extensions = "Buttons",
options = list(
dom = "Bfrtip",
buttons = list(
I("colvis"),
list(
extend = "collection",
text = "Download",
buttons = list(
list(
extend = "csv",
exportOptions = list(
columns = ":visible"
)
)
)
)
)
)
)
Thanks to Stéphane Laurent's answer, I managed to find an answer.
I had some problems to have both buttons (csv and excel) and how to organise the lists with the proposed solution, but I found the way to do it.
I will add the answer with the original code just in case someone has problems like me.
library(shiny)
library(DT)
ui <- fluidPage(
dataTableOutput("table")
)
server <- function(input, output, session) {
output$table <- renderDataTable({
datatable(
iris,
filter = list(position = 'top', clear = FALSE),
selection = "none", #this is to avoid select rows if you click on the rows
rownames = FALSE,
extensions = 'Buttons',
options = list(
scrollX = TRUE,
dom = 'Blrtip',
buttons =
list(I('colvis'),'copy', 'print', list(
extend = 'collection',
text = 'Download',
buttons = list(
list(
extend = "csv", filename = paste0("iris"), title=NULL,
exportOptions = list(
columns = ":visible")
),
list(
extend = "excel", filename = paste0("iris"), title=NULL,
exportOptions = list(
columns = ":visible")
)
)
)),
lengthMenu = list(c(10, 30, 50, -1),
c('10', '30', '50', 'All'))
),
class = "display"
)
})
}
shinyApp(ui, server)
I'm using datatable inside an R shiny web app.
How can I change the file name that is gonna be created when donwloading a datatable object?
For example:
datatable(
iris2,
extensions = 'Buttons', options = list(
dom = 'Bfrtip',
buttons =
list('copy', 'print', list(
extend = 'collection',
buttons = c('csv', 'excel', 'pdf'),
text = 'Download'
))
)
)
I want the file donwloaded to be named by default "iris.xlsx" or "iris.csv" . Thanks
Because of extend = "collection", you need to include the filename argument through a nested list inside the button = list(...)
library(DT)
datatable(
iris,
extensions = 'Buttons', options = list(
dom = 'Bfrtip',
buttons =
list('copy', 'print', list(
extend = 'collection',
buttons = list(
list(extend = 'csv', filename = "iris"),
list(extend = 'excel', filename = "iris"),
list(extend = 'pdf', filename = "iris")),
text = 'Download'
))
)
)
Without a collection of buttons
If you don't want a collection of sub-buttons and instead wanted to specify a filename for a single file type (let's say a CSV file), you can do this
library(DT)
datatable(
iris,
extensions = 'Buttons', options = list(
dom = 'Bfrtip',
buttons =
list('copy', 'print', list(
extend = 'csv',
title = "interesting_file"))))
THe key is to use extend = "csv" to specify the file type and then use title for the filename, all inside a list.
When you click the DataTable 1 tab, you can see the Length Menu at the top which is the main point of this question. The bit starting with output$ex1 in the server codes up this data table.
Actually I would like to have buttons for both column visibility and downloading the data. A little modification to the output$ex1 by adding buttons argument
is required. Then, you end up with output$ex2. But now I miss the Length Menu.
I thought adding pageLength = 5, lengthMenu = c(5, 10, 15, 20) to the output$ex2 as can be seen in the code starting with output$ex3 would solve this issue and I can have the Length Menu back. But third one returned me exactly the same table as the second one.
1) How can I have both the buttons and the Length Menu?
2) How can I arrange the positions of the buttons? For example, I would like the buttons for the colvis to be above the buttons for downloading.
3) When you look at the code below, you see that excel is also included in the buttons: buttons = c('colvis', 'copy', 'csv', 'excel', 'pdf', 'print')
But in none of the last 2 tables can you see the button for excel.
Additionally, I do not receive an error for that.
I would appreciate any help.
library(shiny)
ui <- navbarPage(
title = 'DataTable Options',
tabPanel('DataTable 1', DT::dataTableOutput('ex1')),
tabPanel('DataTable with Buttons 1', DT::dataTableOutput('ex2')),
tabPanel('DataTable with Buttons 2', DT::dataTableOutput('ex3'))
)
server <- function(input, output) {
output$ex1 <- DT::renderDataTable(
DT::datatable(iris,
class = 'cell-border stripe',
filter = 'top',
options = list(autoWidth = TRUE)))
output$ex2 <- DT::renderDataTable(
DT::datatable(iris,
class = 'cell-border stripe',
filter = 'top', extensions = 'Buttons',
options = list(autoWidth = TRUE,
dom = 'Bfrtip',
buttons = c('colvis', 'copy', 'csv', 'excel',
'pdf', 'print'))))
output$ex3 <- DT::renderDataTable(
DT::datatable(iris,
class = 'cell-border stripe',
filter = 'top', extensions = 'Buttons',
options = list(autoWidth = TRUE,
pageLength = 5, lengthMenu = c(5, 10, 15, 20),
dom = 'Bfrtip',
buttons = c('colvis', 'copy', 'csv', 'excel',
'pdf', 'print'))))
}
shinyApp(ui = ui, server = server)
You need to add "l" (small letter "L") to dom, that makes Blfrtip:
B - Buttons
l - Length changing input control
f - Filtering input
r - pRocessing display element
t - Table
i - Table information summary
p - Pagination control
These features can be positioned with following command:
"dom": "<'row'<'col-md-3'B><'col-md-6'l><'col-md-3'f>><'row'<'col-md-12't>><'row'<'col-md-3'i><'col-md-6'><'col-md-3'p>>"
Just like we do it in Bootstrap.
For showing both buttons and length menu, you have to change your dom to 'Blfrtip'.
output$ex2 <- DT::renderDataTable(
DT::datatable(iris,
class = 'cell-border stripe',
filter = 'top', extensions = 'Buttons',
options = list(autoWidth = TRUE,
dom = 'Blfrtip',
buttons = c('colvis', 'copy', 'csv', 'excel', 'pdf', 'print'))))
If you open your app in Chrome, you can see the excel button. This is one of the issues of datatable according to this link.
For positioning the buttons, you'll most likely have to make changes in their HTML tags; something along the lines of this.
With the button extension to DT package, is there a way to specify that the buttons download either (1) all the data feeding the datatable, or (2) only the data on the visible page.
Below is the example from the documentation.
datatable(
iris, extensions = 'Buttons', options = list(
dom = 'Bfrtip',
buttons = c('copy', 'csv', 'excel', 'pdf', 'print')
)
)
As #divibisan said, one option is to use the server argument of renderDT() to control whether the download button will download only the current or all rows.
That would work well if you want to have one download button. However if you want to have two buttons always appear, where one download the current page and one downloads the full dataset, you can use the following code:
library(shiny)
ui <- fluidPage(
DT::DTOutput("table")
)
server <- function(input, output, session) {
output$table <- DT::renderDT(server = FALSE, {
DT::datatable(
mtcars,
extensions = c("Buttons"),
options = list(
dom = 'Bfrtip',
buttons = list(
list(extend = "csv", text = "Download Current Page", filename = "page",
exportOptions = list(
modifier = list(page = "current")
)
),
list(extend = "csv", text = "Download Full Results", filename = "data",
exportOptions = list(
modifier = list(page = "all")
)
)
)
)
)
})
}
shinyApp(ui, server)
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.
you are looking for the modifiers: page: selected. here is a working example
ui <- fluidPage(
title = "Examples of DataTables",
sidebarLayout(
mainPanel(
tabsetPanel(
id = 'dataset',
tabPanel("diamonds", DT::dataTableOutput("mytable1"))
)
)
)
)
server <- function(input, output) {
# choose columns to display
diamonds2 = diamonds[sample(nrow(diamonds), 1000), ]
output$mytable1 <- DT::renderDataTable({
DT::datatable(diamonds2,
extensions = 'Buttons',
options = list(
dom = 'Bfrtip',
buttons =
list(
list(
extend = 'csv',
buttons = c('csv'),
exportOptions = list(
modifiers = list(page = "current")
)
))
)
)
})
}
shinyApp(ui, server)
hope this helps!
If you want to include the options to download the current page and the entire dataset as both a csv or an excel file, I've managed to implement this as two separate dropdown buttons with those options, together with the copy and print buttons:
Here is the modified working code:
library(shiny)
ui <- fluidPage(
DT::dataTableOutput("table")
)
server <- function(input, output, session) {
output$table <- DT::renderDataTable(server = FALSE, {
DT::datatable(
mtcars,
extensions = "Buttons",
filter = "top",
selection = "none", #this is to avoid select rows if you click on the rows
rownames = FALSE,
options = list(
scrollX = TRUE,
autoWidth = FALSE,
dom = 'Blrtip', # the important thing is that there is the l to allow for the lengthMenu
# https://stackoverflow.com/questions/52645959/r-datatables-do-not-display-buttons-and-length-menu-simultaneously
buttons = list(
# insert buttons with copy and print
# colvis includes the button to select and view only certain columns in the output table
# from https://rstudio.github.io/DT/extensions.html
I('colvis'), 'copy', 'print',
# code for the first dropdown download button
# this will download only the current page only (depends on the number of rows selected in the lengthMenu)
# using modifier = list(page = "current")
# only the columns visible will be downloaded using the columns:":visible" option from:
# https://stackoverflow.com/questions/72317260/how-to-download-only-the-selected-columns-in-a-dataframe-using-colvis-from-dt-in/72317607#72317607
list(
extend = 'collection',
buttons = list(
list(extend = "csv", filename = "page",exportOptions = list(
columns = ":visible",modifier = list(page = "current"))
),
list(extend = 'excel', filename = "page", title = NULL,
exportOptions = list(columns = ":visible",modifier = list(page = "current")))),
text = 'Download current page'),
# code for the second dropdown download button
# this will download the entire dataset using modifier = list(page = "all")
list(
extend = 'collection',
buttons = list(
list(extend = "csv", filename = "data",exportOptions = list(
columns = ":visible",modifier = list(page = "all"))
),
list(extend = 'excel', filename = "data", title = NULL,
exportOptions = list(columns = ":visible",modifier = list(page = "all")))),
text = 'Download all data')
),
# add the option to display more rows as a length menu
lengthMenu = list(c(10, 30, 50, -1),
c('10', '30', '50', 'All'))
),
class = "display"
)
})
}
shinyApp(ui, server)
I am trying to add download buttons ('copy', 'csv', 'excel', 'pdf') above the table in my R Shiny app, but the renderDataTable seems doesn't work when using a datatable inside.
output$mytable1 <- DT::renderDataTable(
datatable(
{ plots.dfs()[[1]] },
rownames = TRUE,
options = list(
fixedColumns = TRUE,
autoWidth = TRUE,
ordering = FALSE,
dom = 'tB',
buttons = c('copy', 'csv', 'excel', 'pdf')
),
class = "display"
))
When I use DT::renderDataTable without DT::datatable inside, renderDataTable works well and I have all features (filters, search field, etc), except download buttons (what I am trying to add)
output$mytable1 = DT::renderDataTable({ plots.dfs()[[1]] })
Do you have any idea of what I am doing wrong? Thanks for your help
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"
))
Adding one more solution to keep search and paging (dom = 'Bfrtip'):
datatable(data, 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) ))
Adding an answer that is more explicit about allowing to download the whole table since it should be more clearly outlined in my opinion. Using renderDT({}) the download buttons only download the data currently being displayed. You can make the buttons download the entire dataset with renderDT(server = FALSE, {}) as used below:
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')))
})