Skip to content

Instantly share code, notes, and snippets.

@yihui
Last active June 13, 2021 17:45
  • Star 15 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save yihui/6091942 to your computer and use it in GitHub Desktop.
use knitr (knit2pdf) to generate a PDF report in a Shiny app

To see this app in action, run this in R:

library(shiny)
runGist('https://gist.github.com/yihui/6091942')
\documentclass{article}
\begin{document}
<<names>>=
input$firstname
input$lastname
@
\end{document}
library(knitr)
shinyServer(function(input, output) {
output$report = downloadHandler(
filename = 'myreport.pdf',
content = function(file) {
out = knit2pdf('input.Rnw', clean = TRUE)
file.rename(out, file) # move pdf to file for downloading
},
contentType = 'application/pdf'
)
})
library(shiny)
shinyUI(basicPage(
textInput('firstname', 'First name', value = 'Jimmy'),
textInput('lastname', 'Last name', value = 'John'),
downloadButton('report')
))
@rebordao
Copy link

Knitr is terrific. Thank you!

About this Gist I have a doubt, is it possible to change

content = function(file) {
  out = knit2pdf('input.Rnw', clean = TRUE)
  file.rename(out, file) # move pdf to file for downloading
},

such that the function content outputs an existing pdf file?

Basically my backend already created the pdf via knitr. I just want to have a way to download it, and downloadHandler seems an elegant way to do it. I tried several things but none worked out.

@yihui
Copy link
Author

yihui commented Jun 21, 2014

If you already have made the PDF file, you can just copy it to file, i.e.

content = function(file) file.copy('your_existing.pdf', file, overwrite = TRUE)

@natrot
Copy link

natrot commented Sep 17, 2014

I used the exact server.R downloadHandler. It works fine when I run the shiny app from my FireFox browser, but longer reports seem to timeout.

Is there anywhere that I can set timeout limit for shiny server? Or is there another way I can do the download of the pdf report so that the browser will wait until it is finished?

Thanks for your help.

O, I neglected to say. These longer reports run fine when I run it through shiny in Rstudio, the problem is when I run it from my browser. The report takes about 5 min to generate in Rstudio.

@yihui
Copy link
Author

yihui commented Sep 18, 2014

Sorry I do not know much about shiny server, and you will have to read its documentation unless you have bought shiny server pro.

I'm wondering why your report could take so long to compile. If there are time-consuming code chunks, you can turn on cache in knitr (e.g. the chunk option cache = TRUE).

@natrot
Copy link

natrot commented Sep 19, 2014

Thanks.

The reason for the long generation time is just a data issue. Im working with a big database and it takes long to run the actual data extracts. I have tried to bypass this by running the queries in a separate script and saving it to csv files. Then I use the fread function in my Rnw file.

But my reports got a few parameters, so to be able to cater for all the possible parameters that the user can select my csv files are very big and even fread takes a long time.

Currently my Shiny instance is deployed on a very slow virtual server, so upgrading it will solve this issue. But just wondered if there was another way of downloading a report that wont cause a timeout.

Ill look into Rmarkdown and publishing html reports as well.

Thanks for all your help.

@McClellandLegge
Copy link

Would it be possible to just display the pdf as a static image, or with a pdf reader?

@jonathanflint
Copy link

I've tried using this method on linux, but it falls down at the rename step due to an invalid cross-device link. It works when I run the gist, but not when I do it locally from Rstudio or on shiny-server.
Any idea why?

Error is:

Warning in file.rename(out, file) :
cannot rename file 'notexchange.pdf' to '/tmp/RtmpvJdVpU/file6e8028e1d1f7', reason 'Invalid cross-device link'
Error opening file: 2
Error reading: 9

@geotheory
Copy link

Alas this fails for me with cannot open the connection..

@makman7
Copy link

makman7 commented Sep 16, 2015

After the whole day searching i just know here that objects accessible in .Rnw from ui and server file so u can create reports in shinny app...
ty man

@lomeshptl48
Copy link

Hello, this is all bull sit..

not work any code..
just post foll example with working demo..

there are too many errors are occure when i reguest for generate PDF.
anyone can help me to generate PDF of my data.. or any form of data.. in shiny.. plz.. help me/.. !!

@Bustami
Copy link

Bustami commented Feb 5, 2016

It's awesome. Thanks a lot man!

@Mettekl
Copy link

Mettekl commented Jan 4, 2018

