Skip to main content

docx_page_layout/
docx_page_layout.rs

1//! Word page layout: page size/orientation/margins/columns, and default vs.
2//! first-page vs. even-page headers and footers. Page setup applies to the
3//! whole document, so this example still spans several pages (via manual
4//! page breaks) to show the header/footer alternation in Word's own page
5//! view.
6//!
7//! Run with: `cargo run -p office-toolkit --example docx_page_layout`
8
9use std::path::{Path, PathBuf};
10
11use office_toolkit::SaveToFile;
12use office_toolkit::prelude::*;
13use office_toolkit::word::{HeaderFooter, Orientation, PageSetup, Run};
14
15fn main() -> office_toolkit::Result<()> {
16    let path = output_path("docx_page_layout.docx");
17
18    let page_setup = PageSetup::new()
19        .with_size_twips(16_838, 11_906) // A4 landscape, in twentieths of a point
20        .with_orientation(Orientation::Landscape)
21        .with_margins_twips(1_440, 1_440, 1_800, 1_800) // top, bottom, left, right
22        .with_header_footer_margins_twips(720, 720)
23        .with_gutter_twips(0)
24        .with_columns(2);
25
26    let default_header =
27        HeaderFooter::new().with_paragraph(Paragraph::with_text("Default header — every page"));
28    let default_footer =
29        HeaderFooter::new().with_paragraph(Paragraph::with_text("Default footer — every page"));
30    let first_header = HeaderFooter::new()
31        .with_paragraph(Paragraph::with_text("First-page header — cover page only"));
32    let even_header = HeaderFooter::new().with_paragraph(Paragraph::with_text("Even-page header"));
33
34    let document = Document::new()
35        .with_page_setup(page_setup)
36        .with_header(default_header)
37        .with_footer(default_footer)
38        .with_header_first(first_header)
39        .with_header_even(even_header)
40        .with_paragraph(heading("Page setup: A4 landscape, custom margins, two columns", false))
41        .with_paragraph(Paragraph::with_text(
42            "This document is landscape A4, with wider left/right margins than top/bottom, and its body text \
43             flows in two columns. Look at the page in Word's Layout view to see the effect.",
44        ))
45        .with_paragraph(heading("Headers and footers", true))
46        .with_paragraph(Paragraph::with_text(
47            "Page 1 (this page) uses the first-page header, since \"different first page\" headers are set. \
48             Every other page uses the default header shown above, and every page uses the default footer.",
49        ))
50        .with_paragraph(heading("A third page, to see the default header again", true))
51        .with_paragraph(Paragraph::with_text(
52            "If Word is configured to show even/odd pages differently, this page alternates between the \
53             default and even-page header depending on whether it lands on an even or odd page number.",
54        ));
55
56    document.save_to_file(&path)?;
57    println!("Wrote {}", path.display());
58    Ok(())
59}
60
61fn heading(text: &str, new_page: bool) -> Paragraph {
62    Paragraph::new()
63        .with_run(Run::new(text).with_bold(true).with_font_size(28))
64        .with_page_break_before(new_page)
65}
66
67/// Every example in this directory writes its output under
68/// `tests-data/output/`, resolved relative to this crate's own manifest so
69/// it works no matter what directory `cargo run` was invoked from.
70fn output_path(filename: &str) -> PathBuf {
71    Path::new(env!("CARGO_MANIFEST_DIR"))
72        .join("../../tests-data/output")
73        .join(filename)
74}