You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 02:10:15