1use rust_xlsxwriter::{Workbook, XlsxError};
2use serde_json::Value;
3use std::io::BufRead;
4
5#[derive(Debug)]
6pub enum Error {
7 Io(std::io::Error),
8 Json(serde_json::Error),
9 Xlsx(XlsxError),
10}
11
12impl From<std::io::Error> for Error {
13 fn from(err: std::io::Error) -> Self {
14 Error::Io(err)
15 }
16}
17
18impl From<serde_json::Error> for Error {
19 fn from(err: serde_json::Error) -> Self {
20 Error::Json(err)
21 }
22}
23
24impl From<XlsxError> for Error {
25 fn from(err: XlsxError) -> Self {
26 Error::Xlsx(err)
27 }
28}
29
30impl std::fmt::Display for Error {
31 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
32 match self {
33 Error::Io(err) => write!(f, "IO error: {}", err),
34 Error::Json(err) => write!(f, "JSON error: {}", err),
35 Error::Xlsx(err) => write!(f, "XLSX error: {}", err),
36 }
37 }
38}
39
40pub fn run<R: BufRead>(reader: R, output: &str, sheet: &str, row_limit: u32) -> Result<(), Error> {
41 let mut json_data: Vec<Value> = Vec::new();
42
43 for line in reader.lines().take(row_limit as usize) {
44 let line = line?;
45 let value: Value = serde_json::from_str(&line)?;
46 json_data.push(value);
47 }
48
49 if json_data.is_empty() {
50 println!("No JSON data to write to Excel.");
51 return Ok(());
52 }
53
54 let mut headers: Vec<String> = Vec::new();
55 if let Some(obj) = json_data.first().and_then(|v| v.as_object()) {
56 for key in obj.keys() {
57 headers.push(key.clone());
58 }
59 }
60
61 let mut workbook = Workbook::new();
62 let worksheet = workbook.add_worksheet().set_name(sheet)?;
63
64 for (col_num, header) in headers.iter().enumerate() {
66 worksheet.write_string(0, col_num as u16, header)?;
67 }
68
69 for (row_num, json_obj) in json_data.iter().enumerate() {
71 if let Some(obj) = json_obj.as_object() {
72 for (col_num, header) in headers.iter().enumerate() {
73 if let Some(value) = obj.get(header) {
74 match value {
75 Value::String(s) => {
76 worksheet.write_string((row_num + 1) as u32, col_num as u16, s)?;
77 }
78 Value::Number(n) => {
79 if let Some(f) = n.as_f64() {
80 worksheet.write_number((row_num + 1) as u32, col_num as u16, f)?;
81 } else if let Some(i) = n.as_i64() {
82 worksheet.write_number(
83 (row_num + 1) as u32,
84 col_num as u16,
85 i as f64,
86 )?;
87 } else {
88 worksheet.write_string(
89 (row_num + 1) as u32,
90 col_num as u16,
91 n.to_string(),
92 )?;
93 }
94 }
95 Value::Bool(b) => {
96 worksheet.write_boolean((row_num + 1) as u32, col_num as u16, *b)?;
97 }
98 Value::Null => {
99 worksheet.write_string((row_num + 1) as u32, col_num as u16, "")?;
101 }
102 _ => {
103 worksheet.write_string(
105 (row_num + 1) as u32,
106 col_num as u16,
107 value.to_string(),
108 )?;
109 }
110 }
111 }
112 }
113 }
114 }
115
116 workbook.save(output)?;
117
118 Ok(())
119}