davidgohel / officer

:cop: officer: office documents from R
https://ardata-fr.github.io/officeverse/
Other
602 stars 107 forks source link

Maintain landscape orientation when merging two docx together #431

Closed eusebe closed 2 years ago

eusebe commented 2 years ago

Hello,

Thank you very much for this fantastic package.

I'm trying to figure out how to merge to docx documents, one with a portrait orientation, the second with a landscape orientation.

you will find some of my attempts thereafter, but in summary, it seems impossible to obtain a merged document with the first page having a portrait orientation, and the second a landscape orientation.

Do you have an idea on how to do this?

Thank you very much, David


file1 <- "file1.docx"
file2 <- "file2.docx"
file3 <- "file3.docx"
file4 <- "file4.docx"
file5 <- "file5.docx"
file6 <- "file6.docx"
file7 <- "file7.docx"
file8 <- "file8.docx"

x <- read_docx()
x <- body_add_par(x, "hello world 1", style = "Normal")
print(x, target = file1)

x <- read_docx()
x <- body_add_par(x, "hello world 2", style = "Normal")
x <- body_end_section_landscape(x)
print(x, target = file2)

## First portrait, then landscape, pos = "after" 
x <- read_docx(path = file1)
x <- body_add_break(x)
x <- body_add_docx(x, src = file2)
print(x, target = file3) # => three pages : portrait-portrait-portrait (empty)

## First portrait, then landscape, pos = "on" 
x <- read_docx(path = file1)
x <- body_add_break(x)
x <- body_add_docx(x, src = file2, pos = "on")
print(x, target = file4) # => two pages : portrait-portrait (empty)

## First portrait, then landscape, pos = "before" => three pages : portrait-portrait (empty)-portrait (empty)
x <- read_docx(path = file1)
x <- body_add_break(x)
x <- body_add_docx(x, src = file2, pos = "before")
print(x, target = file5)

## First landscape, then portrait, pos = "after" 
x <- read_docx(path = file2)
x <- body_add_break(x)
x <- body_add_docx(x, src = file1)
print(x, target = file6) # => three pages : landscape-portrait (empty)-portrait

## First landscape, then portrait => two pages : landscape-portrait
x <- read_docx(path = file2)
x <- body_add_break(x)
x <- body_add_docx(x, src = file1, pos = "on")
print(x, target = file7)

## First landscape, then portrait 
x <- read_docx(path = file2)
x <- body_add_break(x)
x <- body_add_docx(x, src = file1, pos = "before")
print(x, target = file8) # => three pages : landscape-portrait-portrait (empty)
``
davidgohel commented 2 years ago

Hello David,

Yes, I can help you. Word sections are weird, it's not my implementation ;)

You need to know they apply to the content placed before the section definition...

- content A
- content B
- section C
- content D
- section E
- content F

From A to B, the section C is used. Content D is using section E. Content F is using the default section. Let me know if you still have questions.

library(officer)

file1 <- "file1.docx"
file2 <- "file2.docx"
file3 <- "file3.docx"

x <- read_docx()
x <- body_add_par(x, "hello world 1", style = "Normal")
print(x, target = file1)

x <- read_docx()
x <- body_add_par(x, "hello world 2", style = "Normal")
print(x, target = file2)

## First portrait, then landscape
psportrait <- prop_section(
  page_size = page_size(orient = "portrait")
)
pslandscape <- prop_section(
  page_size = page_size(orient = "landscape")
)

# solution 1: keep default section as portrait
x <- read_docx(path = file1)

x <- body_end_block_section(x, value = block_section(psportrait))
# as block_section(psportrait) as been set, all content before 
# that ending section until previous section end is portrait

x <- body_add_docx(x, src = file2)

x <- body_end_block_section(x, value = block_section(pslandscape))
# as block_section(pslandscape) as been set, all content before 
#that ending section until previous section ('psportrait') end is landscape

print(x, target = file3) 

# solution 2: set default section as landscape
x <- read_docx(path = file1)
x <- body_end_block_section(x, value = block_section(psportrait))
x <- body_add_docx(x, src = file2)
x <- body_set_default_section(x, value = pslandscape)
print(x, target = file3) 
eusebe commented 2 years ago

Thanks David! Your explanations are very clear!

If I understand well, it seems impossible to first print a docx document in landscape format, and then to integrate it as is with body_add_docx? You always need to apply the landscape style section after body_add_docx command?

More precisely, this will never work?

file1 <- "file1.docx"
file2 <- "file2.docx"
file3 <- "file3.docx"

psportrait <- prop_section(
  page_size = page_size(orient = "portrait")
)
pslandscape <- prop_section(
  page_size = page_size(orient = "landscape")
)

x <- read_docx()
x <- body_add_par(x, "hello world 1", style = "Normal")
x <- body_end_block_section(x, value = block_section(psportrait))
print(x, target = file1)

x <- read_docx()
x <- body_add_par(x, "hello world 2", style = "Normal")
x <- body_end_block_section(x, value = block_section(pslandscape))
print(x, target = file2)

x <- read_docx(path = file1)
x <- body_add_docx(x, src = file2)
print(x, target = file3) 
davidgohel commented 2 years ago

I may have misunderstood the question. It is possible to have 2 docs and split them into the section of your choice in a final document.

library(officer)

file1 <- "file1.docx"
file2 <- "file2.docx"
file3 <- "file3.docx"

x <- read_docx()
x <- body_add_par(x, "hello world 1", style = "Normal")
print(x, target = file1)

x <- read_docx()
x <- body_add_par(x, "hello world 2", style = "Normal")
print(x, target = file2)

## First portrait, then landscape
psportrait <- prop_section(
  page_size = page_size(orient = "portrait")
)
pslandscape <- prop_section(
  page_size = page_size(orient = "landscape")
)

# solution 1: keep default section as portrait
x <- read_docx(path = file1)

x <- body_end_block_section(x, value = block_section(pslandscape))

x <- body_add_docx(x, src = file2)

x <- body_end_block_section(x, value = block_section(psportrait))

print(x, target = file3) 
Capture d’écran 2022-06-09 à 21 33 24

However, I believe that Word does not keep the sections of the embedded documents as is. This must be a feature of Word (officer just adds it but does not change the file). So it is not possible to add a docx into another docx and preserve the original sections, they must be defined in the target/final document.

eusebe commented 2 years ago

Thank you David.

My question was related to the following issue:

I understand now that you have to set the sections in landscape format at merge time, so I will proceed like this.

Thanks a lot!

davidgohel commented 2 years ago

Thanks for the feedback. I also tried manually with Word and got the same result, so I am pretty sure this is a Word feature (issue??). As you said, it's better to add the sections in the final document.

I can close this issue now :)

github-actions[bot] commented 1 year ago

This old thread has been automatically locked. If you think you have found something related to this, please open a new issue and link to this old issue if necessary.