Use R Markdown .docx template in shiny app - r

I build a shiny app that can filter data and automatically render .docx reports. As I want to customize my reports I would like to use the reference_docx function in the YAML header. I have the shiny app, the markdown document and the template.docx all in one folder. However, the shiny app does not automatically "use" the template.docx as markdown usually does. I assume that I have to load the template in a tempdir() or something like this, but I couldn't quite figure out how. What do I have to do to load the reference docx into the shiny app?
Thank you for your help!

Keep your rmarkdown and word template in app folder.
In your downloadhandler:
output$your_output <- downloadHandler(
filename = function() {
'output_title.docx'
},
content = function(file) {
tempReport <- file.path(temp_folder,
"rmarkdown_template.Rmd")
tempTemplate <- file.path(temp_folder, "template.docx")
file.copy("rmarkdown_template.Rmd", tempReport, overwrite = TRUE)
file.copy("template.docx", tempTemplate, overwrite = TRUE)
# Params
)
rmarkdown::render(tempReport, output_file = file, output_format = 'word_document',
params = params,
envir = new.env(parent = globalenv())
)
}
)
Then in your yaml:
output:
word_document:
reference_docx: template.docx

Related

Instructing RMarkdown to use relative filepaths or stop shortening folder names

I have a parameterized RMarkdown PDF report that I am running from a Shiny dashboard (after copying it to a temporary directory).
Example code:
Shiny dashboard:
---
title: "Company Report Frontend"
output:
flexdashboard::flex_dashboard:
orientation: columns
vertical_layout: fill
runtime: shiny
---
```{r global, include=FALSE}
library(flexdashboard)
library(shiny)
```
### Select Company
```{r}
textInput('name', label ='Firm')
```
### Report
```{r}
uiOutput("downloadUI")
# Create the actual downloadButton
output$downloadUI <- renderUI( {
downloadButton("downBtn", "Download Report")
})
# Add download handling
output$downBtn <- downloadHandler(
filename = "full_report.pdf",
content = function(file) {
tempReport <- file.path(tempdir())
file.copy("test_report.Rmd", paste0(tempReport, "/test_report.Rmd"), overwrite = TRUE)
rmarkdown::render(paste0(tempReport, "/test_report.Rmd"), output_file = file,
params = list(input=input),
envir = new.env(parent = globalenv()), clean = FALSE,
knit_root_dir = tempReport,
)
}
)
```
test_report.RMD:
---
title: "Report"
header-includes:
\usepackage{graphicx}
params:
input: NA
output:
pdf_document:
latex_engine: xelatex
---
```{r}
input <- params$input
data(mtcars)
plot(mtcars$hp, mtcars$mpg)
title(input$name)
```
When I run it, it successfully produces the .tex file but then can't compile it. When I try to compile the .tex file directly in a LaTeX editor, I get undefined control sequence and Missing endcsname defined errors on any \includegraphics lines like this one:
\includegraphics{C:/User/LONGUS~1/Temp/file5b381fa967c8_files/figure-latex/unnamed-chunk-1-1.pdf}
where LONGUS~1 is a shortened folder name from the actual Windows username LONGUSERNAME.
The error goes away, and the PDF compiles, if I replace LONGUS~1 with LONGUSERNAME, or just point it to the relative filepath. LaTeX does tend to get finicky about filepaths sometimes.
How can I instruct RMarkdown to either avoid shortening folder names, or skip the absolute filepath and just use the relative? test_report.RMD compiles fine if I run it by itself (and specify a default input), so I'd guess this is something to do with the use of tempdir() or at least something in the render() function. But I really should keep the tempdir() stuff in the case of multiple simultaneous users of the shiny app. I did try removing the knit_root_dir option but that didn't fix it.
Any suggestions welcome. Thank you!

Bookdown Download for HTML single document

