//! # 宏测试 1 //! //! 自动生成表头,自动写入数据 //! use std::time::Instant; use umya_spreadsheet::Worksheet; use xlsx_group_write::prelude::*; use rand::prelude::*; // # 示例 1 : 自动生成表头,各行数据自动写入 #[derive(XlsxGroupWriteQuicker)] #[xlsx_group_write( line_writer_simple = "line_index-1:number,&self.name,&self.tel,&self.dep", group_maker = "&self.dep", template_simple = "序号,姓名,手机,部门", output_file_name_simple = "/tmp/test", )] struct MySimpleData { pub name: String, pub tel: String, pub dep: String, } impl MySimpleData { pub fn new(name: &str, tel: &str, dep: &str) -> Self { Self { name: name.into(), tel: tel.into(), dep: dep.into(), } } } #[test] fn test_simple() { // 初始化待导出数据 let data = vec![ MySimpleData::new("张三", "185xxxx2228", "网金部"), MySimpleData::new("李四", "185xxxx2229", "运管部"), MySimpleData::new("王二", "185xxxx2230", "网金部"), ]; // 导出数据到xlsx文件 // 自动按照部门分别导出,同时还汇总导出一个汇总xlsx文件 // 成功导出返回对应的文件信息和分组id let resp = MySimpleData::write2xlsx_all(&data); println!("resp:{resp:#?}"); } // # 示例 2.1 : 以某xlsx文件为模板,生成表标题和表头,并在表格添加自定义信息,各行数据自动写入 #[derive(XlsxGroupWriteQuicker)] #[xlsx_group_write( line_writer_simple = "line_index-1:number,&self.name,&self.tel,&self.dep", group_maker = "&self.dep", template_advance = "/home/feiy/Desktop/temp.xlsx,4", custom_info_adder = "Self::add_custom_info", output_file_name_simple = "/tmp/test", output_file_name_add_date = "true" )] struct MySimpleDataWithTemplate { pub name: String, pub tel: String, pub dep: String, } impl MySimpleDataWithTemplate { pub fn new(name: &str, tel: &str, dep: &str) -> Self { Self { name: name.into(), tel: tel.into(), dep: dep.into(), } } /// 对导出的xlsx文件进行一些个性化修改 /// 比如需要在第二行插入对应分组名称,插入报表数据范围等信息 /// /// 将在xlsx初始化完成后自动调用该方法 /// /// # 参数说明 /// /// * sheet 要修改的xlsx工作表 /// * group_id 该xlsx对应的分组id fn add_custom_info(sheet: &mut Worksheet, group_id: &str) { sheet .get_cell_mut((&1, &2)) .set_value_string(&format!("{group_id},报表日期:2023年4月20日")); } } #[test] fn test_simple_with_template() { // 初始化待导出数据 let data = vec![ MySimpleDataWithTemplate::new("张三", "185xxxx2228", "网金部"), MySimpleDataWithTemplate::new("李四", "185xxxx2229", "运管部"), MySimpleDataWithTemplate::new("王二", "185xxxx2230", "网金部"), ]; // 导出数据到xlsx文件 // 自动按照部门分别导出,同时还汇总导出一个汇总xlsx文件 // 成功导出返回对应的文件信息和分组id let resp = MySimpleDataWithTemplate::write2xlsx_all(&data); println!("resp:{resp:#?}"); } // # 示例 3 : 以动态使用某xlsx文件为模板,生成表标题和表头,并在表格添加自定义信息,各行数据自动写入 #[derive(XlsxGroupWriteQuicker)] #[xlsx_group_write( line_writer_simple = "line_index-1:number,&self.name,&self.tel,&self.dep", group_maker = "&self.dep", template_getter = "Self::get_cur_template", custom_info_adder = "Self::add_custom_info", output_file_name_simple = "/tmp/test", output_file_name_add_date = "true" )] struct MySimpleDataWithTemplateGetter { pub name: String, pub tel: String, pub dep: String, } impl MySimpleDataWithTemplateGetter { pub fn new(name: &str, tel: &str, dep: &str) -> Self { Self { name: name.into(), tel: tel.into(), dep: dep.into(), } } /// 动态确定模板文件 fn get_cur_template() -> XlsxInitTemplet{ XlsxInitTemplet::new_advance("/home/feiy/Desktop/template.xlsx", 3) } /// 对导出的xlsx文件进行一些个性化修改 /// 比如需要在第二行插入对应分组名称,插入报表数据范围等信息 /// /// 将在xlsx初始化完成后自动调用该方法 /// /// # 参数说明 /// /// * sheet 要修改的xlsx工作表 /// * group_id 该xlsx对应的分组id fn add_custom_info(sheet: &mut Worksheet, group_id: &str) { sheet .get_cell_mut((&1, &2)) .set_value_string(&format!("{group_id},报表日期:2023年4月20日")); } } #[test] fn test_simple_with_template_getter() { // 初始化待导出数据 let data = vec![ MySimpleDataWithTemplateGetter::new("张三", "185xxxx2228", "网金部"), MySimpleDataWithTemplateGetter::new("李四", "185xxxx2229", "运管部"), MySimpleDataWithTemplateGetter::new("王二", "185xxxx2230", "网金部"), ]; // 导出数据到xlsx文件 // 自动按照部门分别导出,同时还汇总导出一个汇总xlsx文件 // 成功导出返回对应的文件信息和分组id let resp = MySimpleDataWithTemplateGetter::write2xlsx_all(&data); println!("resp:{resp:#?}"); } // # 示例 3 : 自动生成表头,各行数据调用个性化写入函数write_xlsx_line写入 #[derive(XlsxGroupWriteQuicker)] #[xlsx_group_write( line_writer_advance = "Self::write_xlsx_line", group_maker = "&self.dep", template_simple = "序号,姓名,手机,部门", output_file_name_simple = "/tmp/test", )] struct MyAdvanceData { pub name: String, pub tel: String, pub dep: String, } impl MyAdvanceData { pub fn new(name: &str, tel: &str, dep: &str) -> Self { Self { name: name.into(), tel: tel.into(), dep: dep.into(), } } fn write_xlsx_line( line_data:&MyAdvanceData, sheet: &mut Worksheet, line_index: u32, ) -> Option { XlsxWriterTool::set_excel_cell_value_number(sheet, 1, line_index, line_index - 1); XlsxWriterTool::set_excel_cell_value_str(sheet, 2, line_index, &format!("ad-{}",&line_data.name)); XlsxWriterTool::set_excel_cell_value_str(sheet, 3, line_index, &line_data.tel); XlsxWriterTool::set_excel_cell_value_str(sheet, 4, line_index, &line_data.dep); None } } #[test] fn test_advance_write() { // 初始化待导出数据 let data = vec![ MyAdvanceData::new("张三", "185xxxx2228", "网金部"), MyAdvanceData::new("李四", "185xxxx2229", "运管部"), MyAdvanceData::new("王二", "185xxxx2230", "网金部"), ]; // 导出数据到xlsx文件 // 自动按照部门分别导出,同时还汇总导出一个汇总xlsx文件 // 成功导出返回对应的文件信息和分组id let resp = MyAdvanceData::write2xlsx_all(&data); println!("resp:{resp:#?}"); } // # 示例 4 : 自动生成表头,各行数据自动写入,输出文件名称通过函数获取 #[derive(XlsxGroupWriteQuicker)] #[xlsx_group_write( line_writer_simple = "line_index-1:number,&self.name,&self.tel,&self.dep", group_maker = "&self.dep", template_simple = "序号,姓名,手机,部门", output_file_name_advance = "Self::get_output_file_name_advance", )] struct MyFileNameData { pub name: String, pub tel: String, pub dep: String, } impl MyFileNameData { pub fn new(name: &str, tel: &str, dep: &str) -> Self { Self { name: name.into(), tel: tel.into(), dep: dep.into(), } } /// 完全自定义的输出文件名称名称生成器 /// /// 参数说明: /// /// * groupt_id :当期数据的分组id #[allow(dead_code)] fn get_output_file_name_advance(group_id: &str) -> String { format!("/tmp/f-{group_id}.xlsx") } } #[test] fn test_advance_file_name() { // 初始化待导出数据 let data = vec![ MyFileNameData::new("张三", "185xxxx2228", "网金部"), MyFileNameData::new("李四", "185xxxx2229", "运管部"), MyFileNameData::new("王二", "185xxxx2230", "网金部"), ]; // 导出数据到xlsx文件 // 自动按照部门分别导出,同时还汇总导出一个汇总xlsx文件 // 成功导出返回对应的文件信息和分组id let resp = MyFileNameData::write2xlsx_all(&data); println!("resp:{resp:#?}"); } // # 示例 5 : 自动生成表头,各行数据自动写入 #[derive(XlsxGroupWriteQuicker)] #[xlsx_group_write( line_writer_simple = "line_index-1:number,&self.name,&self.tel,&self.dep", group_maker = "&self.dep", template_simple = "序号,姓名,手机,部门", output_file_name_simple = "/tmp/test", )] struct MyStrData<'a> { pub name: &'a str, pub tel: &'a str, pub dep: &'a str, } impl<'a> MyStrData<'a> { pub fn new(name: &'a str, tel: &'a str, dep: &'a str) -> Self { Self { name, tel, dep, } } } #[test] fn test_str_data() { // 初始化待导出数据 let data = vec![ MyStrData::new("张三", "185xxxx2228", "网金部"), MyStrData::new("李四", "185xxxx2229", "运管部"), MyStrData::new("王二", "185xxxx2230", "网金部"), ]; // 导出数据到xlsx文件 // 自动按照部门分别导出,同时还汇总导出一个汇总xlsx文件 // 成功导出返回对应的文件信息和分组id let resp = MyStrData::write2xlsx_all(&data); println!("resp:{resp:#?}"); } // # 示例 6 : 大数据测试 #[derive(XlsxGroupWriteQuicker)] #[xlsx_group_write( line_writer_simple = "line_index-1:number,&self.name,&self.tel,&self.dep", group_maker = "&self.dep", template_simple = "序号,姓名,手机,部门", output_file_name_simple = "/tmp/test", )] struct MyBigData { pub name: String, pub tel: String, pub dep: String, } impl MyBigData { pub fn new(name: &str, tel: &str, dep: &str) -> Self { Self { name:name.into(), tel:tel.into(), dep:dep.into(), } } } #[test] fn test_big_data() { // 初始化待导出数据 let mut data: Vec = Vec::with_capacity(1000); let deps = ["网金部","公司部","运管部","机构部","个金部"]; let mut rng = thread_rng(); let distr = rand::distributions::Uniform::new_inclusive(0, 4); for i in 1..=10000 { let name = i.to_string(); let tel = format!("185-{i}"); data.push(MyBigData::new( &name, &tel, deps[rng.sample(distr)] )) } let start = Instant::now(); // 导出数据到xlsx文件 // 自动按照部门分别导出,同时还汇总导出一个汇总xlsx文件 // 成功导出返回对应的文件信息和分组id let resp = MyBigData::write2xlsx_all(&data); println!("resp:{resp:#?}"); println!( " ==== 完毕,总耗时:{} 秒 ====", start.elapsed().as_secs() ); } // # 示例 7 : 自动生成表头,各行数据自动写入,传递额外参数到文件名称,写入个性化信息到xlsx表中 #[derive(XlsxGroupWriteQuicker)] #[xlsx_group_write( line_writer_advance_with_extra_arg = "Self::write_xlsx_line", group_maker = "&self.dep", template_getter = "Self::get_cur_template", extra_arg_type ="String", custom_info_adder = "Self::add_custom_info", output_file_name_advance = "Self::get_output_file_name_advance", )] struct MySimpleDataWithExtraArg { pub name: String, pub tel: String, pub dep: String, } impl MySimpleDataWithExtraArg { pub fn new(name: &str, tel: &str, dep: &str) -> Self { Self { name: name.into(), tel: tel.into(), dep: dep.into(), } } /// 写入行数据,传入额外参数 fn write_xlsx_line( line_data:&MySimpleDataWithExtraArg, sheet: &mut Worksheet, line_index: u32, extra_arg: Option<&String>, ) -> Option { XlsxWriterTool::set_excel_cell_value_number(sheet, 1, line_index, line_index - 1); XlsxWriterTool::set_excel_cell_value_str(sheet, 2, line_index, &format!("ad-{}",&line_data.name)); XlsxWriterTool::set_excel_cell_value_str(sheet, 3, line_index, &line_data.tel); XlsxWriterTool::set_excel_cell_value_str(sheet, 4, line_index, &line_data.dep); if let Some(extra_arg) = extra_arg{ XlsxWriterTool::set_excel_cell_value_str(sheet, 5, line_index, extra_arg); } None } /// 动态确定模板文件 fn get_cur_template() -> XlsxInitTemplet{ XlsxInitTemplet::new_advance("/home/feiy/Desktop/template.xlsx", 3) } /// 对导出的xlsx文件进行一些个性化修改 /// 比如需要在第二行插入对应分组名称,插入报表数据范围等信息 /// /// 将在xlsx初始化完成后自动调用该方法 /// /// # 参数说明 /// /// * sheet 要修改的xlsx工作表 /// * group_id 该xlsx对应的分组id fn add_custom_info(sheet: &mut Worksheet, group_id: &str,org_name:Option<&String>) { if let Some(org_name) = org_name{ sheet .get_cell_mut((&1, &5)) .set_value_string(&format!("{org_name} {group_id},报表日期:2023年4月20日")); }else{ sheet .get_cell_mut((&1, &5)) .set_value_string(&format!("{group_id},报表日期:2023年4月20日")); } } /// 完全自定义的输出文件名称名称生成器 /// /// 参数说明: /// /// * groupt_id :当期数据的分组id #[allow(dead_code)] fn get_output_file_name_advance(group_id: &str,org_name:Option<&String>) -> String { if let Some(org_name) = org_name{ format!("/tmp/f-{org_name}-{group_id}.xlsx") }else{ format!("/tmp/f-{group_id}.xlsx") } } } #[test] fn test_simple_with_extra_arg() { // 初始化待导出数据 let data = vec![ MySimpleDataWithExtraArg::new("张三", "185xxxx2228", "网金部"), MySimpleDataWithExtraArg::new("李四", "185xxxx2229", "运管部"), MySimpleDataWithExtraArg::new("王二", "185xxxx2230", "网金部"), ]; // 导出汇总数据到xlsx文件 // 成功导出返回对应的文件信息和分组id // 传入个性化参数 let resp = MySimpleDataWithExtraArg::write2xlsx_merge_only_with_extra_arg(&data,Some(String::from("个性化参数"))); println!("resp:{resp:#?}"); }