use datafusion::dataframe::DataFrameWriteOptions;
use datafusion::prelude::*;
use rust_xlsxwriter::{ExcelDateTime, Format, Workbook};
#[tokio::main]
async fn main() {
let mut wb = Workbook::new();
let date_fmt = Format::new().set_num_format("yyyy-mm-dd");
let people = wb.add_worksheet().set_name("People").unwrap();
for (c, h) in ["name", "age", "active", "joined"].iter().enumerate() {
people.write_string(0, c as u16, *h).unwrap();
}
let rows = [
("ada", 36.0, true, "2024-01-15"),
("grace", 45.0, false, "2023-11-02"),
("linus", 54.0, true, "2024-06-30"),
];
for (r, (name, age, active, joined)) in rows.iter().enumerate() {
let r = (r + 1) as u32;
people.write_string(r, 0, *name).unwrap();
people.write_number(r, 1, *age).unwrap();
people.write_boolean(r, 2, *active).unwrap();
let dt = ExcelDateTime::parse_from_str(joined).unwrap();
people
.write_datetime_with_format(r, 3, &dt, &date_fmt)
.unwrap();
}
let orders = wb.add_worksheet().set_name("Orders").unwrap();
for (c, h) in ["name", "amount"].iter().enumerate() {
orders.write_string(0, c as u16, *h).unwrap();
}
for (r, (name, amount)) in [("ada", 120.5), ("ada", 30.0), ("linus", 99.99)]
.iter()
.enumerate()
{
let r = (r + 1) as u32;
orders.write_string(r, 0, *name).unwrap();
orders.write_number(r, 1, *amount).unwrap();
}
wb.save("fixtures/sample.xlsx").unwrap();
eprintln!("wrote fixtures/sample.xlsx");
corpus();
parquet().await;
}
async fn parquet() {
let ctx = SessionContext::new();
ctx.register_csv("data", "fixtures/sample.csv", CsvReadOptions::new())
.await
.unwrap();
let df = ctx.sql("SELECT * FROM data").await.unwrap();
let _ = std::fs::remove_file("fixtures/sample.parquet");
df.write_parquet(
"fixtures/sample.parquet",
DataFrameWriteOptions::new().with_single_file_output(true),
None,
)
.await
.unwrap();
eprintln!("wrote fixtures/sample.parquet");
}
fn corpus() {
let dir = "fixtures/corpus";
let mut wb = Workbook::new();
let ws = wb.add_worksheet().set_name("Merged").unwrap();
for (c, h) in ["a", "b", "c"].iter().enumerate() {
ws.write_string(0, c as u16, *h).unwrap();
}
ws.write_number(1, 0, 1.0).unwrap();
ws.merge_range(1, 1, 1, 2, "wide value", &Format::new())
.unwrap();
ws.write_number(2, 0, 2.0).unwrap();
ws.write_string(2, 1, "x").unwrap();
ws.write_string(2, 2, "y").unwrap();
wb.save(format!("{dir}/merged.xlsx")).unwrap();
let mut wb = Workbook::new();
let ws = wb.add_worksheet().set_name("Formats").unwrap();
ws.write_string(0, 0, "price").unwrap();
ws.write_string(0, 1, "growth").unwrap();
let money = Format::new().set_num_format("$#,##0.00");
let pct = Format::new().set_num_format("0.00%");
ws.write_number_with_format(1, 0, 1234.5, &money).unwrap();
ws.write_number_with_format(1, 1, 0.42, &pct).unwrap();
wb.save(format!("{dir}/formats.xlsx")).unwrap();
let mut wb = Workbook::new();
let ws = wb.add_worksheet().set_name("Ragged").unwrap();
for (c, h) in ["a", "b", "c"].iter().enumerate() {
ws.write_string(0, c as u16, *h).unwrap();
}
ws.write_number(1, 0, 1.0).unwrap(); ws.write_number(2, 0, 2.0).unwrap();
ws.write_number(2, 1, 20.0).unwrap();
ws.write_number(2, 2, 200.0).unwrap(); wb.save(format!("{dir}/ragged.xlsx")).unwrap();
let mut wb = Workbook::new();
wb.add_worksheet()
.set_name("数据")
.unwrap()
.write_number(0, 0, 1.0)
.unwrap();
wb.add_worksheet()
.set_name("Ümläute!")
.unwrap()
.write_number(0, 0, 2.0)
.unwrap();
wb.add_worksheet()
.set_name("···")
.unwrap()
.write_number(0, 0, 3.0)
.unwrap();
wb.save(format!("{dir}/unicode.xlsx")).unwrap();
let mut wb = Workbook::new();
let ws = wb.add_worksheet().set_name("Padded").unwrap();
ws.write_string(0, 0, "n").unwrap();
ws.write_number(1, 0, 7.0).unwrap();
ws.write_blank(9, 4, &Format::new().set_num_format("0.00"))
.unwrap();
wb.save(format!("{dir}/padded.xlsx")).unwrap();
let mut wb = Workbook::new();
let ws = wb.add_worksheet().set_name("Big").unwrap();
ws.write_string(0, 0, "n").unwrap();
for r in 1..=20u32 {
ws.write_number(r, 0, r as f64).unwrap();
}
wb.save(format!("{dir}/rowcap.xlsx")).unwrap();
eprintln!("wrote {dir}/{{merged,formats,ragged,unicode,padded,rowcap}}.xlsx");
}