use std::collections::HashMap;
use std::path::Path;
use rdocx::{Alignment, BorderStyle, Document, Length};
fn main() {
let samples_dir = Path::new(env!("CARGO_MANIFEST_DIR"))
.parent()
.unwrap()
.parent()
.unwrap()
.join("samples");
std::fs::create_dir_all(&samples_dir).unwrap();
let template_path = samples_dir.join("_template.docx");
create_template(&template_path);
println!(" Created template: _template.docx");
let output_path = samples_dir.join("from_template.docx");
fill_template(&template_path, &output_path);
println!(" Created filled document: from_template.docx");
std::fs::remove_file(&template_path).ok();
println!("\nDone!");
}
fn create_template(path: &Path) {
let mut doc = Document::new();
doc.set_page_size(Length::inches(8.5), Length::inches(11.0));
doc.set_margins(
Length::inches(1.0),
Length::inches(1.0),
Length::inches(1.0),
Length::inches(1.0),
);
doc.set_header("{{company_name}} — Confidential");
doc.set_footer("Prepared by {{author_name}} on {{date}}");
doc.add_paragraph("{{company_name}}")
.style("Heading1")
.alignment(Alignment::Center);
doc.add_paragraph("Project Proposal")
.alignment(Alignment::Center);
doc.add_paragraph("");
doc.add_paragraph("Executive Summary").style("Heading2");
doc.add_paragraph(
"This proposal outlines the {{project_name}} project for {{company_name}}. \
The primary contact is {{contact_name}} ({{contact_email}}). \
The proposed start date is {{start_date}} with an estimated duration of {{duration}}.",
);
doc.add_paragraph("");
doc.add_paragraph("Key Details").style("Heading2");
{
let mut p = doc.add_paragraph("");
p.add_run("Project: ").bold(true);
p.add_run("{{project_name}}");
}
{
let mut p = doc.add_paragraph("");
p.add_run("Budget: ").bold(true);
p.add_run("{{budget}}");
}
{
let mut p = doc.add_paragraph("");
p.add_run("Status: ").bold(true);
p.add_run("{{status}}");
}
doc.add_paragraph("");
doc.add_paragraph("Team Members").style("Heading2");
{
let mut tbl = doc.add_table(4, 3);
tbl = tbl.borders(BorderStyle::Single, 4, "000000");
for col in 0..3 {
tbl.cell(0, col).unwrap().shading("2E75B6");
}
tbl.cell(0, 0).unwrap().set_text("Name");
tbl.cell(0, 1).unwrap().set_text("Role");
tbl.cell(0, 2).unwrap().set_text("Email");
tbl.cell(1, 0).unwrap().set_text("{{member1_name}}");
tbl.cell(1, 1).unwrap().set_text("{{member1_role}}");
tbl.cell(1, 2).unwrap().set_text("{{member1_email}}");
tbl.cell(2, 0).unwrap().set_text("{{member2_name}}");
tbl.cell(2, 1).unwrap().set_text("{{member2_role}}");
tbl.cell(2, 2).unwrap().set_text("{{member2_email}}");
tbl.cell(3, 0).unwrap().set_text("{{member3_name}}");
tbl.cell(3, 1).unwrap().set_text("{{member3_role}}");
tbl.cell(3, 2).unwrap().set_text("{{member3_email}}");
}
doc.add_paragraph("");
doc.add_paragraph("Deliverables").style("Heading2");
doc.add_paragraph("INSERTION_POINT");
doc.add_paragraph("");
doc.add_paragraph("Acceptance").style("Heading2");
doc.add_paragraph(
"By signing below, {{company_name}} agrees to the terms outlined in this proposal.",
);
{
let mut tbl = doc.add_table(2, 2);
tbl = tbl.borders(BorderStyle::Single, 4, "000000");
tbl.cell(0, 0)
.unwrap()
.set_text("Customer: ___________________");
tbl.cell(0, 1)
.unwrap()
.set_text("Provider: ___________________");
tbl.cell(1, 0).unwrap().set_text("Date: {{date}}");
tbl.cell(1, 1).unwrap().set_text("Date: {{date}}");
}
doc.set_title("{{company_name}} — Project Proposal Template");
doc.set_author("Template Generator");
doc.save(path).unwrap();
}
fn fill_template(template_path: &Path, output_path: &Path) {
let mut doc = Document::open(template_path).unwrap();
let mut replacements = HashMap::new();
replacements.insert("{{company_name}}", "Riverside Medical Center");
replacements.insert("{{project_name}}", "Network Security Upgrade");
replacements.insert("{{contact_name}}", "Dr. Sarah Chen");
replacements.insert("{{contact_email}}", "s.chen@riverside.org");
replacements.insert("{{start_date}}", "March 1, 2026");
replacements.insert("{{duration}}", "12 weeks");
replacements.insert("{{budget}}", "$185,000");
replacements.insert("{{status}}", "Pending Approval");
replacements.insert("{{author_name}}", "James Wilson");
replacements.insert("{{date}}", "February 22, 2026");
replacements.insert("{{member1_name}}", "James Wilson");
replacements.insert("{{member1_role}}", "Project Lead");
replacements.insert("{{member1_email}}", "j.wilson@provider.com");
replacements.insert("{{member2_name}}", "Maria Garcia");
replacements.insert("{{member2_role}}", "Security Architect");
replacements.insert("{{member2_email}}", "m.garcia@provider.com");
replacements.insert("{{member3_name}}", "David Park");
replacements.insert("{{member3_role}}", "Network Engineer");
replacements.insert("{{member3_email}}", "d.park@provider.com");
let count = doc.replace_all(&replacements);
println!(" Replaced {} placeholders", count);
if let Some(idx) = doc.find_content_index("INSERTION_POINT") {
doc.remove_content(idx);
doc.insert_paragraph(idx, "The following deliverables are included:");
let mut tbl = doc.insert_table(idx + 1, 5, 3);
tbl = tbl.borders(BorderStyle::Single, 4, "000000");
for col in 0..3 {
tbl.cell(0, col).unwrap().shading("E2EFDA");
}
tbl.cell(0, 0).unwrap().set_text("Phase");
tbl.cell(0, 1).unwrap().set_text("Description");
tbl.cell(0, 2).unwrap().set_text("Timeline");
tbl.cell(1, 0).unwrap().set_text("1. Discovery");
tbl.cell(1, 1)
.unwrap()
.set_text("Network assessment and asset inventory");
tbl.cell(1, 2).unwrap().set_text("Weeks 1-3");
tbl.cell(2, 0).unwrap().set_text("2. Design");
tbl.cell(2, 1)
.unwrap()
.set_text("Security architecture and policy design");
tbl.cell(2, 2).unwrap().set_text("Weeks 4-6");
tbl.cell(3, 0).unwrap().set_text("3. Implementation");
tbl.cell(3, 1)
.unwrap()
.set_text("Deploy monitoring and access controls");
tbl.cell(3, 2).unwrap().set_text("Weeks 7-10");
tbl.cell(4, 0).unwrap().set_text("4. Validation");
tbl.cell(4, 1)
.unwrap()
.set_text("Testing, training, and handover");
tbl.cell(4, 2).unwrap().set_text("Weeks 11-12");
println!(" Inserted deliverables table at position {}", idx);
}
doc.set_title("Riverside Medical Center — Network Security Upgrade Proposal");
doc.set_author("James Wilson");
doc.set_subject("Project Proposal");
doc.set_keywords("security, network, medical, proposal");
doc.save(output_path).unwrap();
}