Closed jmcnamara closed 7 months ago
Wouldn't it be nicer to have serialize_vec(&items)
where items
is a Vec<Produce>
? That is, instead of having the vecs inside the struct.
Wouldn't it be nicer to have
serialize_vec(&items)
whereitems
is aVec<Produce>
? That is, instead of having the vecs inside the struct.
Thanks for the input. That is probably a common use case in JSON style responses.
The good news is that this would work with the current API once the serialize_headers()
step is completed.
For example:
use rust_xlsxwriter::{Format, Workbook, XlsxError};
use serde::Serialize;
fn main() -> Result<(), XlsxError> {
let mut workbook = Workbook::new();
// Add a worksheet to the workbook.
let worksheet = workbook.add_worksheet();
// Add a simple format for the headers.
let format = Format::new().set_bold();
// Create a serializable test struct.
#[derive(Serialize)]
#[serde(rename_all = "PascalCase")]
struct Produce {
fruit: &'static str,
cost: f64,
}
// Create some data instances.
let items = vec![
Produce {
fruit: "Peach",
cost: 1.05,
},
Produce {
fruit: "Plum",
cost: 0.15,
},
Produce {
fruit: "Pear",
cost: 0.75,
},
];
// Set up the start location and headers of the data to be serialized.
worksheet.serialize_headers_with_format(0, 0, &items.get(0).unwrap(), &format)?;
// Serialize the data.
worksheet.serialize(&items)?;
// Save the file.
workbook.save("serialize.xlsx")?;
Ok(())
}
This would also work for a tuple of structs:
// Create some data instances.
let items = (
Produce {
fruit: "Peach",
cost: 1.05,
},
Produce {
fruit: "Plum",
cost: 0.15,
},
Produce {
fruit: "Pear",
cost: 0.75,
},
);
// Set up the start location and headers of the data to be serialized.
worksheet.serialize_headers_with_format(0, 0, &items.1, &format)?;
// Serialize the data.
worksheet.serialize(&items)?;
Both examples produces the same output as the first example above. Would that work for you?
Because serialize_headers
does not require temporary item for its work, I think, it is better to provide only the type:
worksheet.serialize_headers::<Produce>(0, 0)?;
worksheet.serialize_headers_with_format::<Produce>(0, 0, &format)?;
I think, it is better to provide only the type:
@Mingun That would be nice.
However, I think an instance is required, and not just the type, since it needs to be serialized to find the fields to convert them to worksheet headers. Or am I missing something?
For reference the code of the method is here: https://github.com/jmcnamara/rust_xlsxwriter/blob/1844dfea6645383d55462f387d20232f6ea263ab/src/serializer.rs#L404-L425
I have added support for Serde serialization in v0.57.0. See Working with Serde in the rust_xlsxwriter
docs.
Some additional serialisation features and helpers will be added in upcoming releases.
I've added initial support for serialization of Serde structures to
rust_xlsxwriter
main under theserde
feature flag.The support works like this:
#[derive(Serialize)]
struct.worksheet.serialize()
repeatedly to write data, without having to specify the row/col position.For example:
Which would give this output:![worksheet_serialize](https://github.com/jmcnamara/rust_xlsxwriter/assets/94267/cd8c1b03-61a6-43d8-99b0-4c1cbf2c3168)
The output can be positioned anywhere in the worksheet. For example if we change this line in the previous example:
We get this output:
It will also serialize vectors in the struct:
This gives the same output as the first example.
From the docs:
I am looking for feedback on the workability of this technique for any serialization use case that people may have. In particular I'd appreciate feedback from trying to make it work with existing serialize structures (within reason of what could be applied to a worksheet). Please leave comments below.
The code is on main. You will need to enable it in a local project with the following or similar:
There is some ongoing work to add support for ExcelDateTime and Chrono date/times. I will also be adding a method for adding formatting to each field value, and options to ignore fields apart from Serde
#[serde(skip_serializing)]
, and also to reorder the fields. I may also change the error handling to just ignore unknown structs/fields.