1use umya_spreadsheet::Worksheet;
2
3use crate::cell::{read_cell_value, write_cell_value};
4use crate::types::{CellInfo, CellValue, MergeRange, RangeData};
5
6fn col_num_to_letter(mut col: u32) -> String {
8 let mut result = String::new();
9 while col > 0 {
10 col -= 1;
11 result.insert(0, (b'A' + (col % 26) as u8) as char);
12 col /= 26;
13 }
14 result
15}
16
17pub fn get_cell_value(sheet: &Worksheet, row: u32, col: u32) -> CellValue {
19 match sheet.get_cell((col, row)) {
20 Some(cell) => read_cell_value(cell),
21 None => CellValue::Empty,
22 }
23}
24
25pub fn set_cell_value(sheet: &mut Worksheet, row: u32, col: u32, value: &CellValue) {
27 let cell = sheet.get_cell_mut((col, row));
28 write_cell_value(cell, value);
29}
30
31pub fn get_cell_info(sheet: &Worksheet, row: u32, col: u32) -> CellInfo {
33 let value = get_cell_value(sheet, row, col);
34 let formula = sheet
35 .get_cell((col, row))
36 .map(|c| {
37 let f = c.get_formula();
38 if f.is_empty() {
39 None
40 } else {
41 Some(f.to_string())
42 }
43 })
44 .flatten();
45
46 CellInfo {
47 row,
48 col,
49 value,
50 formula,
51 }
52}
53
54pub fn read_range(
56 sheet: &Worksheet,
57 start_row: u32,
58 start_col: u32,
59 end_row: u32,
60 end_col: u32,
61) -> RangeData {
62 let mut rows = Vec::new();
63 for r in start_row..=end_row {
64 let mut row = Vec::new();
65 for c in start_col..=end_col {
66 row.push(get_cell_value(sheet, r, c));
67 }
68 rows.push(row);
69 }
70 RangeData {
71 start_row,
72 start_col,
73 end_row,
74 end_col,
75 rows,
76 }
77}
78
79pub fn write_range(sheet: &mut Worksheet, data: &RangeData) {
81 for (ri, row) in data.rows.iter().enumerate() {
82 for (ci, val) in row.iter().enumerate() {
83 let r = data.start_row + ri as u32;
84 let c = data.start_col + ci as u32;
85 set_cell_value(sheet, r, c, val);
86 }
87 }
88}
89
90pub fn insert_rows(sheet: &mut Worksheet, at: u32, count: u32) {
92 for _ in 0..count {
93 sheet.insert_new_row(&at, &1);
94 }
95}
96
97pub fn delete_rows(sheet: &mut Worksheet, at: u32, count: u32) {
99 for _ in 0..count {
100 sheet.remove_row(&at, &1);
101 }
102}
103
104pub fn insert_columns(sheet: &mut Worksheet, at: u32, count: u32) {
106 for _ in 0..count {
107 sheet.insert_new_column_by_index(&at, &1);
108 }
109}
110
111pub fn delete_columns(sheet: &mut Worksheet, at: u32, count: u32) {
113 for _ in 0..count {
114 sheet.remove_column_by_index(&at, &1);
115 }
116}
117
118pub fn set_row_height(sheet: &mut Worksheet, row: u32, height: f64) {
120 sheet.get_row_dimension_mut(&row).set_height(height);
121}
122
123pub fn set_column_width(sheet: &mut Worksheet, col: u32, width: f64) {
125 sheet
126 .get_column_dimension_by_number_mut(&col)
127 .set_width(width);
128}
129
130pub fn get_row_height(sheet: &Worksheet, row: u32) -> f64 {
132 sheet
133 .get_row_dimension(&row)
134 .map(|r| *r.get_height())
135 .unwrap_or(15.0)
136}
137
138pub fn get_column_width(sheet: &Worksheet, col: u32) -> f64 {
140 sheet
141 .get_column_dimension_by_number(&col)
142 .map(|c| *c.get_width())
143 .unwrap_or(8.43)
144}
145
146pub fn merge_cells(sheet: &mut Worksheet, range: &MergeRange) {
148 let range_str = format!(
149 "{}{}:{}{}",
150 col_num_to_letter(range.start_col),
151 range.start_row,
152 col_num_to_letter(range.end_col),
153 range.end_row,
154 );
155 sheet.add_merge_cells(&range_str);
156}
157
158pub fn unmerge_cells(sheet: &mut Worksheet, range: &MergeRange) {
160 let range_str = format!(
161 "{}{}:{}{}",
162 col_num_to_letter(range.start_col),
163 range.start_row,
164 col_num_to_letter(range.end_col),
165 range.end_row,
166 );
167 let merges = sheet.get_merge_cells_mut();
169 merges.retain(|r| r.get_range() != range_str);
170}
171
172pub fn get_merged_cells(sheet: &Worksheet) -> Vec<MergeRange> {
174 sheet
175 .get_merge_cells()
176 .iter()
177 .filter_map(|r| {
178 let start_col = r.get_coordinate_start_col()?.get_num().clone();
179 let start_row = r.get_coordinate_start_row()?.get_num().clone();
180 let end_col = r.get_coordinate_end_col()?.get_num().clone();
181 let end_row = r.get_coordinate_end_row()?.get_num().clone();
182 Some(MergeRange {
183 start_row,
184 start_col,
185 end_row,
186 end_col,
187 })
188 })
189 .collect()
190}