br_excel/
write.rs

1use std::fs;
2use std::path::Path;
3use base64::Engine;
4use base64::engine::general_purpose::STANDARD;
5use json::{JsonValue, object};
6use umya_spreadsheet::{FontSize, HorizontalAlignmentValues, Image, new_file, Spreadsheet, VerticalAlignmentValues, writer};
7use umya_spreadsheet::drawing::spreadsheet::{BlipFill, MarkerType, NonVisualDrawingProperties, NonVisualPictureDrawingProperties, NonVisualPictureProperties, Picture, ShapeProperties, TwoCellAnchor};
8use umya_spreadsheet::drawing::{AdjustValueList, Blip, FillRectangle, Miter, NoFill, Outline, PictureLocks, Point2DType, PositiveSize2DType, PresetGeometry, Stretch, Transform2D};
9use crate::Head;
10
11pub struct Write {
12    path: String,
13    page: usize,
14    excel: Spreadsheet,
15}
16
17impl Write {
18    pub fn new(filepath: &str) -> Self {
19        let book = new_file();
20        Self {
21            path: filepath.to_string(),
22            page: 0,
23            excel: book,
24        }
25    }
26    /// 设置数据
27    /// * page 1 开始
28    pub fn set_page(&mut self, page: usize, name: &str, headers: Vec<Head>, data: JsonValue) -> &mut Self {
29        self.page = page - 1;
30        if self.page > 0 {
31            self.excel.new_sheet(name).unwrap();
32        }
33        self.excel.get_sheet_mut(&self.page).unwrap().set_name(name);
34        let mut row_line = 1;
35        let mut col_line = 1;
36        let mut header_key_value = object! {};
37        for header in headers.iter() {
38            self.excel.get_sheet_mut(&self.page).unwrap().get_cell_mut((col_line, row_line)).set_value_string(header.clone().title);
39            // 设置列宽
40            let index = Write::col_int_to_str(col_line);
41            self.excel.get_sheet_mut(&self.page).unwrap().get_column_dimension_mut(index.as_str()).set_width(header.width as f64);
42            header_key_value[header.clone().field] = JsonValue::from(col_line);
43            col_line += 1;
44        }
45        for row in data.members() {
46            row_line += 1;
47            for (key, value) in row.entries() {
48                if header_key_value[key].is_empty() {
49                    continue;
50                }
51                col_line = header_key_value[key].as_u32().unwrap();
52                self.excel.get_sheet_mut(&self.page).unwrap().get_cell_mut((col_line, row_line)).set_value_string(value.to_string().clone());
53            }
54        }
55        self
56    }
57    /// 设置 自定义样式 数据
58    /// * page 1 开始
59    pub fn set_page_array(&mut self, page: usize, name: &str, data: JsonValue) -> &mut Self {
60        self.page = page - 1;
61        if self.page > 0 {
62            self.excel.new_sheet(name).unwrap();
63        }
64        self.excel.get_sheet_mut(&self.page).unwrap().set_name(name);
65
66
67        let mut merge_cells = vec![];
68
69        let mut row_line = 1;
70
71        for row in data.members() {
72            let mut col_line = 1;
73            for col in row.members() {
74                self.excel.get_sheet_mut(&self.page).unwrap().get_cell_mut((col_line, row_line)).set_value_string(col["value"].to_string());
75                if !col["style"].is_empty() {
76                    let style = col["style"].clone();
77                    if !style["height"].is_empty() {
78                        let height = style["height"].to_string().replace("m", "").as_str().parse::<f64>().unwrap();
79                        self.excel.get_sheet_mut(&self.page).unwrap().get_row_dimension_mut(&row_line).set_height(height / 0.3612);
80                    }
81                    if !style["width"].is_empty() {
82                        let width = style["width"].to_string().replace("m", "").as_str().parse::<f64>().unwrap();
83                        self.excel.get_sheet_mut(&self.page).unwrap().get_column_dimension_by_number_mut(&col_line).set_width(width / 2.54);
84                    }
85                    if !style["font-size"].is_empty() {
86                        let size = style["font-size"].to_string().parse::<f64>().unwrap();
87                        let mut fontsize = FontSize::default();
88                        let tt = fontsize.set_val(size);
89                        self.excel.get_sheet_mut(&self.page).unwrap().get_cell_mut((col_line, row_line))
90                            .get_style_mut()
91                            .get_font_mut().set_font_size(tt.clone());
92                    }
93                    if !style["text-align"].is_empty() {
94                        match style["text-align"].as_str().unwrap() {
95                            "center" => {
96                                self.excel.get_sheet_mut(&self.page).unwrap().get_cell_mut((col_line, row_line))
97                                    .get_style_mut()
98                                    .get_alignment_mut()
99                                    .set_vertical(VerticalAlignmentValues::Center);
100
101                                self.excel.get_sheet_mut(&self.page).unwrap().get_cell_mut((col_line, row_line))
102                                    .get_style_mut()
103                                    .get_alignment_mut()
104                                    .set_horizontal(HorizontalAlignmentValues::Center);
105                            }
106                            "left" => {
107                                self.excel.get_sheet_mut(&self.page).unwrap().get_cell_mut((col_line, row_line))
108                                    .get_style_mut()
109                                    .get_alignment_mut()
110                                    .set_vertical(VerticalAlignmentValues::Center);
111
112                                self.excel.get_sheet_mut(&self.page).unwrap().get_cell_mut((col_line, row_line))
113                                    .get_style_mut()
114                                    .get_alignment_mut()
115                                    .set_horizontal(HorizontalAlignmentValues::Left);
116                            }
117                            "right" => {
118                                self.excel.get_sheet_mut(&self.page).unwrap().get_cell_mut((col_line, row_line))
119                                    .get_style_mut()
120                                    .get_alignment_mut()
121                                    .set_vertical(VerticalAlignmentValues::Center);
122
123                                self.excel.get_sheet_mut(&self.page).unwrap().get_cell_mut((col_line, row_line))
124                                    .get_style_mut()
125                                    .get_alignment_mut()
126                                    .set_horizontal(HorizontalAlignmentValues::Right);
127                            }
128                            "bottom" => {
129                                self.excel.get_sheet_mut(&self.page).unwrap().get_cell_mut((col_line, row_line))
130                                    .get_style_mut()
131                                    .get_alignment_mut()
132                                    .set_vertical(VerticalAlignmentValues::Bottom);
133                            }
134                            "justify" => {
135                                self.excel.get_sheet_mut(&self.page).unwrap().get_cell_mut((col_line, row_line))
136                                    .get_style_mut()
137                                    .get_alignment_mut()
138                                    .set_vertical(VerticalAlignmentValues::Justify);
139                            }
140                            "fill" => {
141                                self.excel.get_sheet_mut(&self.page).unwrap().get_cell_mut((col_line, row_line))
142                                    .get_style_mut()
143                                    .get_alignment_mut()
144                                    .set_horizontal(HorizontalAlignmentValues::Fill);
145                            }
146                            _ => {
147                                self.excel.get_sheet_mut(&self.page).unwrap().get_cell_mut((col_line, row_line))
148                                    .get_style_mut()
149                                    .get_alignment_mut()
150                                    .set_vertical(VerticalAlignmentValues::Center);
151
152                                self.excel.get_sheet_mut(&self.page).unwrap().get_cell_mut((col_line, row_line))
153                                    .get_style_mut()
154                                    .get_alignment_mut()
155                                    .set_horizontal(HorizontalAlignmentValues::Center);
156                            }
157                        }
158                    }
159                }
160
161                if !col["border"]["top"].is_empty() {
162                    self.excel.get_sheet_mut(&self.page).unwrap().get_cell_mut((col_line, row_line))
163                        .get_style_mut()
164                        .get_borders_mut()
165                        .get_top_mut()
166                        .set_border_style(umya_spreadsheet::Border::BORDER_THIN);
167                }
168                if !col["border"]["right"].is_empty() {
169                    self.excel.get_sheet_mut(&self.page).unwrap().get_cell_mut((col_line, row_line))
170                        .get_style_mut()
171                        .get_borders_mut()
172                        .get_right_mut()
173                        .set_border_style(umya_spreadsheet::Border::BORDER_THIN);
174                }
175                if !col["border"]["bottom"].is_empty() {
176                    self.excel.get_sheet_mut(&self.page).unwrap().get_cell_mut((col_line, row_line))
177                        .get_style_mut()
178                        .get_borders_mut()
179                        .get_bottom_mut()
180                        .set_border_style(umya_spreadsheet::Border::BORDER_THIN);
181                }
182                if !col["border"]["left"].is_empty() {
183                    self.excel.get_sheet_mut(&self.page).unwrap()
184                        .get_cell_mut((col_line, row_line))
185                        .get_style_mut()
186                        .get_borders_mut()
187                        .get_left_mut()
188                        .set_border_style(umya_spreadsheet::Border::BORDER_THIN);
189                }
190
191                if col["rowspan"] != 0 && col["colspan"] != 0 {
192                    let start = self.int_to_str(col["col"].to_string().parse::<u32>().unwrap(), col["row"].to_string().parse::<u32>().unwrap());
193                    let end = self.int_to_str_js(col["col"].to_string().parse::<u32>().unwrap() + col["colspan"].as_u32().unwrap(), col["row"].to_string().parse::<u32>().unwrap() + col["rowspan"].as_u32().unwrap());
194                    merge_cells.push(format!("{}:{}", start, end));
195                }
196                col_line += 1;
197            }
198            row_line += 1;
199        }
200
201        for item in merge_cells.iter() {
202            self.excel.get_sheet_mut(&self.page).unwrap().add_merge_cells(item);
203        }
204        self
205    }
206    pub fn set_page_array_image(&mut self, page: usize, name: &str, data: JsonValue) -> &mut Self {
207        self.page = page - 1;
208        if self.page > 0 {
209            self.excel.new_sheet(name).unwrap();
210        }
211        self.excel.get_sheet_mut(&self.page).unwrap().set_name(name);
212
213
214        let page_info = self.excel.get_sheet_mut(&self.page).unwrap();
215        let mut merge_cells = vec![];
216        let mut image_cells = vec![];
217
218        let mut row_line = 1;
219
220        for row in data.members() {
221            let mut col_line = 1;
222            for col in row.members() {
223                let text = col["value"].as_str().unwrap_or("");
224                page_info.get_cell_mut((col_line, row_line)).set_value_string(text);
225
226                for (key, value) in col.entries() {
227                    match key {
228                        "style" => {
229                            let style = value.clone();
230
231                            let width = style["width"].to_string().replace("mm", "").as_str().parse::<f64>().unwrap();
232                            page_info.get_column_dimension_by_number_mut(&col_line).set_width(width / 2.54);
233
234                            let height = style["height"].to_string().replace("mm", "").as_str().parse::<f64>().unwrap();
235                            page_info.get_row_dimension_mut(&row_line).set_height(height / 0.3612);
236
237                            let size = style["font-size"].to_string().replace("px", "").parse::<f64>().unwrap();
238
239                            let mut fontsize = FontSize::default();
240                            let tt = fontsize.set_val(size);
241                            page_info.get_cell_mut((col_line, row_line))
242                                .get_style_mut()
243                                .get_font_mut().set_font_size(tt.clone());
244
245                            match style["text-align"].as_str().unwrap_or("center") {
246                                "center" => {
247                                    page_info.get_cell_mut((col_line, row_line))
248                                        .get_style_mut()
249                                        .get_alignment_mut()
250                                        .set_vertical(VerticalAlignmentValues::Center);
251
252                                    page_info.get_cell_mut((col_line, row_line))
253                                        .get_style_mut()
254                                        .get_alignment_mut()
255                                        .set_horizontal(HorizontalAlignmentValues::Center);
256                                }
257                                "left" => {
258                                    page_info.get_cell_mut((col_line, row_line))
259                                        .get_style_mut()
260                                        .get_alignment_mut()
261                                        .set_vertical(VerticalAlignmentValues::Center);
262
263                                    page_info.get_cell_mut((col_line, row_line))
264                                        .get_style_mut()
265                                        .get_alignment_mut()
266                                        .set_horizontal(HorizontalAlignmentValues::Left);
267                                }
268                                "right" => {
269                                    page_info.get_cell_mut((col_line, row_line))
270                                        .get_style_mut()
271                                        .get_alignment_mut()
272                                        .set_vertical(VerticalAlignmentValues::Center);
273
274                                    page_info.get_cell_mut((col_line, row_line))
275                                        .get_style_mut()
276                                        .get_alignment_mut()
277                                        .set_horizontal(HorizontalAlignmentValues::Right);
278                                }
279                                "justify" => {
280                                    page_info.get_cell_mut((col_line, row_line))
281                                        .get_style_mut()
282                                        .get_alignment_mut()
283                                        .set_vertical(VerticalAlignmentValues::Justify);
284                                }
285                                _ => {
286                                    page_info.get_cell_mut((col_line, row_line))
287                                        .get_style_mut()
288                                        .get_alignment_mut()
289                                        .set_vertical(VerticalAlignmentValues::Center);
290
291                                    page_info.get_cell_mut((col_line, row_line))
292                                        .get_style_mut()
293                                        .get_alignment_mut()
294                                        .set_horizontal(HorizontalAlignmentValues::Center);
295                                }
296                            }
297
298                            if !style["border-top"].is_empty() {
299                                page_info.get_cell_mut((col_line, row_line))
300                                    .get_style_mut()
301                                    .get_borders_mut()
302                                    .get_top_mut()
303                                    .set_border_style(umya_spreadsheet::Border::BORDER_THIN);
304                            }
305                            if !style["border-right"].is_empty() {
306                                page_info.get_cell_mut((col_line, row_line))
307                                    .get_style_mut()
308                                    .get_borders_mut()
309                                    .get_right_mut()
310                                    .set_border_style(umya_spreadsheet::Border::BORDER_THIN);
311                            }
312                            if !style["border-bottom"].is_empty() {
313                                page_info.get_cell_mut((col_line, row_line))
314                                    .get_style_mut()
315                                    .get_borders_mut()
316                                    .get_bottom_mut()
317                                    .set_border_style(umya_spreadsheet::Border::BORDER_THIN);
318                            }
319                            if !style["border-left"].is_empty() {
320                                page_info.get_cell_mut((col_line, row_line))
321                                    .get_style_mut()
322                                    .get_borders_mut()
323                                    .get_left_mut()
324                                    .set_border_style(umya_spreadsheet::Border::BORDER_THIN);
325                            }
326                        }
327                        "image" => {
328                            if value.is_empty() {
329                                continue;
330                            }
331                            let path = format!("./{}_{}_{}", col_line, row_line, col["image_n"]);
332                            let images = value.as_str().unwrap().split(",").collect::<Vec<&str>>();
333                            let images = images[1];
334                            let images = STANDARD.decode(images).unwrap_or_else(|_| vec![]);
335                            if fs::write(path.clone(), images).is_ok() {
336                                let mut image = Image::default();
337
338
339                                let mut two_cell = TwoCellAnchor::default();
340                                let mut transform_2d = Transform2D::default();
341                                let mut point2dtype = Point2DType::default();
342
343
344                                let x = col["image_x"].to_string().parse::<f64>().unwrap() * 70823.0;
345                                let y = col["image_y"].to_string().parse::<f64>().unwrap() * 32743.37;
346
347                                point2dtype.set_x(x as i64);
348                                point2dtype.set_y(y as i64);
349
350                                let mut positive_size2dtype = PositiveSize2DType::default();
351
352                                let cx = col["image_w"].to_string().parse::<f64>().unwrap() * 70823.0;
353                                let cy = col["image_h"].to_string().parse::<f64>().unwrap() * 32743.37;
354
355                                positive_size2dtype.set_cx(cx as i64);
356                                positive_size2dtype.set_cy(cy as i64);
357
358                                transform_2d.set_offset(point2dtype);
359                                transform_2d.set_extents(positive_size2dtype);
360
361
362                                let mut marker = MarkerType::default();
363                                marker.set_row(col["image_from_row"].to_string().parse::<u32>().unwrap());
364                                marker.set_col(col["image_from_col"].to_string().parse::<u32>().unwrap());
365                                marker.set_col_off(col["image_from_col_off"].to_string().parse::<i32>().unwrap());
366                                marker.set_row_off(col["image_from_row_off"].to_string().parse::<i32>().unwrap());
367
368                                two_cell.set_from_marker(marker.clone());
369
370
371                                let mut to_marker = MarkerType::default();
372                                to_marker.set_row(col["image_to_row"].to_string().parse::<u32>().unwrap());
373                                to_marker.set_col(col["image_to_col"].to_string().parse::<u32>().unwrap());
374                                to_marker.set_col_off(col["image_to_col_off"].to_string().parse::<i32>().unwrap());
375                                to_marker.set_row_off(col["image_to_row_off"].to_string().parse::<i32>().unwrap());
376
377
378                                two_cell.set_to_marker(to_marker);
379
380                                let mut picture = Picture::default();
381                                let mut non_visual_picture_properties = NonVisualPictureProperties::default();
382
383                                let mut non_visual_drawing_properties = NonVisualDrawingProperties::default();
384                                let mut picture_locks = PictureLocks::default();
385                                picture_locks.set_no_change_aspect(true);
386
387                                non_visual_drawing_properties.set_name(col["image_n"].to_string());
388                                non_visual_drawing_properties.set_id(col["image_id"].to_string().parse::<u32>().unwrap_or(0));
389
390                                non_visual_picture_properties.set_non_visual_drawing_properties(non_visual_drawing_properties);
391
392                                let mut non_visual_picture_drawing_properties = NonVisualPictureDrawingProperties::default();
393                                non_visual_picture_drawing_properties.set_picture_locks(picture_locks);
394
395                                non_visual_picture_properties.set_non_visual_picture_drawing_properties(non_visual_picture_drawing_properties);
396
397                                picture.set_non_visual_picture_properties(non_visual_picture_properties);
398                                let mut shape_properties = ShapeProperties::default();
399                                shape_properties.set_transform2d(transform_2d);
400
401                                let mut geometry = PresetGeometry::default();
402                                let adjust_value_list = AdjustValueList::default();
403                                geometry.set_adjust_value_list(adjust_value_list);
404                                geometry.set_geometry("rect");
405
406                                shape_properties.set_geometry(geometry);
407
408                                let mut outline = Outline::default();
409                                let image_w_w = col["image_w_w"].to_string().parse::<u32>().unwrap();
410                                let image_h_w = col["image_h_w"].to_string().parse::<u32>().unwrap();
411                                outline.set_width(image_w_w);
412                                outline.set_cap_type("flat");
413                                let tt = NoFill::default();
414                                outline.set_no_fill(tt);
415                                let mut miter = Miter::default();
416                                miter.set_limit(image_h_w as i32);
417                                outline.set_miter(miter);
418
419                                shape_properties.set_outline(outline);
420
421                                picture.set_shape_properties(shape_properties);
422                                let mut blip_fill = BlipFill::default();
423
424                                let mut blip = Blip::default();
425
426                                let r = blip.get_image_mut();
427
428                                let rrr = fs::read(path.clone()).unwrap();
429
430                                r.set_image_data(rrr);
431                                r.set_image_name(col["image_n"].to_string());
432
433                                let ttt = r.clone().clone();
434                                blip.set_image(ttt);
435
436                                blip_fill.set_blip(blip);
437                                let mut stretch = Stretch::default();
438                                stretch.set_fill_rectangle(FillRectangle::default());
439                                blip_fill.set_stretch(stretch);
440                                picture.set_blip_fill(blip_fill);
441
442                                two_cell.set_picture(picture);
443                                image.set_two_cell_anchor(two_cell.clone());
444
445                                image_cells.push(image);
446
447                                fs::remove_file(path.clone()).expect("TODO: panic message");
448                            }
449                        }
450                        _ => {}
451                    }
452                }
453
454                if col["rowspan"] != 0 && col["colspan"] != 0 {
455                    let start = Write::int_to_str_new(col["col"].to_string().parse::<u32>().unwrap() - 1, col["row"].to_string().parse::<u32>().unwrap());
456                    let end = Write::int_to_str_new(
457                        col["col"].to_string().parse::<u32>().unwrap() + col["colspan"].as_u32().unwrap() - 2,
458                        col["row"].to_string().parse::<u32>().unwrap() + col["rowspan"].as_u32().unwrap() - 1,
459                    );
460                    merge_cells.push(format!("{}:{}", start, end));
461                }
462                col_line += 1;
463            }
464            row_line += 1;
465        }
466
467        for image_cell in image_cells.iter() {
468            page_info.add_image(image_cell.clone());
469        }
470        for item in merge_cells.iter() {
471            page_info.add_merge_cells(item);
472        }
473        self
474    }
475    fn int_to_str_new(row: u32, col: u32) -> String {
476        let count = row / 26 + 1;
477        let row = row % 26;
478        let ascii = row as u8 + 65;
479
480        let mut r = vec![65; (count - 1) as usize];
481        r.push(ascii);
482        let row_t = r.escape_ascii().to_string();
483        format!("{}{}", row_t, col)
484    }
485    // 列的索引转title字母 1->A,2->B,3->C
486    fn col_int_to_str(mut col: u32) -> String {
487        let mut result = String::new();
488        while col > 0 {
489            // Excel 列号是从 1 开始的,但我们需要从 0 计算
490            col -= 1;
491            let ch = (col % 26) as u8 + b'A';
492            result.insert(0, ch as char); // 将字符插入到结果的最前面
493            col /= 26;
494        }
495        result
496    }
497    fn int_to_str(&mut self, row: u32, col: u32) -> String {
498        let row = row - 1;
499        let count = row / 26 + 1;
500        let row = row % 26;
501        let ascii = row as u8 + 65;
502
503        let mut r = vec![65; (count - 1) as usize];
504        r.push(ascii);
505        let row_t = r.escape_ascii().to_string();
506        format!("{}{}", row_t, col)
507    }
508    fn int_to_str_js(&mut self, row: u32, col: u32) -> String {
509        let row = row - 2;
510        let col = col - 1;
511        let count = row / 26 + 1;
512        let row = row % 26;
513        let ascii = row as u8 + 65;
514
515        let mut r = vec![65; (count - 1) as usize];
516        r.push(ascii);
517        let row_t = r.escape_ascii().to_string();
518        let col_t = col;
519        format!("{}{}", row_t, col_t)
520    }
521
522    pub fn save(&mut self) -> bool {
523        let path = Path::new(self.path.as_str());
524        match writer::xlsx::write(&self.excel, path) {
525            Ok(_) => true,
526            Err(e) => {
527                println!("保存错误: {} {}", e, path.to_str().unwrap());
528                false
529            }
530        }
531    }
532}