1use umya_spreadsheet::structs::PatternValues;
2use umya_spreadsheet::Worksheet;
3
4use crate::types::{BorderEdge, CellStyleDto, MergeRange};
5
6pub fn get_cell_style(sheet: &Worksheet, row: u32, col: u32) -> CellStyleDto {
8 let Some(cell) = sheet.get_cell((col, row)) else {
9 return CellStyleDto::default();
10 };
11
12 let style = cell.get_style();
13
14 let (font_name, font_size, bold, italic, underline, strikethrough, font_color) =
15 if let Some(font) = style.get_font() {
16 (
17 Some(font.get_name().to_string()),
18 Some(*font.get_size()),
19 Some(*font.get_bold()),
20 Some(*font.get_italic()),
21 {
22 let u = font.get_underline();
23 Some(!u.is_empty() && u != "none")
24 },
25 Some(*font.get_strikethrough()),
26 Some(font.get_color().get_argb().to_string()),
27 )
28 } else {
29 (None, None, None, None, None, None, None)
30 };
31
32 let bg_color = style
33 .get_fill()
34 .and_then(|fill| fill.get_pattern_fill())
35 .and_then(|pf| pf.get_foreground_color())
36 .map(|c| c.get_argb().to_string());
37
38 let (border_top, border_bottom, border_left, border_right) =
39 if let Some(borders) = style.get_borders() {
40 (
41 Some(BorderEdge {
42 style: Some(borders.get_top().get_border_style().to_string()),
43 color: Some(borders.get_top().get_color().get_argb().to_string()),
44 }),
45 Some(BorderEdge {
46 style: Some(borders.get_bottom().get_border_style().to_string()),
47 color: Some(borders.get_bottom().get_color().get_argb().to_string()),
48 }),
49 Some(BorderEdge {
50 style: Some(borders.get_left().get_border_style().to_string()),
51 color: Some(borders.get_left().get_color().get_argb().to_string()),
52 }),
53 Some(BorderEdge {
54 style: Some(borders.get_right().get_border_style().to_string()),
55 color: Some(borders.get_right().get_color().get_argb().to_string()),
56 }),
57 )
58 } else {
59 (None, None, None, None)
60 };
61
62 let (horizontal_align, vertical_align, wrap_text) =
63 if let Some(alignment) = style.get_alignment() {
64 (
65 Some(format!("{:?}", alignment.get_horizontal())),
66 Some(format!("{:?}", alignment.get_vertical())),
67 Some(*alignment.get_wrap_text()),
68 )
69 } else {
70 (None, None, None)
71 };
72
73 let number_format = style
74 .get_number_format()
75 .map(|nf| nf.get_format_code().to_string());
76
77 CellStyleDto {
78 font_name,
79 font_size,
80 bold,
81 italic,
82 underline,
83 strikethrough,
84 font_color,
85 bg_color,
86 border_top,
87 border_bottom,
88 border_left,
89 border_right,
90 horizontal_align,
91 vertical_align,
92 wrap_text,
93 number_format,
94 }
95}
96
97pub fn apply_cell_style(sheet: &mut Worksheet, row: u32, col: u32, dto: &CellStyleDto) {
99 let cell = sheet.get_cell_mut((col, row));
100 let style = cell.get_style_mut();
101
102 if let Some(ref name) = dto.font_name {
104 style.get_font_mut().set_name(name);
105 }
106 if let Some(size) = dto.font_size {
107 style.get_font_mut().set_size(size);
108 }
109 if let Some(bold) = dto.bold {
110 style.get_font_mut().set_bold(bold);
111 }
112 if let Some(italic) = dto.italic {
113 style.get_font_mut().set_italic(italic);
114 }
115 if let Some(underline) = dto.underline {
116 let val = if underline { "single" } else { "none" };
117 style.get_font_mut().set_underline(val);
118 }
119 if let Some(strike) = dto.strikethrough {
120 style.get_font_mut().set_strikethrough(strike);
121 }
122 if let Some(ref color) = dto.font_color {
123 style.get_font_mut().get_color_mut().set_argb(color);
124 }
125
126 if let Some(ref bg) = dto.bg_color {
128 style
129 .get_fill_mut()
130 .get_pattern_fill_mut()
131 .get_foreground_color_mut()
132 .set_argb(bg);
133 style
134 .get_fill_mut()
135 .get_pattern_fill_mut()
136 .set_pattern_type(PatternValues::Solid);
137 }
138
139 if let Some(ref edge) = dto.border_top {
141 let border = style.get_borders_mut().get_top_mut();
142 if let Some(ref s) = edge.style {
143 border.set_border_style(s);
144 }
145 if let Some(ref c) = edge.color {
146 border.get_color_mut().set_argb(c);
147 }
148 }
149 if let Some(ref edge) = dto.border_bottom {
150 let border = style.get_borders_mut().get_bottom_mut();
151 if let Some(ref s) = edge.style {
152 border.set_border_style(s);
153 }
154 if let Some(ref c) = edge.color {
155 border.get_color_mut().set_argb(c);
156 }
157 }
158 if let Some(ref edge) = dto.border_left {
159 let border = style.get_borders_mut().get_left_mut();
160 if let Some(ref s) = edge.style {
161 border.set_border_style(s);
162 }
163 if let Some(ref c) = edge.color {
164 border.get_color_mut().set_argb(c);
165 }
166 }
167 if let Some(ref edge) = dto.border_right {
168 let border = style.get_borders_mut().get_right_mut();
169 if let Some(ref s) = edge.style {
170 border.set_border_style(s);
171 }
172 if let Some(ref c) = edge.color {
173 border.get_color_mut().set_argb(c);
174 }
175 }
176
177 if let Some(ref h) = dto.horizontal_align {
179 if let Some(val) = parse_horizontal_align(h) {
180 style.get_alignment_mut().set_horizontal(val);
181 }
182 }
183 if let Some(ref v) = dto.vertical_align {
184 if let Some(val) = parse_vertical_align(v) {
185 style.get_alignment_mut().set_vertical(val);
186 }
187 }
188 if let Some(wrap) = dto.wrap_text {
189 style.get_alignment_mut().set_wrap_text(wrap);
190 }
191
192 if let Some(ref fmt) = dto.number_format {
194 style.get_number_format_mut().set_format_code(fmt);
195 }
196}
197
198pub fn apply_range_style(sheet: &mut Worksheet, range: &MergeRange, dto: &CellStyleDto) {
200 for r in range.start_row..=range.end_row {
201 for c in range.start_col..=range.end_col {
202 apply_cell_style(sheet, r, c, dto);
203 }
204 }
205}
206
207fn parse_horizontal_align(s: &str) -> Option<umya_spreadsheet::structs::HorizontalAlignmentValues> {
208 use umya_spreadsheet::structs::HorizontalAlignmentValues::*;
209 match s.to_lowercase().as_str() {
210 "center" => Some(Center),
211 "centercontinuous" => Some(CenterContinuous),
212 "distributed" => Some(Distributed),
213 "fill" => Some(Fill),
214 "general" => Some(General),
215 "justify" => Some(Justify),
216 "left" => Some(Left),
217 "right" => Some(Right),
218 _ => None,
219 }
220}
221
222fn parse_vertical_align(s: &str) -> Option<umya_spreadsheet::structs::VerticalAlignmentValues> {
223 use umya_spreadsheet::structs::VerticalAlignmentValues::*;
224 match s.to_lowercase().as_str() {
225 "bottom" => Some(Bottom),
226 "center" => Some(Center),
227 "distributed" => Some(Distributed),
228 "justify" => Some(Justify),
229 "top" => Some(Top),
230 _ => None,
231 }
232}