thscharler / spreadsheet-ods

Apache License 2.0
29 stars 6 forks source link

How to get the style of text within cells? #26

Closed claytonrcarter closed 2 years ago

claytonrcarter commented 2 years ago

Hi, thank you for this great library! I'm sorry that this is more of a how-to question than a bug (I think), but how can I get access to the styling properties of individual cell values? I have been trying to use CellStyle, but it seems like that's intended for some sort of named, reusable style. I'm interested in the ad-hoc styles that get applied to cells; for example when using LibreOffice, editing a cell and making it bold or such by pressing Cmd-b.

Here's an example file: test-cell-styles.ods

With these contents:

Screen Shot 2022-06-04 at 6 02 56 AM

Here's a code snippet to print the position and cellstyle() for each cell, but they all return None.

fn main() {
    let path = std::path::Path::new("test-cell-styles.ods");
    let wb = spreadsheet_ods::read_ods(path).unwrap();
    let sheet = wb.sheet(0);
    for iter in sheet.iter() {
        let ((row, col), _) = iter;
        println!("({}, {}) => {:?}", row, col, sheet.cellstyle(row, col));
    }
}

And the output of this code:

❯ cargo run
   Compiling rust_spreadsheet v0.1.0 (/Users/crcarter/src/Other/rust-spreadsheet)
    Finished dev [unoptimized + debuginfo] target(s) in 1.78s
     Running `target/debug/rust_spreadsheet`
(0, 0) => None
(0, 1) => None
(0, 2) => None
(0, 3) => None
(0, 4) => None

My use case is that I'm trying to display an ODS and I want to be able to display these cell contents as accurately as possible, so I want to know something like this:

(0, 0) => { text_style: Bold,             text_color: None, background_color: None }
(0, 1) => { text_style: Underline,        text_color: None, background_color: None }
(0, 2) => { text_style: Bold & Underline, text_color: None, background_color: None }
(0, 3) => { text_style: None,             text_color: Red,  background_color: None }
(0, 4) => { text_style: None,             text_color: None, background_color: Yellow }

(This output is just made up, but gives an idea of the info I'm looking for.) Is it possible to determine the styling and coloring for these ad-hoc styles? Any help you can offer would be greatly appreciated!

This file was created via LibreOffice 7.2.1.2, and my code is using spreadsheet_ods 0.9.0 and rustc 1.61.0.

Thank you!

claytonrcarter commented 2 years ago

Oh, nevermind! After digging through the code of the ODS XML and this library, I found the "default column cellstyle" at Sheet::col_cellstyle. That does the trick:

fn main() {
    let path = std::path::Path::new("test-cell-styles.ods");
    let wb = spreadsheet_ods::read_ods(path).unwrap();
    let sheet = wb.sheet(0);
    for iter in sheet.iter() {
        let ((row, col), _) = iter;
        println!("({}, {}) => {:?} / {:?}", row, col, sheet.cellstyle(row, col), sheet.col_cellstyle(col));
    }
}
❯ cargo run
   Compiling rust_spreadsheet v0.1.0 (/Users/crcarter/src/Other/rust-spreadsheet)
    Finished dev [unoptimized + debuginfo] target(s) in 0.92s
     Running `target/debug/rust_spreadsheet`
(0, 0) => None / Some("ce1")
(0, 1) => None / Some("ce2")
(0, 2) => None / Some("ce3")
(0, 3) => None / Some("ce7")
(0, 4) => None / Some("ce8")

Then, I guess I use Workbook::cellstyle() to get the style properties and go from there. Sorry for the noise!

thscharler commented 2 years ago

Yes, working with the styles is tricky.

There can be a cell-style on a single cell, or a default-cell-style for a row or a column.

The content of the style then can be retrieved with Workbook::cellstyle(), true, but there is also the possibility that this style has a parent-style too.

I have not tried to resolve this, but map the underlying structure of the xml format.