1use crabxl::{
3 Alignment, Border, BorderLine, BorderSide, Cell, CellAddress, CellStyle, CellValue, Color,
4 ColorKind, ExcelDateTime, Fill, FillPattern, Font, PatternFill, Row, RowIndex, SheetId,
5 StyleId, Workbook, WorkbookLimits, WorkbookWriter, WriteOptions,
6};
7#[allow(clippy::large_enum_variant)]
9enum Output {
10 Streaming(WorkbookWriter),
11 Owned {
12 book: Workbook,
13 sheet: Option<SheetId>,
14 },
15}
16impl Output {
17 fn register_style(&mut self, style: CellStyle) -> crabxl::Result<StyleId> {
18 match self {
19 Self::Streaming(writer) => writer.register_style(style),
20 Self::Owned { book, .. } => book.register_style(style),
21 }
22 }
23 fn start_sheet(&mut self) -> crabxl::Result<()> {
24 match self {
25 Self::Streaming(writer) => writer.start_sheet("Sheet"),
26 Self::Owned { book, sheet } => {
27 *sheet = Some(book.create_sheet("Sheet")?);
28 Ok(())
29 }
30 }
31 }
32 fn write_row(&mut self, row: &mut Row) -> crabxl::Result<()> {
33 match self {
34 Self::Streaming(writer) => writer.write_row(row),
35 Self::Owned { book, sheet } => {
36 let id = sheet.ok_or_else(|| {
37 crabxl::Error::new(crabxl::ErrorKind::InvalidState, "Missing fixture sheet")
38 })?;
39 let mut editor = book.sheet_mut(id)?;
40 for cell in row.cells.drain(..) {
41 editor.set(cell)?;
42 }
43 Ok(())
44 }
45 }
46 }
47 fn finish(self, path: String) -> crabxl::Result<()> {
48 let writer = match self {
49 Self::Streaming(mut writer) => {
50 writer.close_sheet()?;
51 writer
52 }
53 Self::Owned { book, .. } => {
54 eprintln!("BANK_BYTES {}", book.charged_bytes());
55 WorkbookWriter::from_workbook(WriteOptions::default(), book)?
56 }
57 };
58 eprintln!("STYLE_BYTES {}", writer.style_memory_bytes());
59 eprintln!("TEMP_BYTES {}", writer.stats().peak_temp_bytes);
60 writer.finish(std::fs::File::create(path).map_err(|error| {
61 crabxl::Error::caused_by(crabxl::ErrorKind::Io, "Cannot create fixture", error)
62 })?)?;
63 Ok(())
64 }
65}
66fn main() -> Result<(), Box<dyn std::error::Error>> {
67 let mut arguments = std::env::args().skip(1);
68 let path = arguments.next().ok_or("Missing output")?;
69 let rows: u32 = arguments.next().as_deref().unwrap_or("4").parse()?;
70 if rows == 0 || rows > 1_048_576 {
71 return Err("Invalid row count".into());
72 }
73 let mut writer = match arguments.next().as_deref() {
74 None => Output::Streaming(WorkbookWriter::new(WriteOptions::default())?),
75 Some("owned") => Output::Owned {
76 book: Workbook::new(WorkbookLimits::default())?,
77 sheet: None,
78 },
79 Some(_) => return Err("Unknown fixture mode".into()),
80 };
81 let mut identities = Vec::<StyleId>::new();
82 identities.try_reserve_exact(5)?;
83 for code in ["General", "0.00", "yyyy-mm-dd", "hh:mm:ss", "[h]:mm:ss"] {
84 identities.push(writer.register_style(CellStyle {
85 number_format: code.into(),
86 font: Font {
87 name: Some("Public temporal font".into()),
88 size: Some(14.0),
89 bold: Some(true),
90 color: Some(Color {
91 kind: ColorKind::Argb(0xff112233),
92 tint: None,
93 }),
94 ..Default::default()
95 },
96 fill: Fill::Pattern(PatternFill {
97 pattern: Some(FillPattern::Solid),
98 foreground: Some(Color {
99 kind: ColorKind::Argb(0xff445566),
100 tint: None,
101 }),
102 ..Default::default()
103 }),
104 borders: {
105 let mut border = Border::default();
106 border.sides[0] = Some(BorderSide {
107 line: Some(BorderLine::Thin),
108 color: Some(Color {
109 kind: ColorKind::Argb(0xff778899),
110 tint: None,
111 }),
112 });
113 border
114 },
115 alignment: Alignment {
116 indent: Some(2.5),
117 wrap_text: Some(true),
118 ..Default::default()
119 },
120 ..Default::default()
121 })?);
122 }
123 let dates = [
124 ExcelDateTime::from_ymd(2024, 1, 2)?,
125 ExcelDateTime::from_ymd_hms_micro(2024, 1, 2, 3, 4, 5, 678900)?,
126 ExcelDateTime::from_hms_micro(3, 4, 5, 678900)?,
127 ExcelDateTime::from_duration_parts(2, 3, 678900)?,
128 ];
129 writer.start_sheet()?;
130 let mut row = Row::new(RowIndex::new(0)?);
131 row.cells.try_reserve_exact(5)?;
132 for index in 0..rows {
133 row.index = RowIndex::new(index)?;
134 row.cells.clear();
135 for (column, id) in identities.iter().enumerate() {
136 row.cells.push(Cell {
137 address: CellAddress::new(index, column as u32)?,
138 value: CellValue::DateTime(Box::new(dates[index as usize % dates.len()])),
139 style: *id,
140 });
141 }
142 writer.write_row(&mut row)?;
143 }
144 writer.finish(path)?;
145 println!("{}", rows * 5);
146 Ok(())
147}