jmcnamara / rust_xlsxwriter

A Rust library for creating Excel XLSX files.
https://crates.io/crates/rust_xlsxwriter
Apache License 2.0
348 stars 25 forks source link

question: No two saves produce identical output #107

Closed arifd closed 3 months ago

arifd commented 3 months ago

Question

This makes me not be able to write a test and compare against a previously saved truth.

I suspect it just contains a timestamp or something, is there a way to make two saves be bitwise reproducible?

Btw, thanks for this wonderful contribution to the Rust ecosystem!!

jmcnamara commented 3 months ago

Thanks for the feedback.

That issue and the workaround is explained in the docs: https://docs.rs/rust_xlsxwriter/latest/rust_xlsxwriter/workbook/index.html#checksum-of-a-saved-file

arifd commented 3 months ago

Aha! damn... and your docs are so well written already... Apologies for not RTFM!

jmcnamara commented 3 months ago

Apologies for not RTFM

Not your fault. There is a lot of documentation and it hard to find something like that that isn't a function. 🙂

arifd commented 2 months ago

Hi @jmcnamara, this was the code I was using to write the creation date (before I used the chrono feature and passed in the Utc::now() directly):

use chrono::Utc;
use rust_xlsxwriter::*;

fn main() -> Result<(), XlsxError> {
    let mut wb = Workbook::new();

    // This will produce a corrupted file:
    wb.set_properties(
        &DocProperties::new()
            .set_creation_datetime(&ExcelDateTime::from_timestamp(Utc::now().timestamp())?),
    );

    wb.save("corrupted.xlsx")?;

    Ok(())
}

And it would create a file that appeared to be corrupt according Micrsofot Excel for Mac:

image (14)

Does anything strike out to you as obviously wrong here?

The documentation for both functions in the conversion:

ExcelDateTime::from_timestamp:

Create a ExcelDateTime instance from a Unix time.

Create a ExcelDateTime instance from a [Unix Time](https://en.wikipedia.org/wiki/Unix_time) which is the number of seconds since the 1970-01-01 00:00:00 UTC epoch. This is a common format used for system times and timestamps.

Leap seconds are not taken into account.

DateTIme::timestamp:

Returns the number of non-leap seconds since January 1, 1970 0:00:00 UTC (aka “UNIX timestamp”).
jmcnamara commented 2 months ago

Thanks for the report. That is a bug. I'll look into it.

jmcnamara commented 2 months ago

@arifd this is now fixed on main. Thanks for the report.