oca_data_entry/format/
xlsx.rs1use std::path::Path;
2
3use umya_spreadsheet::{
4 new_file,
5 writer::xlsx::{write, XlsxError},
6};
7
8use crate::model::EntrySchema;
9
10pub struct XlsxOptions {
11 pub include_metadata_row: bool,
12 pub label_lang: Option<String>,
13 pub metadata_lang: Option<String>,
14}
15
16pub fn write_xlsx(schema: &EntrySchema, path: &Path, opts: &XlsxOptions) -> Result<(), XlsxError> {
17 let mut book = new_file();
18 let sheet = book.get_sheet_by_name_mut("Sheet1").unwrap();
19
20 for (idx, attr) in schema.attributes.iter().enumerate() {
22 let col = column_name(idx + 1);
23 let header = if opts.label_lang.is_some() {
24 attr.label.clone().unwrap_or_else(|| attr.name.clone())
25 } else {
26 attr.name.clone()
27 };
28 let cell = format!("{}1", col);
29 sheet.get_cell_mut(cell.as_str()).set_value(header);
30 }
31
32 if opts.include_metadata_row {
33 let meta_name = "meta";
34 let _ = book.new_sheet(meta_name);
35 let meta_sheet = book.get_sheet_by_name_mut(meta_name).unwrap();
36
37 meta_sheet.get_cell_mut("A1").set_value("oca_bundle_said");
38 meta_sheet.get_cell_mut("B1").set_value(schema.said.clone());
39
40 meta_sheet.get_cell_mut("A3").set_value("attribute");
41 meta_sheet.get_cell_mut("B3").set_value("label");
42 meta_sheet.get_cell_mut("C3").set_value("type");
43
44 let mut row_meta = 4u32;
45 for attr in schema.attributes.iter() {
46 let cell = format!("A{}", row_meta);
47 meta_sheet
48 .get_cell_mut(cell.as_str())
49 .set_value(attr.name.clone());
50 if let Some(label) = &attr.label {
51 let cell = format!("B{}", row_meta);
52 meta_sheet
53 .get_cell_mut(cell.as_str())
54 .set_value(label.clone());
55 }
56 if let Some(t) = &attr.attr_type {
57 let cell = format!("C{}", row_meta);
58 meta_sheet.get_cell_mut(cell.as_str()).set_value(t.clone());
59 }
60 row_meta += 1;
61 }
62 }
63
64 write(&book, path)?;
65 Ok(())
66}
67
68fn column_name(mut idx: usize) -> String {
69 let mut name = String::new();
70 while idx > 0 {
71 let rem = (idx - 1) % 26;
72 name.insert(0, (b'A' + rem as u8) as char);
73 idx = (idx - 1) / 26;
74 }
75 name
76}