I had similiar problems with the downloadHandler when generating longer pdf reports.
The timeout is default 45 s and it can be set by changing the http_keepalive_timeout parameter in the shiny-server configuration file @natrot. See here:
https://github.com/rstudio/shiny-server/blob/master/config/shiny-server-rules.config

@jonathanflint try to use file.copy instead of file.rename. It does not seem to have the same problem.

@jaloszekk
Copy link

I tried to use your example but I am not able to change the name of the pdf, cuz when I do that it causes error.

@csliangy
Copy link

Hi, Yihui

I have posted the same message on your blog but I think this might be a better place to discuss the issue.

I published the exact the same sample app on shinyapps.io but I came cross the following issues (I can run locally on my windows as well as RStudio Server (On an Ubuntu)):

2018-10-26T01:48:44.985563+00:00 shinyapps[535924]: Server version: 1.6.8-6
2018-10-26T01:48:44.985565+00:00 shinyapps[535924]: LANG: en_US.UTF-8
2018-10-26T01:48:44.985618+00:00 shinyapps[535924]: rmarkdown version: NA
2018-10-26T01:48:44.985614+00:00 shinyapps[535924]: R version: 3.5.1
2018-10-26T01:48:44.985616+00:00 shinyapps[535924]: shiny version: 1.1.0
2018-10-26T01:48:45.133726+00:00 shinyapps[535924]:
2018-10-26T01:48:44.985619+00:00 shinyapps[535924]: knitr version: 1.20
2018-10-26T01:48:44.985617+00:00 shinyapps[535924]: httpuv version: 1.4.5
2018-10-26T01:48:45.128881+00:00 shinyapps[535924]: Using jsonlite for JSON processing
2018-10-26T01:48:45.172152+00:00 shinyapps[535924]: Listening on http://127.0.0.1:41445
2018-10-26T01:48:44.985620+00:00 shinyapps[535924]: RJSONIO version: NA
2018-10-26T01:48:44.985621+00:00 shinyapps[535924]: htmltools version: 0.3.6
2018-10-26T01:48:45.133728+00:00 shinyapps[535924]: Starting R with process ID: '18'
2018-10-26T01:48:44.985699+00:00 shinyapps[535924]: Using pandoc at /opt/connect/ext/pandoc2
2018-10-26T01:48:45.172150+00:00 shinyapps[535924]:
2018-10-26T01:48:44.985619+00:00 shinyapps[535924]: jsonlite version: 1.5
2018-10-26T01:48:54.630740+00:00 shinyapps[535924]:
2018-10-26T01:48:54.630742+00:00 shinyapps[535924]:
2018-10-26T01:48:54.630744+00:00 shinyapps[535924]: processing file: input.Rnw
2018-10-26T01:48:54.652924+00:00 shinyapps[535924]: ordinary text without R code
2018-10-26T01:48:54.652725+00:00 shinyapps[535924]:
|
| | 0%
|
|...................... | 33%
2018-10-26T01:48:54.652925+00:00 shinyapps[535924]:
2018-10-26T01:48:54.653358+00:00 shinyapps[535924]:
|
|........................................... | 67%
2018-10-26T01:48:54.654942+00:00 shinyapps[535924]: label: names
2018-10-26T01:48:54.729765+00:00 shinyapps[535924]: ordinary text without R code
2018-10-26T01:48:54.729719+00:00 shinyapps[535924]:
|
|.................................................................| 100%
2018-10-26T01:48:54.729766+00:00 shinyapps[535924]:
2018-10-26T01:48:54.730620+00:00 shinyapps[535924]:
2018-10-26T01:48:54.732189+00:00 shinyapps[535924]: output file: input.tex
2018-10-26T01:48:54.732189+00:00 shinyapps[535924]:
2018-10-26T01:48:54.734834+00:00 shinyapps[535924]: Warning: Error in loadNamespace: there is no package called ‘tinytex’
2018-10-26T01:48:54.739940+00:00 shinyapps[535924]: [No stack trace available]

Thanks,
Liang

@Kamakshaiah
Copy link

Kamakshaiah commented Jan 8, 2019

Hi yihui,
This is really a very helpful information. However, I am getting the following warning while executing "app".

Warning in file.rename(out, file) : cannot rename file 'input.pdf' to '/tmp/RtmpAeLXey/file1c6b135b80b9.pdf', reason 'Invalid cross-device link'

No output file is being created after...
Will you please help me how to solve this? Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment