I have an RShiny application that generates a network plot using the diagrammeR package:
blc3001 <- eventReactive(input$datapath,{
data_blc <- readxl::read_xlsx(input$datapath$datapath)
blc3001 <- "digraph test{<TONS OF GRAPH CODE>"
})
I can output to Shiny using:
output$blc3001 <- renderGrViz({
grViz(blc3001())
})
And I can download as a .png using:
output$d_blc3001 <- downloadHandler(
filename = "blc3001.png",
content = function(file) {
grViz(blc3001()) %>% export_svg %>% charToRaw %>% rsvg_png(file)
},
contentType = "image/png"
)
Now I am trying to download this graph into a powerpoint slide, but am running into difficulty. I am open to any method or package, but I am currently trying to do this via the "officer" package.
output$blc3001_powerpoint <- downloadHandler(
filename = function() {
"blc3001.pptx"
},
content = function(file) {
image <- grViz(blc3001()) %>% export_svg %>% charToRaw %>% rsvg_png()
ppt_report <- read_pptx() %>%
add_slide(layout = "Title and Content", master = "Office Theme") %>%
ph_with(value = image, location = ph_location_type(type = "body"))
print(ppt_report, target = file)
}
)
Although I can download the png, when I define ppt_report, I get error:
Error in UseMethod("ph_with", value) :
no applicable method for 'ph_with' applied to an object of class "raw"
I assume this is because I specify content type is img/PNG in the image download handler, but not the powerpoint download handler. I can download the powerpoint without error if I remove "%>% charToRaw %>% rsvg_png()" from defining image, but the powerpoint slide contains the XML code rather than rendering the actual svg. If anyone can please provide any tips on how to proceed I would greatly appreciate it! Thanks!
Related
I'm creating an application to track soccer statistics for a high school team. The coach wants it to be like an excel sheet, where player data can be inputted and saved to be looked at later. I've figured out how to do that with rhandsontable, but I can't get it to download to my shadow document from my r shiny. I was able to get the shadow doc to work before adding the rhandsontable, but it is no longer working. I'm attaching the code from the server that I'm using to create the table. The player_names is a csv with columns for player name, team level, goals scored,.... other stats. I'm first looking at only one team level (ie varsity), then making the table. It works great in the shiny, but I don't how to save it from there.
output$hot <- renderRHandsontable({
player_names %>%
filter(Team == input$team_level) %>%
rhandsontable()
})
values <- reactiveValues(data = NULL)
observe({
values$data <- hot_to_r(input$hot)
})
# 3. I assign this df to a variable call df1
df1 <- reactive({
values$data
})
Code to make shadow doc:
output$downloadReport <- downloadHandler(
filename = function() {
paste("ophs_soccer", sep = ".", switch(
input$format, PDF = "pdf", HTML = "html", Word = "docx"
))
},
content = function(file) {
src <- normalizePath("shadow_page.Rmd")
# temporarily switch to the temp dir, in case you do not have write
# permission to the current working directory
owd <- setwd(tempdir())
on.exit(setwd(owd))
file.copy(src, "shadow_page.Rmd", overwrite = TRUE)
library(rmarkdown)
out <- render("shadow_page.Rmd", switch(
input$format,
PDF = pdf_document(), HTML = html_document(), Word = word_document()
))
file.rename(out, file)
I tried to create output in the shadow doc like I did with the other reactive inputs, and it did not work. I get an error when trying to download the document.
i'm trying to create a ggplot editable with ppt or word
Here's the code:
library(tidyverse)
library(rvg)
library(officer)
##I create a dml object
anyplot = dml(code = barplot(1:5, col = 2:6), bg = "wheat")
## add slide
doc <- read_pptx()
##specify object and location of object
doc <- add_slide(doc, "Title and Content", "Office Theme")
doc <- ph_with.dml(doc, anyplot, location = ph_location_fullsize())
## print it in pptx
print(doc, target = 'plot.pptx')
But I keep getting could not find function "ph_with.dml"
note: I understand ph_with.dml is the new version of ph_with_vg (which cannot be find either)
Any suggestion or different approach would be appreciated!
I want to add a graphic in the form of a pdf to a power point file created by officer. The following code works, in the sense that the powerpoint is created and the pdf is included. But to get to the powerpoint you have to let it repair itself. Here's an example
library(officer)
library(magrittr)
my_pres <- read_pptx()
testpdf <- "test.pdf"
extImgObs_pdf <- external_img(src = testpdf)
fp_3 <- fp_text(italic = TRUE, color = "black", font.size = 14)
my_pres <- add_slide(x = my_pres, layout = 'Title Only', master = 'Office Theme')
titleTextObserved <- "some text for the title field"
my_pres <- ph_with( x = my_pres, value = fpar(ftext(titleTextObserved, fp_3)), location = ph_location_type(type = "title") )
my_pres <- ph_with( x = my_pres, value = extImgObs_pdf, location = ph_location(left = 0, top = 1.2) )
print(my_pres, target = "presentations/cmip6/chillHours_Ensemble.pptx") %>% browseURL()
With some arbitrary test.pdf file (I've generated it with the pdf driver in R and removed whitespace with the linux pdfcrop program), the above code generates a powerpoint. If you click the Repair ok message the powerpoint shows up as expected. But when you click Cancel rather than Repair, Powerpoint returns "Sorry, PowerPoint can't read ^O." Is there any way to remove the Repair message other than by manually clicking Repair?
Clicking repair makes the pdf image visible locally but the ppt doesn't show the graphic for others. Need to use something other than pdf for the graphics. png, tiff, bmp and jpeg are options.
I am working on an R Shiny app where a user supplies information that modifies an existing Word document for the user to download. I've had trouble getting R Shiny to download the resulting new Word document. I've tried regular hyperlinks, and that doesn't seem to work.
(Edit: After typing up this post, I came across how to download files with hyperlinks. I forgot files need to be placed inside a www folder, as specified here: Shiny hyperlink relative path to a file. So although I can get my Shiny App to work using this approach, I'd still like to know why my example below is not working).
I came across Github Issue #145 (https://github.com/davidgohel/officer/issues/145) which almost has the solution. But the pptx being downloaded is created from scratch whereas I want to start from an EXISTING Word docx.
In my code example, there are 3 downloadHandler buttons:
Uses the original pptx download code example from Github Issue #145
The second modifies the above to download a docx
The third button is my attempt to download an existing and modified docx file
The third button is not working as I had hoped. If I had to guess, I think it has to do with my template being from from read_docx. It looks like it creates some temporary file behind the scenes. But I don't know where to go from here.
For completeness, here are some related links:
Reporters package to download docx report from shiny (uses ReporeRs which is older than officer R package)
Writing word documents with the officer package: How to combine several rdocx objects? (Helpful if merging existing docx to the tempfile in my example)
downloadHandler reference: https://shiny.rstudio.com/reference/shiny/latest/downloadHandler.html
# -------- Example code ------------
library(shiny)
library(officer)
library(mschart)
library(dplyr)
# Create template folder and file. (Irrelevant if already exists.)
dir.create("www")
read_docx() %>%
body_add_par("My template file") %>%
print(., target = "www/template.docx")
# Existing file as Template
mytemplate <- read_docx(path = "www/template.docx")
# For Button 1
gen_pptx <- function(chart, file) {
read_pptx() %>%
add_slide(layout = "Title and Content", master = "Office Theme") %>%
ph_with_chart(chart = chart) %>%
print(target = file)
}
chart <- data.frame(x = letters[1:3], y = 1:3) %>%
ms_barchart(x = "x", y = "y")
# For button 2
gen_docx <- function(file) {
read_docx() %>%
body_add_par("Hello World") %>%
print(target = file)
}
# For button 3
gen_docx2 <- function(file, doc) {
file %>%
body_add_par("Hello World") %>%
body_add_docx(src = doc) %>%
print(target = file)
}
ui <- fluidPage(
titlePanel("Example"),
downloadButton("chart", "Get Chart"),
downloadButton("document", "Get New Doc"),
downloadButton("document2", "Get Doc from Template"),
tags$hr(),
tags$p("Example hyperlink works"),
tags$a(href='template.docx', target='_blank', 'Can only download from www folder', download = 'template.docx')
)
server <- function(input, output) {
output$chart <- downloadHandler(
filename = function() paste0("chart_", Sys.Date(), ".pptx"),
content = function(file) {
file_pptx <- tempfile(fileext = ".pptx")
gen_pptx(chart, file_pptx)
file.rename( from = file_pptx, to = file )
}
)
output$document <- downloadHandler(
filename = function() paste0("doc_", Sys.Date(), ".docx"),
content = function(file) {
file_docx <- tempfile(fileext = ".docx")
gen_docx(file_docx)
file.rename( from = file_docx, to = file )
}
)
output$document2 <- downloadHandler(
filename = function() paste0("doc_", Sys.Date(), ".docx"),
content = function(file) {
file_docx <- tempfile(fileext = ".docx")
gen_docx2(file_docx, mytemplate)
file.rename( from = file_docx, to = file )
}
)
}
shinyApp(ui = ui, server = server)
Do not use print to generate docx file in helper function gen_docx2.
Instead, you should use print as a last step in content function to return file to the downloadHandler.
Simple example:
gen_docx2 <- function(file, doc) {
file %>%
body_add_par("Hello World") %>%
body_add_docx(src = doc)
}
notice the function above does not print anything
outputdocument2 <- downloadHandler(
filename = function() {
paste0("doc_", Sys.Date(), ".docx")
},
content = function(file) {
doc <- read_docx() %>% gen_docx2(file_docx, mytemplate)
print(doc, target = file)
}
)
Use read_docx() to generate temporary word file and then use print(doc, target = file) in the end to pass it to the downloadHandler. The function file.rename is not needed.
When exporting a flextable to *.pptx using 'officer' if the flextable has a footer it seems to corrupt the power point and it needs to be repaired.
I've tried using the other footer functions. I also tried adding a header to see if that similar code throws the error. Adding headers seem fine.
I also tried going back to officer v. 0.3.3.
Officer is v. 0.3.4
flextable is v. 0.5.4
R is 3.6.0 "Planting of a Tree"
library(officer)
library(flextable)
library(dplyr)
pdoc <- read_pptx()
footer <- "foot"
header <- "head"
myft <- iris %>% head() %>% flextable()
myft <- myft %>% add_header_lines( values = header)
pdoc <- pdoc %>%
add_slide(layout = "Title and Content", master = "Office Theme") %>%
ph_with_flextable(myft , type = "body")
print(pdoc, "test1passes.pptx")
myft <- myft %>% add_footer_lines( values = footer)
pdoc <- pdoc %>%
add_slide(layout = "Title and Content", master = "Office Theme") %>%
ph_with_flextable(myft , type = "body")
print(pdoc, "test2fails.pptx")
I can open the "test1passes.pptx" file with no problem.
When I open the "test2fails.pptx" I get an error from pptx saying the file is corrupted when I expected that it should open with no problem.