use std::fs::File; use std::io::BufReader; use calamine::{Reader, open_workbook, Xlsx, Data, DataType}; use anyhow::Result; use crate::models::work_model::WorkModel; pub(crate) struct ExcelService { current_line: usize, work_book: Xlsx>, sheet: calamine::Range, } impl ExcelService { pub fn get_current_line(&self) -> usize { return self.current_line; } pub fn new(file_path: &str) -> Result { let mut work_book: Xlsx<_> = match open_workbook(file_path) { Ok(work_book) => work_book, Err(err) => return Err(err.to_string()) }; let sheet = match work_book.worksheet_range("Sheet1") { Ok(sheet) => sheet, Err(err) => return Err(err.to_string()) }; let mut service = ExcelService { current_line: 0, work_book, sheet, }; service.current_line = service.find_first_useful_line(); Ok(service) } pub fn find_first_useful_line(&mut self) -> usize { //find fist useful line, not contains empty cell and table head let mut current_line = 0; for row in self.sheet.rows() { current_line += 1; let mut is_useful = false; for cell in row { if cell.is_empty() { continue; } is_useful = true; break; } if is_useful { break; } } current_line } pub fn set_current_line(&mut self, line: usize)->Result<(), String>{ self.current_line = line; Ok(()) } pub fn roll_back(&mut self){ self.current_line -= 1; } pub fn get_next_work_model(&mut self) -> Result { let mut work_model = WorkModel::default(); if let Some(imei) = self.sheet.get((self.current_line, 0)) { if imei.is_empty() { return Err("No more data".to_string()); } work_model.imei = imei.to_string(); } if let Some(sn) = self.sheet.get((self.current_line, 1)) { work_model.sn = sn.to_string(); } if let Some(line_number) = self.sheet.get((self.current_line, 2)) { work_model.line_number = line_number.to_string(); } self.current_line += 1; Ok(work_model) } } #[test] fn open_excel_test() { let mut service = ExcelService::new("test_excel.xlsx").unwrap(); let model = service.get_next_work_model().unwrap(); let model2 = service.get_next_work_model().unwrap(); println!("{:?}", model); println!("{:?}", model2); }