I have a shiny app like this:
library(shiny)
library(data.table)
tabledata <- data.table(a=1:4, b= 5:8)
ui <- fluidPage(
dataTableOutput("currenttable")
)
server <- function(input,output, session){
output$currenttable <- renderDataTable({tabledata},rownames = FALSE, extensions = 'Buttons',
options = list(dom = 'Bfrtip', buttons = c('copy', 'pdf'),
filename = "CurrentTable", header= "My Header", pageLength = nrow(tabledata))
)
}
shinyApp(ui, server)
The pdf button works, but only saves the file as "pdf.pdf" not "CurrentTable" and header is missing.
You'll need to bind the options to the pdf button. You can include filename and header options in this way.
From the DataTable pdf reference, header indicates whether the table header (i.e. column names) should be included in the exported table or not -- this can only be TRUE or FALSE, not a string. If you're looking for a title above the table, you could use the title option.
Here's your example:
library(shiny)
library(data.table)
library(DT)
tabledata <- data.table(a=1:4, b= 5:8)
ui <- fluidPage(
DT::dataTableOutput("currenttable")
)
server <- function(input,output, session){
output$currenttable <- renderDT({tabledata},
rownames = FALSE,
extensions = 'Buttons',
options = list(dom = 'Bfrtip',
pageLength = nrow(tabledata),
buttons = list(
list(extend = 'copy'),
list(extend = 'pdf',
filename = 'CurrentTable',
title = "My Title",
header = FALSE)
)
)
)
}
shinyApp(ui, server)
Related
I want to create a button that downloads the filtered data of a dataTable, so I read these two posts and tried to do like them but I got an error and it didn't show the table rows. (please see the attachment)
R - Download Filtered Datatable
and
Download filtered data from renderDataTable() in Shiny
The error is: 'data' must be 2-dimensional (e.g. data frame or matrix)
This is a part of my code:
#UI SECTION
downloadButton("download_filtered", "Download filtered dataset"),
verbatimTextOutput("filtered_row"),
DT::dataTableOutput("fancyTable"),
tags$hr(),
plotOutput("fancyPlot")
#SERVER SECTION
server <- function(input, output) {
output$fancyTable<- renderDataTable ({
my_data = data_filter()
DT::datatable(my_data, extensions = "Buttons",
options = list(paging = TRUE,
scrollX=TRUE,
searching = TRUE,
ordering = TRUE,
dom = 'l<"sep">Bfrtip',
buttons = c('copy', 'csv', 'excel', 'pdf'),
pageLength=10,
lengthMenu=c(10,20,50,100) )
)
output$filtered_row <- renderPrint({
input[["fancyTable_rows_all"]]
})
output$download_filtered <- downloadHandler(
filename = "Filtered Data.csv",
content = function(file){
write.csv(my_data[input[["fancyTable_rows_all"]], ],
file)
}
)
})
}
I would be happy if you have any suggestions.
Thank you :)
I have tweaked the code minimally. First I used mtcars instead of my_data.
I think the main issue is to Set server = FALSE in the renderDT function (learned here #Stéphane Laurent) R shiny datatable extension "Buttons" - how to export the whole table to excel?:
library(shiny)
library(DT)
ui <- fluidPage(
downloadButton("download_filtered", "Download filtered dataset"),
verbatimTextOutput("filtered_row"),
DT::dataTableOutput("fancyTable"),
tags$hr(),
plotOutput("fancyPlot")
)
server <- function(input, output, session) {
output$fancyTable <-
DT::renderDT({
datatable(mtcars,
filter = "top",
extensions = "Buttons",
options = list(paging = TRUE,
scrollX=TRUE,
searching = TRUE,
ordering = TRUE,
dom = 'l<"sep">Bfrtip',
buttons = c('copy', 'csv', 'excel', 'pdf'),
pageLength=10,
lengthMenu=c(10,20,50,100)
)
)
}, server = FALSE
)
output$filtered_row <- renderPrint({
input[["fancyTable_rows_all"]]
})
output$download_filtered <- downloadHandler(
filename = "Filtered Data.csv",
content = function(file){
write.csv(my_data[input[["fancyTable_rows_all"]], ],
file)
}
)
}
shinyApp(ui, server)
I have a shiny application with data displayed with DT.
I can export this data with the buttons extensions. But when I export the data, the accent characters do not show correctly.
How can I change the export encoding to have the accents correctly written ?
The original data is
Nom,"Prenom"
Dupond,"Étienne"
Dupont,"François"
Martin,"Frédéric"
This is what I get when I use the CSV or Excel button :
Nom,"Prenom"
Dupond,"Étienne"
Dupont,"François"
Martin,"Frédéric"
Here is a code sample
library(shiny)
library(DT)
ui <- fluidPage(
DT::DTOutput("table_utilisateurs")
)
server <- function(input, output, session) {
output$table_utilisateurs <- DT::renderDT(server = FALSE, {
DT::datatable(
data.frame(Nom = c('Dupond', 'Dupont', 'Martin'),
Prenom = c('Étienne', 'François', 'Frédéric')),
extensions = "Buttons",
filter = 'top',
rownames = FALSE,
options = list(
pageLength = 10,
lengthMenu = c(10,20,50,100),
order = list(list(0,'asc')),
autoWidth = TRUE,
dom = 'lftipB',
buttons = c('copy', 'csv', 'excel')
)
)
})
}
shinyApp(ui, server)
Try this:
buttons = list(
"copy",
"excel",
list(
extend = "csv",
charset = "utf-8",
bom = TRUE
)
)
Now, is the CSV export ok?
I have:
library(shiny)
library(DT)
ui <- fluidPage(
h2("Explorer"),
tabPanel(h3("Inspector"),
p("Overview of data for a particular sample."),
selectInput(inputId = "sample",
label = h3("Select sample"),
selectize = TRUE,
choices = names(vcf_tibbles)),
dataTableOutput("sample_inspector")
)
)
server <- function(input, output) {
output$sample_inspector <- DT::renderDataTable(
sample_overview(sample_id = input$sample, vcf_tibbles = vcf_tibbles),
rownames = FALSE,
extensions = 'Buttons',
options = list(paging = FALSE,
dom = 'Bfrtip',
buttons = list( list(extend = 'csv', filename = paste("snp", input$sample, sep = "-")),
list(extend = 'excel', filename = paste("snp", input$sample, sep = "-"))))
)
}
Everything works fine, in that I select a sample and the table correspondingly updates. And if I click CSV or Excel, the corresponding dta downloads. However, the file name is always wrong.
It seems that the content of the data table is being updated, but input$sample is not being considered with the buttons.
Is there a way to make the filename argument in the buttons also be reactive?
I tried to make the name be the result of a function call, but was unable to get that to work either.
Thanks!
This works like this:
server <- function(input, output) {
output$sample_inspector <- DT::renderDataTable(
iris,
rownames = FALSE,
extensions = 'Buttons',
options = exprToFunction(
list(paging = FALSE,
dom = 'Bfrtip',
buttons = list(
list(extend = 'csv', filename = paste("snp", input$sample, sep = "-")),
list(extend = 'excel', filename = paste("snp", input$sample, sep = "-"))))
)
)
}
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)
The extensions Buttons works great for shiny application, from library(DT). However it export the data without formatting. Is there a way to export data with format (e.g. percentage, or currency)? Similar question left unsolved.
Reproducible code
library(DT)
data.frame(a = c(1,2),
b = c(2,3)) %>%
datatable(extensions = 'Buttons', options = list(
dom = 'Bfrtip',
buttons = c('copy', 'csv', 'excel', 'pdf', 'print')) )%>%
formatPercentage('a') %>%
formatCurrency('b')
Instead of using the Buttons extension, you can use the TableExport library.
library(shiny)
library(DT)
library(shinyjs)
js_export <-
"
var $table = $('#DTtable').find('table');
var instance = $table.tableExport({
formats: ['xlsx'],
exportButtons: false,
filename: 'myTable',
sheetname: 'Sheet1'
});
var exportData0 = instance.getExportData();
var exportData = exportData0[Object.keys(exportData0)[0]]['xlsx'];
instance.export2file(exportData.data, exportData.mimeType, exportData.filename,
exportData.fileExtension, exportData.merges,
exportData.RTL, exportData.sheetname);
"
ui <- fluidPage(
useShinyjs(),
tags$head(
# put these files in the www subfolder
tags$script(src = "xlsx.core.min.js"),
tags$script(src = "FileSaver.min.js"),
tags$script(src = "tableexport.min.js")
),
DTOutput("DTtable"),
actionButton("export", "Export table")
)
server <- function(input, output, session){
output$DTtable <- renderDT({
data.frame(
a = c(1,2),
b = c(2,3)
) %>%
datatable() %>%
formatPercentage('a') %>%
formatCurrency('b')
})
observeEvent(input$export, {
runjs(js_export)
})
}
shinyApp(ui, server)