Cover Up

Adding full sized cover images to Word documents programatically with officer, officedown, and purrr
I needed to add full size (A4, portrait) images to the first page of my Word document ( there are 13, all 30+ pages, which I’m generating in RMarkdown, as per previous post).
I didn’t want to do this by hand, especially when I discovered that due to margins and page settings, each image would have to be resized to fit on the page. (I tried adding the full sized image to a blank Word document but it was too large, and resulting attempts to resize it did not work well. I did not want to do this multiple times).
Here was the plan:
- get all the full size images my colleagues created and save them in a source folder
- automate the process of creating resized copies, and save those in another folder
- create a blank, one page, Word document for each image
- loop through and add the resized images to the corresponding blank document
- use {officer} to add these blank documents as my ‘cover’ for each report.
I saved all the original , full size images into a ‘resources’ folder inside my ‘img’ folder, then looped through them and resized them as below.
library(here)
library(purrr)
library(magick)
setwd(here("img", "resources"))
files <- dir()
# taking dimensions at 90%
files_read <- map(files, image_read)
files_resized <- map(files_read, ~ image_resize(.x,
geometry = geometry_size_percent(width = 90)))
outdir <- paste0(here("img","resized", files))
walk2(files_resized, outdir, ~ image_write(.x, path = .y))
The next bit was to create blank documents, and add the resized images.
I created 2 functions; create_covers
and add_images
library(officer)
library(officedown)
library(here)
library(magrittr)
create_covers <- function(areas) {
# get list of resized images to insert into blank doc
areas <- dir(here("img","resized"), full.names = TRUE)
outnames <- gsub(".png", ".docx", areas)
# save these to a 'covers' folder outside the main 'img' folder
outnames <- gsub("img/resized","covers",outnames)
# read the blank source doc
temp <- read_docx(here("covers","blank_cover.docx"))
# write out the blank files
walk(outnames,~ print(temp, .x))
}
add_images <- function(outnames, images, width = 9.3,
height = 13.15625,
position_at = "after") {
for (i in seq_along(outnames)) {
read_docx(outnames[i]) %>%
cursor_begin() %>%
body_remove() %>%
body_add_img(., images[i],
width = 9.3, # was 9.5 @92%
height = 13.15625, # was 13.4375 @ 92%
pos = position_at) %>%
print(.,outnames[i])
}
}
With those functions in place, here’s how I created the covers and added the images:
areas <- dir(here("img","resized"), full.names = TRUE)
# create the blank covers - takes some time
create_covers(areas)
# replace the file extension
outnames <- gsub(".png", ".docx", areas)
outnames <- gsub("img/resized","covers", outnames)
images <- dir(here("img","resized"), full.names = TRUE)
# for loops FTW
add_images(outnames, images)
The final step was to add this to my Rmd file
cover_page_margin <- officer::page_mar(bottom = 0.00787402, # .02 cm
top = 0.00787402,
right = 0.015748, #.04 cm
left = 0.015748,
header = 0,
footer = 0,
gutter = 0.00393701) # .01 cm
cover_section <- officer::prop_section(page_margins = cover_page_margin,
page_size = (page_size(orient = "portrait")),
type = "continuous")
And also :
officer::block_pour_docx(here("covers",eval(paste0(params$HSCP,".docx"))))
officer::block_section(cover_section)
This set the margins for the cover ( I had to have some space assigned), then created the section properties for the cover.
The block_pour_docx
inserted the relevant cover page, and the block_section
applied the cover section layout. This has to be placed after the content, as opposed to before it, as you may have expected.
With all this in place, the front covers look good, with a fairly even border all round.
Useful links:
Doing this work involves constantly converting between inches, centimetres, and pixels - here are some links that will help:
[https://www.a4-size.com/a4-size-in-pixels/]https://www.a4-size.com/a4-size-in-pixels/
[https://convertermaniacs.com/px-to-inch/convert-1263-pixels-to-inches.html]https://convertermaniacs.com/px-to-inch/convert-1263-pixels-to-inches.html