ginberg
ginberg

Reputation: 91

How can I add a generated htmlwidget to Rmarkdown and convert it to a Word document?

I would like to create a word document of the items in a shiny dashboard. The dashboard contains text, plots generated by ggplot and htmlwidgets.

The generation of the word document is done via Rmarkdown and it goes well when I am including text and the ggplots. I am struggling with htmlwidgets though. I have tried to include the html, generated from the htmlwidget directly into the document, but it doesn't work. It does work when I choose as output "html_document" instead of "word_document". Some elements are included but some others seem to be get neglected. Below just a simple example, the link and image are not appearing in the word document. Any ideas?

---
title: 'Title'
output: 
  word_document:
    md_extensions: +markdown_in_html_blocks
---

<html>
<head>
<meta charset="utf-8" />
<title>title</title>
<a href="https://google.com"><h2>Text without link</h2></a>
<img src="test.png">
</body>
</html>

Upvotes: 2

Views: 1921

Answers (2)

RLesur
RLesur

Reputation: 5910

I think @ginberg solution can be simplified in a more straightforward way: since knitr v1.13, HTML widgets are automatically rendered as snapshots using the webshot package.

Setup
First, webshot and phantomjs need to be installed:

install.packages("webshot")
webshot::install_phantomjs()

Automatically convert htmlwidgets

library(magrittr)
library(canvasXpress)
library(rmarkdown)

tmp_rmd <- "out.Rmd"

data <- t(iris[,1:4])
varAnnot <- as.matrix(iris[,5])
colnames(varAnnot) <- "Species"

widget <- canvasXpress(t(data), 
                       varAnnot = varAnnot, 
                       graphType = 'Scatter3D', 
                       colorBy = 'Species')

"---
title: htmlwidget output
---
```{r, echo=FALSE}
widget
```
" %>% cat(file = tmp_rmd)

render(tmp_rmd, word_document())

Obviously, you can permanently store the out.Rmd file to simplify the code.

Upvotes: 1

ginberg
ginberg

Reputation: 91

Here's how I got it working, thanks to the suggestion of @romles It's a bit different than my previous example since I am generating the rmarkdown string in R code.

library(htmlwidgets)
library(webshot)
library(canvasXpress)

rpt <- c("---", 
         "title: htmlwidget output", 
         paste("output: ", "  word_document"), 
         "---")

tmp_html <- tempfile(fileext = ".html")
tmp_image <- tempfile(fileext = ".png")
tmp_md  <-  "out.md"
out_docx <- "out.docx"

data <- t(iris[,1:4])
varAnnot <- as.matrix(iris[,5])
colnames(varAnnot) <- "Species"
widget <- canvasXpress(t(data), 
                       varAnnot = varAnnot, 
                       graphType = 'Scatter3D', 
                       colorBy = 'Species')

saveWidget(widget, tmp_html, selfcontained = FALSE)
webshot(tmp_html, 
        file = tmp_image, 
        vwidth = widget$width, 
        vheight = widget$height)

image_md <- paste0("![](", tmp_image, ")")
rpt <- c(rpt, image_md)

report.md <- knitr::knit(text = rpt, output = tmp_md)
rmarkdown::render(input = tmp_md, 
                  output_format = "word_document",
                  output_file   = out_docx)

Upvotes: 1

Related Questions