I have a bookdown book with multiple output formats.
I want the user to be able to download the content in multiple formats. This works wonders with PDF, EPUB and so on. But it does not work with single file HTML bookdown::html_document2 documents as they are rendered in the present working directory . and not the _book folder.
E.g., when I specify bookdown::git_book: ... it gets created in _book.
When I use bookdown::pdf_book: ... it also gets created in _book.
However, when I use bookdown::html_document2: ..., it gets created in ..
Setting output_dir for the single page document didn't work.
Do you know how to solve this?
MWE
## _bookdown.yml
book_filename: "The-book"
delete_merged_file: yes
## _output.yml
bookdown::gitbook:
split_by: rmd
config:
download:
- ["The-book.pdf", "PDF"]
- ["The-book.html", "HTML"]
bookdown::html_document2:
toc: true
bookdown::pdf_book:
keep_tex: no
dev: "cairo_pdf"
latex_engine: xelatex
and then in 01-intro.Rmd
# Intro
This is a test
I make book directly from a R script and this work for me:
bookdown::render_book(
input = "index.Rmd",
output_format = "bookdown::html_document2",
output_file = "_book/The-book.html"),
)
By making the book from R script you can start to have fun with name (like adding the date) and directory of the book, noting that if the directory is not _book you will need to create it before. With pdf output you can use output_dir to have the directory created for you, but it seems not to work and even conflict with output_file for html_document2. Ex:
## PDF report
bookdown::render_book(
input = "index.Rmd",
output_format = "bookdown::pdf_document2",
output_file = paste0("Proceedings-pdf-", format(Sys.time(), format = "%Y-%m-%d-%H%M%S"), ".pdf"),
output_dir = "Proceedings"
)
## HTML
dir.create("Proceedings", showWarnings = F)
bookdown::render_book(
input = "index.Rmd",
output_format = "bookdown::html_document2",
output_file = paste0("Proceedings/Proceedings-html-", format(Sys.time(), format = "%Y-%m-%d-%H%M%S"), ".html"),
)
Quarto is able to produce stand-alone html files (https://quarto.org/docs/output-formats/html-basics.html#self-contained). E.g.
---
project:
type: book
format:
html:
embed-resources: true
---
Note that this currently does not work if you specify an output path (see here).

Shiny Rmarkdown html download

In my Rmarkdownfile I want to download my .rmd as a html file but I get the following error.
Warning: Error in file. Cannot open the connection.
I think it's because of the external file included by source(...), but I don't know why. In the external file I make a connection to a db.
---
output:
flexdashboard::flex_dashboard:
orientation: columns
vertical_layout: fill
runtime: shiny
---
```{r setup, include=FALSE}
library(flexdashboard)
library(rmarkdown)
source('R/load_data.R')
```
```{r}
output$export_btn<- downloadHandler(
filename = "report.html",
content = function(file) {
tempReport <- file.path(tempdir(), "test.Rmd")
file.copy("test.Rmd", tempReport, overwrite = TRUE)
out<-render(tempReport, html_document())
file.rename(out,file)
}
)
```
You are passing file to your function content = function(file). file is a default R function. Did you mean to pass filename to the function instead?
output$export_btn<- downloadHandler(
filename = "report.html",
content = function(filename) {
tempReport <- file.path(tempdir(), "test.Rmd")
file.copy("test.Rmd", tempReport, overwrite = TRUE)
out<-render(tempReport, html_document())
file.rename(out,filename)
}
)

Unable to see images in rmarkdown table

I am trying to create a downloadable report from a shiny app. The report shows a table in which there are images.
I am passing the table with the url in the table as a parameter to the report as follows:
server <- function(input, output,session) {
data <- reactive({
data <- data.frame(RV3$data[,input$Map_EndoscopistIn],
RV3$data[,input$Map_FindingsIn],
RV3$data[,input$Map_MicroscopicTextIn],
RV3$data$url)
names(data)<-c(input$Map_EndoscopistIn,input$Map_FindingsIn,input$Map_MicroscopicTextIn,"Image")
if(!is.null(input$EndoscopistChooserIn)){
data<-data%>%filter(get(input$Map_EndoscopistIn)==input$EndoscopistChooserIn)
}
data
})
}
output$report <- downloadHandler(
# For PDF output, change this to "report.pdf"
filename = "report.doc",
content = function(file) {
# Copy the report file to a temporary directory before processing it, in
# case we don't have write permissions to the current working dir (which
# can happen when deployed).
tempReport <- file.path(tempdir(), "report.Rmd")
file.copy("report.Rmd", tempReport, overwrite = TRUE)
browser()
# Set up parameters to pass to Rmd document
params <- list(performanceTable=data()
)
# Knit the document, passing in the `params` list, and eval it in a
# child of the global environment (this isolates the code in the document
# from the code in this app).
rmarkdown::render(tempReport, output_file = file,
params = params,
envir = new.env(parent = globalenv())
)
}
)
the url column in data() contains the following path eg:
![](<img src='Images/Images Captured with Proc Data Audit.files/img2527.jpg'>)
The report is as follows:
---
title: "Dynamic report"
always_allow_html: yes
output:
word_document:
fig_caption: true
params:
performanceTable: NA
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(ggplot2)
```
```{r,echo=FALSE,warning=FALSE}
pander(params$performanceTable, justify='left',split.table=Inf,caption="Table 1: Cancer diagnoses")
```
The report is in the same folder as the Images folder.
With this I get the following error example:
[pandoc warning] Could not find image `img%20src='Images/Images%20Captured%20with%20Proc%20Data%20Audit.files/img2500.jpg'', skipping...
What am I doing wrong? Is this a reformatting in pander issue or a paths issue or what? Or could this be that the report root is the tmp directory whereas I am referring to images stored in anoter static directory. If it is the latter, what do I do to get paths relative to the temp directory so I can see the images?
The reason you couldn't locate your image file is because you render your report.Rmd from a temp directory where your image doesn't exist:
tempReport <- file.path(tempdir(), "report.Rmd")
file.copy("report.Rmd", tempReport, overwrite = TRUE)
The solution is that the image should also be copied to the same temp directory where markdown syntax ![](img.png) will pick up the file.
As in code change, you should be able to get it working by doing this:
assign a tempDir
tempDir <- tempdir()
Move Rmd as well as images to tempDir
file.copy(c("report.Rmd", "Images/Images Captured with Proc Data
Audit.files/img2527.jpg"), tempDir, overwrite = TRUE)
then render from temp dir
rmarkdown::render(file.path(tempDir, 'report.Rmd'), output_file = file,
params = params,
envir = new.env(parent = globalenv())

download pdf with knitr in shiny in R

I try to create button for downloading with knitr package.
I have found some example which works a bit but I'm not able to change the name of the pdf. moreover it causes errors then.
enter image description here
second problem is that when I download the file , it is not a .pdf extension and I have to choose program to open it when I try to open. How can I download file as .pdf in default?
here are my codes (example from the internet):
server.R
library(knitr)
shinyServer(function(input, output) {
output$myreport = downloadHandler(
filename = "adads.pdf",
content = function(file) {
out = knit2pdf('input.Rnw', clean = TRUE )
file.rename(out, file) # move pdf to file for downloading
},
contentType = 'application/pdf'
)
})
ui.R
library(shiny)
shinyUI(basicPage(
textInput('firstname', 'First name', value = 'Jimmy'),
textInput('lastname', 'Last name', value = 'John'),
downloadButton('myreport')
))
and input.Rnw file
\documentclass{article}
\begin{document}
<<names>>=
input$firstname
input$lastname
#
\end{document}

Resources