3

I have seen that there is already a question about that known limitation for pptx. But is there a workaround like converting it first into an image and import that to pptx or something similar? I don‘t care that the table can‘t be edited afterwards, that would actually be an advantage.

Edit: Here as wished a minimal example where the Graphs are not included in the pptx.

library(flextable)
library(data.table)
library(officer)
library(dplyr)
z <- as.data.table(ggplot2::diamonds)
z <- z[, list(
  price = mean(price, na.rm = TRUE),
  list_col = list(.SD$x)
), by = "cut"]
z

ft <- flextable(data = z) %>%
  compose(j = "list_col", value = as_paragraph(
    plot_chunk(value = list_col, type = "dens", col = "pink", 
               width = 1.5, height = .4, free_scale = TRUE)
  )) %>%
  colformat_double(big.mark = " ", suffix = " $") %>% 
  set_header_labels(list_col = "density") %>% 
  autofit()
ft
print(ft, preview = "pptx")
Swyler
  • 124
  • 1
  • 12
  • Could you please share some code you have tried and reproducible data using `dput`? So we can help you better. – Quinten Aug 19 '22 at 13:59

3 Answers3

3

You can use the new grid output feature for that—the following code demo some of its features (see ?gen_grob for more informations):

library(flextable)
library(data.table)
library(officer)
library(dplyr)

z <- as.data.table(ggplot2::diamonds)
z <- z[, list(
  price = mean(price, na.rm = TRUE),
  list_col = list(.SD$x)
), by = "cut"]
z

ft <- flextable(data = z) %>%
  mk_par(j = "list_col", value = as_paragraph(
    plot_chunk(value = list_col, type = "dens", col = "pink", 
               width = 1.5, height = .4, free_scale = TRUE)
  )) %>%
  colformat_double(big.mark = " ", suffix = " $") %>% 
  set_header_labels(list_col = "density") %>% 
  autofit()
ft

# create powerpoint
ppt <- read_pptx() %>% 
  add_slide() %>% 
  ph_with(value = plot_instr(code = plot(ft, fit = FALSE, scaling = "fixed")), 
                         location = ph_location_type()) %>% 
  add_slide() %>% 
  ph_with(value = plot_instr(code = plot(ft)), 
                         location = ph_location_fullsize()) %>% 
  add_slide() %>% 
  ph_with(value = plot_instr(code = plot(ft, fit = "width", scaling = "min")), 
                         location = ph_location_fullsize())
# save powerpoint
print(ppt, preview = "pptx", target = 'output.pptx')

enter image description here

David Gohel
  • 9,180
  • 2
  • 16
  • 34
2

You could save your table as an image using save_as_image from officer package. After that you can add the image using ph_with where you add a value using the external_img function to add your image. Here is a reproducible example:

library(flextable)
library(data.table)
library(officer)
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:data.table':
#> 
#>     between, first, last
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
z <- as.data.table(ggplot2::diamonds)
z <- z[, list(
  price = mean(price, na.rm = TRUE),
  list_col = list(.SD$x)
), by = "cut"]
z
#>          cut    price                          list_col
#> 1:     Ideal 3457.542 3.95,3.93,4.35,4.31,4.49,4.49,...
#> 2:   Premium 4584.258 3.89,4.20,3.88,3.79,4.38,3.97,...
#> 3:      Good 3928.864 4.05,4.34,4.25,4.23,4.23,4.26,...
#> 4: Very Good 3981.760 3.94,3.95,4.07,4.00,4.21,3.85,...
#> 5:      Fair 4358.758 3.87,6.45,6.27,5.57,5.63,6.11,...

ft <- flextable(data = z) %>%
  compose(j = "list_col", value = as_paragraph(
    plot_chunk(value = list_col, type = "dens", col = "pink", 
               width = 1.5, height = .4, free_scale = TRUE)
  )) %>%
  colformat_double(big.mark = " ", suffix = " $") %>% 
  set_header_labels(list_col = "density") %>% 
  autofit()

# image
image <- save_as_image(ft, path = '~/Downloads/table.png')
# create powerpoint
ppt <- read_pptx() %>% add_slide()
slide <- ppt %>% ph_with(value = external_img(image), location = ph_location(left = 0, top = 0))
# save powerpoint
print(ppt, preview = "pptx", target = 'output.pptx')

enter image description here

Created on 2022-09-23 with reprex v2.0.2

Quinten
  • 35,235
  • 5
  • 20
  • 53
-1

flextable can naturally be placed into powerpoint pptx with Officer https://ardata-fr.github.io/officeverse/officer-for-powerpoint.html

a simple example

library(flextable)
library(officer)
myflex <- flextable(head(iris)) 

my_pres <- read_pptx() 
my_pres <- add_slide(my_pres, layout = "Title and Content", master = "Office Theme")
my_pres <- ph_with(my_pres, value =myflex, 
                   location = ph_location_type(type = "body")) 

print(my_pres, target = "example.pptx") 

I earlier incorrectly called out htmltools_value() as being relevant, but this would only be so if you wanted to put a flextable (myflex) into a shiny renderUI - which is something I did a lot recently...

Nir Graham
  • 2,567
  • 2
  • 6
  • 10
  • I am able to transfer it to html but how do I integrate it to pptx via officer? Could you add some lines to my minimum example? – Swyler Aug 24 '22 at 08:00
  • My advice is to work through the officer documentation linked to. I prefer to make a powerpoint template that officer reads in , makes slides from and injects my contents to. I will have set placeholders in powerpoint for where I want my content to appear on a given slide. the officer function to place content is `ph_with()` [link](https://ardata-fr.github.io/officeverse/officer-for-powerpoint.html#add-content-to-a-slide) – Nir Graham Aug 24 '22 at 09:04
  • I can‘t find anything about adding html to pptx. By adding the html via ph_with() I get the following errormessage: Error in UseMethod("ph_with", value) : no applicable method for 'ph_with' applied to an object of class "c('shiny.tag.list', 'list')" – Swyler Aug 24 '22 at 10:18
  • I apologise, I misinformed you. I will edit my answer – Nir Graham Aug 24 '22 at 11:51