Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
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:
A4 size in pixels
https://convertermaniacs.com/px-to-inch/convert-1263-pixels-to-inches.html
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.