Skip to main content

docx_metadata_and_protection/
docx_metadata_and_protection.rs

1//! Word document metadata (docProps/core.xml and app.xml, plus custom
2//! properties) and document protection. Metadata and protection are both
3//! whole-document settings, so this example writes two small files rather
4//! than two pages of a single one.
5//!
6//! Run with: `cargo run -p office-toolkit --example docx_metadata_and_protection`
7
8use std::path::{Path, PathBuf};
9
10use office_toolkit::SaveToFile;
11use office_toolkit::prelude::*;
12use office_toolkit::word::{
13    CustomPropertyValue, DocumentProperties, ExtendedProperties, ProtectionKind,
14};
15
16fn main() -> office_toolkit::Result<()> {
17    let properties = DocumentProperties::new()
18        .with_title("Quarterly Report")
19        .with_subject("Q3 results")
20        .with_creator("Jane Doe")
21        .with_keywords("finance, quarterly, report")
22        .with_description("An example document showing document properties.")
23        .with_category("Finance")
24        .with_content_status("Draft");
25    let extended_properties = ExtendedProperties::new()
26        .with_company("Acme Corp.")
27        .with_manager("Jane Manager");
28
29    let metadata_document = Document::new()
30        .with_properties(properties)
31        .with_extended_properties(extended_properties)
32        .with_custom_property("ProjectCode", CustomPropertyValue::Text("Q3-2026".to_string()))
33        .with_custom_property("Budget", CustomPropertyValue::Number(125_000.0))
34        .with_custom_property("Approved", CustomPropertyValue::Bool(false))
35        .with_custom_property("RevisionCount", CustomPropertyValue::Int(3))
36        .with_track_changes(true)
37        .with_paragraph(Paragraph::with_text(
38            "This document carries standard properties (title/author/subject/...), four custom properties, \
39             and has track changes turned on — check File > Info in Word to see them.",
40        ));
41    let metadata_path = output_path("docx_metadata.docx");
42    metadata_document.save_to_file(&metadata_path)?;
43    println!("Wrote {}", metadata_path.display());
44
45    let protected_document = Document::new()
46        .with_protection(ProtectionKind::ReadOnly)
47        .with_paragraph(Paragraph::with_text(
48            "This document is protected as read-only — Word will ask for a password before allowing edits.",
49        ));
50    let protected_path = output_path("docx_protected.docx");
51    protected_document.save_to_file(&protected_path)?;
52    println!("Wrote {}", protected_path.display());
53
54    Ok(())
55}
56
57/// Every example in this directory writes its output under
58/// `tests-data/output/`, resolved relative to this crate's own manifest so
59/// it works no matter what directory `cargo run` was invoked from.
60fn output_path(filename: &str) -> PathBuf {
61    Path::new(env!("CARGO_MANIFEST_DIR"))
62        .join("../../tests-data/output")
63        .join(filename)
64}