如何使用calamine按坐标获取Excel单元格的值?
问题描述
我正在用Rust重构一个处理Excel的Python项目,目前已经能读取xlsx文件的所有值,现有代码如下:
use calamine::Reader; use calamine::open_workbook; use calamine::Xlsx; use calamine::DataType; fn main() { let path = "example.xlsx"; let mut workbook: Xlsx<_> = open_workbook(path).expect("Open Failed"); let mut rows: usize = 0; let mut cols: usize = 0; match workbook.worksheet_range("Sheet1") { Some(Ok(range)) => { rows = range.get_size().0; cols = range.get_size().1; for row in range.rows() { for ele in row { match ele { DataType::Float(value) => print!("{}", value), DataType::String(value) => print!("{}", value), DataType::Error(value) => print!("{}", value), DataType::Bool(value) => print!("{}", value), DataType::DateTime(value) => print!("{}", value), DataType::Empty => print!("/"), DataType::Int(value) => print!("{}", value), } print!(" | "); } println!(""); } }, _ => (), } println!("rows: {}, cols: {}", rows, cols); }
想获取(1, 3)这类坐标对应的单个单元格值,尝试使用get_value方法但未成功,尝试的代码如下:
use calamine::{Range, DataType}; let mut range = Range::new((0, 0), (5, 2)); assert_eq!(range.get_value((2, 1)), Some(&DataType::Empty)); range.set_value((2, 1), DataType::Float(1.0)); assert_eq!(range.get_value((2, 1)), Some(&DataType::Float(1.0)));
解决方案
要正确获取指定坐标的单元格值,需注意以下几点:
- 坐标起始规则:calamine的
Range采用0起始索引,如果你习惯Excel的1起始坐标,需要将目标坐标各值减1转换,比如Excel的第2行第4列对应(1, 3)。 - 现有Range的使用方式:从
workbook.worksheet_range获取的Range是只读的,直接调用get_value即可,无需手动创建新的Range实例。 - 坐标有效性校验:调用
get_value前要确认坐标在range.get_size()返回的行列范围内,超出范围会返回None。
修改原有代码,添加获取指定单元格值的逻辑示例:
use calamine::Reader; use calamine::open_workbook; use calamine::Xlsx; use calamine::DataType; fn main() { let path = "example.xlsx"; let mut workbook: Xlsx<_> = open_workbook(path).expect("Open Failed"); match workbook.worksheet_range("Sheet1") { Some(Ok(range)) => { let (rows, cols) = range.get_size(); println!("rows: {}, cols: {}", rows, cols); // 获取(1,3)坐标的单元格值(0起始) if let Some(cell_value) = range.get_value((1, 3)) { match cell_value { DataType::Float(v) => println!("Cell (1,3) value: {}", v), DataType::String(v) => println!("Cell (1,3) value: {}", v), DataType::Bool(v) => println!("Cell (1,3) value: {}", v), DataType::DateTime(v) => println!("Cell (1,3) value: {}", v), DataType::Int(v) => println!("Cell (1,3) value: {}", v), DataType::Error(v) => println!("Cell (1,3) error: {}", v), DataType::Empty => println!("Cell (1,3) is empty"), } } else { println!("Cell (1,3) is out of range"); } // 原有遍历逻辑 for row in range.rows() { for ele in row { match ele { DataType::Float(value) => print!("{}", value), DataType::String(value) => print!("{}", value), DataType::Error(value) => print!("{}", value), DataType::Bool(value) => print!("{}", value), DataType::DateTime(value) => print!("{}", value), DataType::Empty => print!("/"), DataType::Int(value) => print!("{}", value), } print!(" | "); } println!(); } }, Some(Err(e)) => println!("Failed to get worksheet range: {}", e), None => println!("Worksheet 'Sheet1' not found"), } }
常见问题排查
- 若
get_value返回None,先检查坐标是否超出range.get_size()的行列范围; - 确认工作表名称拼写正确(注意大小写、空格);
- 确保文件路径正确,且文件未被其他程序占用。
内容的提问来源于stack exchange,提问作者baby195lxl
相关产品推荐
相关产品推荐

