excel_cli/json_export/
extractors.rs

1use 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}