excel_cli/json_export/
extractors.rs1use anyhow::Result;
2use std::collections::HashMap;
3
4use crate::excel::Sheet;
5
6pub fn extract_horizontal_headers(
7 sheet: &Sheet,
8 header_rows: usize,
9) -> Result<HashMap<usize, String>> {
10 let mut headers = HashMap::new();
11 let mut last_values_by_row: HashMap<usize, String> = HashMap::new();
12
13 for col_idx in 1..sheet.data[0].len() {
14 let mut header_parts = Vec::new();
15
16 for row_idx in 1..=header_rows {
17 if row_idx < sheet.data.len() && col_idx < sheet.data[row_idx].len() {
18 let cell_value = &sheet.data[row_idx][col_idx].value;
19
20 if cell_value.is_empty() {
21 if let Some(last_value) = last_values_by_row.get(&row_idx) {
22 header_parts.push(last_value.clone());
23 } else if row_idx > 1 {
24 let prev_row_idx = row_idx - 1;
25 let prev_header_parts_len = header_parts.len();
26
27 if prev_header_parts_len > 0 && prev_row_idx >= 1 {
28 header_parts.push(header_parts[prev_header_parts_len - 1].clone());
29 }
30 }
31 } else {
32 last_values_by_row.insert(row_idx, cell_value.clone());
33 header_parts.push(cell_value.clone());
34 }
35 }
36 }
37
38 let header = header_parts.join("-");
39
40 if !header.is_empty() {
41 headers.insert(col_idx, header);
42 }
43 }
44
45 Ok(headers)
46}
47
48pub fn extract_vertical_headers(
49 sheet: &Sheet,
50 header_cols: usize,
51) -> Result<HashMap<usize, String>> {
52 let mut headers = HashMap::new();
53 let mut last_values_by_col: HashMap<usize, String> = HashMap::new();
54
55 for row_idx in 1..sheet.data.len() {
56 let mut header_parts = Vec::new();
57
58 for col_idx in 1..=header_cols {
59 if col_idx < sheet.data[0].len() && row_idx < sheet.data.len() {
60 let cell_value = &sheet.data[row_idx][col_idx].value;
61
62 if cell_value.is_empty() {
63 if let Some(last_value) = last_values_by_col.get(&col_idx) {
64 header_parts.push(last_value.clone());
65 } else if col_idx > 1 {
66 let prev_col_idx = col_idx - 1;
67 let prev_header_parts_len = header_parts.len();
68
69 if prev_header_parts_len > 0 && prev_col_idx >= 1 {
70 header_parts.push(header_parts[prev_header_parts_len - 1].clone());
71 }
72 }
73 } else {
74 last_values_by_col.insert(col_idx, cell_value.clone());
75 header_parts.push(cell_value.clone());
76 }
77 }
78 }
79
80 let header = header_parts.join("-");
81
82 if !header.is_empty() {
83 headers.insert(row_idx, header);
84 }
85 }
86
87 Ok(headers)
88}