I am new to shiny and was wondering if there is a way to display a pdf file generated in "downloadHandler"?
I am using a package to do some biological analysis, and I can make it create a pdf file in downloadHandler. However, I am still struggling if I can view this pdf instead of downloading it.
This question is related to Shiny to output a function that generates a pdf file itself.
Please see the below for the code that works for downloading the pdf output. Thanks so much!
library(shiny)
library(msa)
runApp(list(
#Load the exmaple from the msa package.
mySequenceFile <- system.file("examples", "exampleAA.fasta", package="msa"),
mySequences <- readAAStringSet(mySequenceFile),
myFirstAlignment <- msa(mySequences),
# A simple shiny app.
# Is it possible to see the generated pdf file on screen?
ui = fluidPage(downloadButton('downloadPDF')),
server = function(input, output) {
output$downloadPDF = downloadHandler(
filename = 'myreport.pdf',
content = function(file) {
msaPrettyPrint(
myFirstAlignment
, file = 'myreport.pdf'
, output="pdf"
, showNames="left"
, showLogo="top"
, consensusColor="BlueRed"
, logoColors="accessible area"
, askForOverwrite=FALSE)
file.rename("myreport.pdf", file) # move pdf to file for downloading
},
contentType = 'application/pdf'
)
}
))
If you intend to display the pdf, you should not use downloadHandler. Instead, just use your pdf printing function to generate the pdf file, but the key is
Create a www folder under your Shiny project root
Point the file argument of msaPrettyPrint to www/myreport.pdf
Dynamically add an iframe to display the file. Note in the iframe you point to myreport.pdf directly without www, as Shiny automatically looks for static/media files inside the www folder.
See below for a working example (note I am not using the msa package here but the idea should be the same).
library(shiny)
ui <- shinyUI(fluidPage(
titlePanel("Old Faithful Geyser Data"),
sidebarLayout(
sidebarPanel(
actionButton("generate", "Generate PDF")
),
mainPanel(
uiOutput("pdfview")
)
)
))
server <- shinyServer(function(input, output) {
observeEvent(input$generate, {
output$pdfview <- renderUI({
pdf("www/myreport.pdf")
hist(rnorm(100))
dev.off()
tags$iframe(style="height:600px; width:100%", src="myreport.pdf")
})
})
})
shinyApp(ui = ui, server = server)
Related
I am using R to generate an image (png file). How do I use shiny to render it to the ui?
source("#rasterBasePlot.R")
output$spatialMap <- renderImage ({
filename <- PNGFileName
# Return a list containing the filename
list(src = filename)
}, deleteFile = TRUE)
You can simply create a www folder inside your app folder and put the images you want to display there. After that something like the following should be sufficent:
library(shiny)
ui <- fluidPage(
tags$img(
src = "/myimage.png", width = 100
)
)
server <- function(input, output, session) {}
shinyApp(ui, server)
If you want to use folders other than www you can use addResourcePath to add resources to Shiny's web server. Please see this.
I'm building a Shiny App where users complete a survey, and based on their responses, it suggests different templates for them to use. The templates are all excel files that are heavily formatted (e.g., have pictures on them, misaligned headings, etc.), like the screenshot that I've uploaded here. Unfortunately, stackoverflow won't let me upload the excel file to make this fully reproducible, but if you can run it with any non-tabular excel file, it'll work.[![enter image description here][1]][1]
These templates are all uploaded to the server, and the users input does not affect them. I've tried following the example by others, like this [one][2], but I keep getting errors.
How do I get it so when users click the download button, they get the excel file exactly as it appears?
library(readxl)
library(shiny)
library(writexl)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
),
mainPanel(
downloadButton("downloadData", "Download Fancy Excel File")
)))
server <- function(input, output) {
output$downloadData <- downloadHandler(
filename = function() {
paste("file", "xlsx", sep='')
},
content = function(file) {
myfile <- srcpath <- 'Home/Other Layer/Fancy Template.xlsx'
file.copy(myfile, file)
}
)
}
# Run the application
shinyApp(ui = ui, server = server)
~~~~
[1]: https://i.stack.imgur.com/FK034.png
[2]: https://stackoverflow.com/questions/39449544/shiny-download-an-excel-file
You are missing a . in the file name. Also, you can keep all the files you want the users to download in www folder. The following works for me.
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
),
mainPanel(
downloadButton("downloadData", "Download Fancy Excel File")
)))
server <- function(input, output) {
output$downloadData <- downloadHandler(
filename = function() {
paste("testfile", ".xlsx", sep='')
},
content = function(file) {
# myfile <- srcpath <- 'Home/Other Layer/Fancy Template.xlsx'
myfile <- srcpath <- "./www/test141.xlsx"
file.copy(myfile, file)
}
)
}
# Run the application
shinyApp(ui = ui, server = server)
I am not good at English, so sentences may be wrong.
I want to distribute excel files prepared in advance to users. Is it possible to realize such a system with shiny? No problem with .zip.
Thank you
ui.R
shinyUI(
fluidPage(
downloadButton('downloadData', 'Excel Download')
)
)
server.R
shinyServer(function(input, output) {
output$downloadData <- downloadHandler(
filename = "distribution.xlsx",
content = "distribution_excel"
)
})
Yes, it is possible and you were nearly there. Below is a minimal working example. I assume that your .xlsx file is located in the same folder as your app.R. Notice that I have created the app in a single R file as opposed to two separate files.
The trick to getting the file to download is to use a function for the content inside of downloadHandler(). Specifically we are using the base function file.copy(). Clicking the button should now download the file: distribution.xlsx. This file can obviously be exchanged with a zip file.
If you want different users to access different Excel files, you can write an additional function inside of your server function that passes the file argument to the downloadHandler().
# Load packages ----
pkgs <- c("shiny")
invisible(lapply(pkgs, require, character.only = TRUE))
# Set up the UI ----
ui <- fluidPage(
# Define your download button
downloadButton(
outputId = "downloadData",
label = "Excel Download"
)
)
# Set up the server side ----
server <- function(input, output, session) {
# Define the download handler with function() for content.
output$downloadData <- downloadHandler(
filename = "distribution.xlsx",
content = function(file) {
file.copy("distribution.xlsx", file)
}
)
}
# Combine into an app ----
shinyApp(ui = ui, server = server)
I am learing Shiny. I want to make a simple app that allows for dynamic paths that the user enters. The app should then list csv files in folder A and then copy them from folder A to folder B (the working directory). Then the app does some operations in folder B using an external exe program. Afterwards the folder will cut the results files (.txt) from B and copies them into A.
The structure of my app is as follows ( I have also attached a picture). the problem is explained in the comments in the code.
library(shiny)
ui<-fluidPage(
textInput("prg","Program",getwd()),
verbatimTextOutput("prg"),
textInput("prj","Project","Project"),
verbatimTextOutput("prj")
)
server<-function(input, output,session) {
output$prg=renderText(input$prg)
renderPrint(output$prg)
output$prj=renderText(paste0(input$prg,"/",input$prj))
#This is where my challenge is
#I want to
#list.files(path=path-shown-in-text-box-Project,pattern=".csv")
#Then i want to copy csv files from A to B as described above and run the following program
#This works
observeEvent(input$run,
{
system("my.exe") #exe not shared
})
#Finally I want to cut and paste the results (.txt) from B back into A
}
shinyApp(ui,server)
I want to list.files(path=path-shown-in-text-box-Project,pattern=".csv")
Here's code you can use to browse any directory for a particular CSV file, read that file and display its contents.
library(shiny)
# Define UI
ui <- pageWithSidebar(
# App title ----
headerPanel("Open a File and Show Contents"),
# Sidebar panel for inputs ----
sidebarPanel(
label="Data Source",fileInput("fileName", "File Name",accept=c(".csv"))),
# Main panel for displaying outputs ----
mainPanel(
tableOutput(outputId = "table")
)
)
# Define server logic
server <- function(input, output) {
inputData <- reactive ({
if (is.null(input$fileName)) return(NULL)
inFile <- input$fileName
conInFile <- file(inFile$datapath,open='read')
inData <- read.csv(conInFile,stringsAsFactors = FALSE)
close (conInFile)
return (inData)
})
output$table <- renderTable ({
inData <- inputData()
if (length(inData) > 0) inData
})
}
shinyApp(ui, server)
I am trying to make a Shiny App that retrieves an image from Nasa API and displays it to the user.
Although I manage to download the image from the API and store it in a temp file I can't display it in the shiny app but only locally.
Here is my code so far:
library(shiny)
library(httr)
library(jpeg)
library(RCurl)
library(jsonlite)
library(shinythemes)
#library(imager)
key<-"eH45R9w40U4mHE79ErvPWMtaANJlDwNaEtGx3vLF"
url<-"https://api.nasa.gov/planetary/apod?date="
ui <- fluidPage(theme = shinytheme("yeti"),
# Application title
titlePanel("Nasa API"),
sidebarLayout(
sidebarPanel(
helpText("Wellcome to Nasa search API ",
"enter a date in YYYY-MM-DD to search for picture"),
textInput("date", label="Date input",
value = "Enter date..."),
actionButton("go", "Search")
),
mainPanel(
imageOutput("myImage")
)
)
)
server <- function(input, output,session) {
query<-eventReactive(input$go,{
input$date
})
output$myImage <- renderImage({
nasa_url<-paste0(url,query(),"&api_key=",key)
# A temp file to save the output.
# This file will be removed later by renderImage
response<-getURLContent(nasa_url)
json<-fromJSON(response)
img_url<-json$url
temp<-tempfile(pattern = "file", fileext = ".jpg")
download.file(img_url,temp,mode="wb")
jj <- readJPEG(temp,native=TRUE)
plot(0:1,0:1,type="n",ann=FALSE,axes=FALSE)
rasterImage(jj,0,0,1,1)
#im<-load.image(temp) #use this with library(imager)
#plot(im) #use this with library(imager)
},deleteFile = T)
}
# Run the application
shinyApp(ui = ui, server = server)
Be careful when sharing your code as you just shared your private API key. I suggest you generate a new one.
It does not work because shiny only serves files that are in the ~/www directory. So they should be downloaded to that folder for your method to work.
Perhaps an easier way to go about this is simply to embed the image. Looking at the code it looks like json$url is the URL to the image.
library(shiny)
ui <- fluidPage(
h4("Embedded image"),
uiOutput("img")
)
server <- function(input, output, session) {
output$img <- renderUI({
tags$img(src = "https://www.r-project.org/logo/Rlogo.png")
})
}
shinyApp(ui, server)
You could try the above without hardcoding https://www.r-project.org/logo/Rlogo.png and using your json$url instead.