1use std::slice::Iter;
2use crate::api::cell::Cell;
3use crate::api::cell::formula::Formula;
4use crate::api::cell::values::{CellDisplay, CellType, CellValue};
5use crate::api::cell::location::{Location, LocationRange};
6use crate::api::cell::rich_text::RichText;
7use crate::api::worksheet::format::_Format;
8use crate::api::worksheet::hyperlink::_Hyperlink;
9use crate::Format;
10use crate::api::worksheet::WorkSheet;
11use crate::result::WorkSheetResult;
12use crate::xml::extension::{AddExtension, ExtensionType};
13
14pub trait Write: _Write {
15 fn write_cell<L: Location, T: Clone + CellDisplay + CellValue>(&mut self, loc: L, cell: &Cell<T>) -> WorkSheetResult<()> {
16 self.write_by_api_cell(&loc, &cell)?;
17 Ok(())
18 }
19
20 fn write<L: Location, T: Default + Clone + CellDisplay + CellValue>(&mut self, loc: L, data: T) -> WorkSheetResult<()> {
21 let mut cell = Cell::default();
22 cell.cell_type = Some(data.to_cell_type());
23 cell.text = Some(data);
24 self.write_by_api_cell(&loc, &cell)
25 }
26 fn write_string<L: Location>(&mut self, loc: L, data: String) -> WorkSheetResult<()> {
27 let mut cell = Cell::default();
28 cell.text = Some(data);
29 self.write_by_api_cell(&loc, &cell)
30 }
31 fn write_rich_string<L: Location>(&mut self, loc: L, data: &RichText) -> WorkSheetResult<()> {
32 let mut cell: Cell<String> = Cell::default();
33 cell.rich_text = Some(data.clone());
34 self.write_by_api_cell(&loc, &cell)
35 }
36 fn write_number<L: Location>(&mut self, loc: L, data: i32) -> WorkSheetResult<()> {
37 let mut cell = Cell::default();
38 cell.text = Some(data);
39 self.write_by_api_cell(&loc, &cell)
40 }
41 fn write_double<L: Location>(&mut self, loc: L, data: f64) -> WorkSheetResult<()> {
42 let mut cell = Cell::default();
43 cell.text = Some(data);
44 self.write_by_api_cell(&loc, &cell)
45 }
46 fn write_boolean<L: Location>(&mut self, loc: L, data: bool) -> WorkSheetResult<()> {
47 let mut cell = Cell::default();
48 cell.text = Some(data);
49 self.write_by_api_cell(&loc, &cell)
50 }
51 fn write_row<L: Location, T: CellDisplay + CellValue>(&mut self, loc: L, data: &[T]) -> WorkSheetResult<()> {
52 let (row, mut col) = loc.to_location();
53 for data in data {
54 self.write_display_all(&(row, col), data, None)?;
55 col += 1;
56 }
57 Ok(())
58 }
59
60 fn write_row_cells<L: Location, T: CellDisplay + CellValue + Clone>(&mut self, loc: L, cells: &[Cell<T>]) -> WorkSheetResult<()> {
61 let (row, mut col) = loc.to_location();
62 for cell in cells {
63 self.write_by_api_cell(&(row, col), cell)?;
64 col += 1;
65 }
66 Ok(())
67 }
68
69 fn write_column<L: Location, T: CellDisplay + CellValue>(&mut self, loc: L, data: &[T]) -> WorkSheetResult<()> {
70 let (mut row, col) = loc.to_location();
71 for data in data {
72 self.write_display_all(&(row, col), data, None)?;
73 row += 1;
74 }
75 Ok(())
76 }
77
78 fn write_column_cells<L: Location, T: CellDisplay + CellValue + Clone>(&mut self, loc: L, cells: &[Cell<T>]) -> WorkSheetResult<()> {
79 let (mut row, col) = loc.to_location();
80 for cell in cells {
81 self.write_by_api_cell(&(row, col), cell)?;
82 row += 1;
83 }
84 Ok(())
85 }
86
87 fn write_url<L: Location>(&mut self, loc: L, url: &str) -> WorkSheetResult<()> {
88 let mut cell = Cell::default();
89 cell.text = Some(url);
90 cell.hyperlink = Some(url.to_string());
91 self.write_by_api_cell(&loc, &cell)
92 }
93
94 fn write_url_text<L: Location, T: CellDisplay + CellValue>(&mut self, loc: L, url: &str, data: &str) -> WorkSheetResult<()> {
95 let mut cell = Cell::default();
96 cell.text = Some(data);
97 cell.hyperlink = Some(url.to_string());
98 self.write_by_api_cell(&loc, &cell)
99 }
100
101 fn merge_range<L: LocationRange, T: CellDisplay + CellValue>(&mut self, loc: L, data: T) -> WorkSheetResult<()> {
102 self.merge_range_all(loc, data, None)
103 }
104
105 fn write_formula<L: Location>(&mut self, loc: L, data: &str) -> WorkSheetResult<()> {
106 let mut cell: Cell<&str> = Cell::default();
107 cell.formula = Some(Formula::new_array_formula(data, &loc));
111 self.write_by_api_cell(&loc, &cell)
113 }
115
116 fn write_old_formula<L: Location>(&mut self, loc: L, data: &str) -> WorkSheetResult<()> {
117 let mut cell: Cell<&str> = Cell::default();
118 cell.formula = Some(Formula::new(data));
119 self.write_by_api_cell(&loc, &cell)
120 }
121 fn write_array_formula<L: Location>(&mut self, loc: L, data: &str) -> WorkSheetResult<()> {
122 let mut cell: Cell<&str> = Cell::default();
123 cell.formula = Some(Formula::new_array_formula(data, &loc));
124 self.write_by_api_cell(&loc, &cell)
126 }
127 fn write_dynamic_array_formula<L: Location>(&mut self, loc: L, data: &str) -> WorkSheetResult<()> {
128 let mut cell: Cell<&str> = Cell::default();
129 cell.formula = Some(Formula::new_array_formula(data, &loc));
130 self.write_by_api_cell(&loc, &cell)
132 }
133 fn write_with_format<L: Location, T: Default + Clone + CellDisplay + CellValue>(&mut self, loc: L, data: T, format: &Format) -> WorkSheetResult<()> {
134 let mut cell = Cell::default();
135 cell.cell_type = Some(data.to_cell_type());
136 cell.text = Some(data);
137 cell.format = Some(format.clone());
138 self.write_by_api_cell(&loc, &cell)
139 }
140
141 fn write_string_with_format<L: Location>(&mut self, loc: L, data: String, format: &Format) -> WorkSheetResult<()> {
142 let mut cell = Cell::default();
143 cell.text = Some(data);
144 cell.format = Some(format.clone());
145 self.write_by_api_cell(&loc, &cell)
146 }
147
148 fn write_number_with_format<L: Location>(&mut self, loc: L, data: i32, format: &Format) -> WorkSheetResult<()> {
149 let mut cell = Cell::default();
150 cell.text = Some(data);
151 cell.format = Some(format.clone());
152 self.write_by_api_cell(&loc, &cell)
153 }
154 fn write_double_with_format<L: Location>(&mut self, loc: L, data: f64, format: &Format) -> WorkSheetResult<()> {
155 let mut cell = Cell::default();
156 cell.text = Some(data);
157 cell.format = Some(format.clone());
158 self.write_by_api_cell(&loc, &cell)
159 }
160 fn write_boolean_with_format<L: Location>(&mut self, loc: L, data: bool, format: &Format) -> WorkSheetResult<()> {
161 let mut cell = Cell::default();
162 cell.text = Some(data);
163 cell.format = Some(format.clone());
164 self.write_by_api_cell(&loc, &cell)
165 }
166 fn write_row_with_format<L: Location, T: CellDisplay + CellValue>(&mut self, loc: L, data: Iter<'_, T>, format: &Format) -> WorkSheetResult<()> {
167 let (row, mut col) = loc.to_location();
168 for data in data {
169 self.write_display_all(&(row, col), data, Some(format))?;
170 col += 1;
171 }
172 Ok(())
173 }
174 fn write_column_with_format<L: Location, T: CellDisplay + CellValue>(&mut self, loc: L, data: Iter<'_, T>, format: &Format) -> WorkSheetResult<()> {
175 let (mut row, col) = loc.to_location();
176 for data in data {
177 self.write_display_all(&(row, col), data, Some(format))?;
178 row += 1;
179 }
180 Ok(())
181 }
182 fn write_url_with_format<L: Location>(&mut self, loc: L, url: &str, format: &Format) -> WorkSheetResult<()> {
183 let mut cell = Cell::default();
184 cell.text = Some(url);
185 cell.hyperlink = Some(url.to_string());
186 cell.format = Some(format.clone());
187 self.write_by_api_cell(&loc, &cell)
188 }
189 fn write_url_text_with_format<L: Location>(&mut self, loc: L, url: &str, data: &str, format: &Format) -> WorkSheetResult<()> {
190 let mut cell = Cell::default();
191 cell.text = Some(data);
192 cell.hyperlink = Some(url.to_string());
193 cell.format = Some(format.clone());
194 self.write_by_api_cell(&loc, &cell)
195 }
196 fn write_formula_with_format<L: Location>(&mut self, loc: L, data: &str, format: &Format) -> WorkSheetResult<()> {
197 let mut cell: Cell<&str> = Cell::default();
198 cell.formula = Some(Formula::new_array_formula(data, &loc));
199 cell.format = Some(format.clone());
201 self.write_by_api_cell(&loc, &cell)
202 }
203 fn write_array_formula_with_format<L: Location>(&mut self, loc: L, data: &str, format: &Format) -> WorkSheetResult<()> {
204 let mut cell: Cell<&str> = Cell::default();
205 cell.formula = Some(Formula::new_array_formula(data, &loc));
206 cell.format = Some(format.clone());
207 self.write_by_api_cell(&loc, &cell)
208 }
209 fn write_dynamic_array_formula_with_format<L: LocationRange>(&mut self, loc_range: L, data: &str, format: &Format) -> WorkSheetResult<()> {
210 let loc = loc_range.to_range();
211 let mut cell: Cell<&str> = Cell::default();
212 cell.formula = Some(Formula::new_array_formula_by_range(data, &loc));
213 cell.format = Some(format.clone());
214 self.write_by_api_cell(&(loc.0, loc.1), &cell)
216 }
217 fn merge_range_with_format<L: LocationRange, T: CellDisplay + CellValue>(&mut self, loc: L, data: T, format:&Format) -> WorkSheetResult<()> {
218 self.merge_range_all(loc, data, Some(format))
219 }
220}
221
222trait _Write: _Format + _Hyperlink {
223 fn write_by_api_cell<L: Location, T: CellDisplay + CellValue + Clone>(&mut self, loc: &L, cell: &Cell<T>) -> WorkSheetResult<()>;
224 fn write_display_all<L: Location, T: CellDisplay + CellValue>(&mut self, loc: &L, data: &T, format: Option<&Format>) -> WorkSheetResult<()>;
225 fn merge_range_all<L: LocationRange, T: CellDisplay + CellValue>(&mut self, loc: L, data: T, format: Option<&Format>) -> WorkSheetResult<()>;
228}
229
230impl _Write for WorkSheet {
231 fn write_by_api_cell<L: Location, T: CellDisplay + CellValue + Clone>(&mut self, loc: &L, cell: &Cell<T>) -> WorkSheetResult<()> {
232 let mut cell = cell.clone();
233 if let Some(_) = &cell.formula {
234 self.worksheet.xmlns_attrs.add_xr();
235 self.worksheet.xmlns_attrs.add_xr_2();
236 self.worksheet.xmlns_attrs.add_xr_3();
237 }
238 if let Some(CellType::SharedString) = &cell.cell_type {
239 if cell.rich_text.is_some() {
240 cell.cell_type = Some(CellType::InlineString);
241 } else {
242 cell.cell_type = Some(CellType::String);
243 }
244 }
245 if let Some(format) = &cell.format {
246 let style = self.add_format(format);
247 cell.style = Some(style);
248 }
249 if let Some(url) = &cell.hyperlink {
250 let url_r_id = self.worksheet_rel.add_hyperlink(url);
251 self.worksheet.add_hyperlink(loc, url_r_id);
252 }
253 if let Some(_) = &cell.formula {
254 self.metadata.borrow_mut().add_extension(ExtensionType::XdaDynamicArrayProperties);
255 self.workbook_rel.borrow_mut().get_or_add_metadata();
256 self.content_types.borrow_mut().add_metadata();
257 }
258 self.worksheet.sheet_data.write_by_api_cell(loc, &cell)?;
259 Ok(())
260 }
261
262 fn write_display_all<L: Location, T: CellDisplay + CellValue>(&mut self, loc: &L, data: &T, format: Option<&Format>) -> WorkSheetResult<()> {
263 let mut style = self.worksheet.get_default_style(loc);
264 if let Some(format) = format {
265 style = Some(self.add_format(format));
266 }
267 let worksheet = &mut self.worksheet;
268 let sheet_data = &mut worksheet.sheet_data;
269 sheet_data.write_display(loc, data, style)?;
270 Ok(())
271 }
272
273 fn merge_range_all<L: LocationRange, T: CellDisplay + CellValue>(&mut self, loc: L, data: T, format: Option<&Format>) -> WorkSheetResult<()> {
298 let (first_row, first_col, last_row, last_col) = loc.to_range();
299 let worksheet = &mut self.worksheet;
300 worksheet.add_merge_cell(first_row, first_col, last_row, last_col);
301 for row in first_row..=last_row {
302 for col in first_col..=last_col {
303 self.write_display_all(&(row, col), &data, format)?;
304 }
305 }
306 Ok(())
307 }
308}