RustでExcelのセルの書式を設定する

フリーランスエンジニアとして活動していて、現在携わっている案件ではRustとTauriを使ってExcelファイルを出力するデスクトップアプリを開発しています。先日、顧客から出力するExcelファイルで金額は間違いを防止するためにカンマ区切りにしたいという要望がありましたので、Rustでセルの書式を設定する方法を調べました。

前回の記事から引き続き、今回もExcelファイルを書き込むためのライブラリとして「[xlsxwriter-rs](https://docs.rs/crate/xlsxwriter/0.6.0)」を使用します。

xlsxwriter-rsでセルの書式設定を行うには`write_number_with_format`メソッドを使用します。第一引数に行番号、第二引数には列番号、第三引数には値、第四引数には書式の構造体のを渡します。

```:Rust
pub fn write_number_with_format<T>(
    &mut self,
    row: RowNum,
    col: ColNum,
    number: T,
    format: &Format
) -> Result<&mut Worksheet, XlsxError>
where
    T: Into<f64>,
```

> Write a formatted number to a worksheet cell.
> Write a number with formatting to a worksheet cell. The format is set via a Format struct which can control the numerical formatting of the number, for example as a currency or a percentage value, or the visual format, such as bold and italic text.
> All numerical values in Excel are stored as IEEE 754 Doubles which are the equivalent of rust’s f64 type. This method will accept any rust type that will convert Into a f64. These include i8, u8, i16, u16, i32, u32 and f32 but not i64 or u64. IEEE 754 Doubles and f64 have around 15 digits of precision. Anything beyond that cannot be stored by Excel as a number without loss of precision and may need to be stored as a string instead.
> Excel doesn’t have handling for NaN or INF floating point numbers. These will be stored as the strings “Nan”, “INF”, and “-INF” strings instead.
>> Arguments
>>row - The zero indexed row number.
>>col - The zero indexed column number.
>>number - The number to write to the cell.
>>format - The Format property for the cell.

https://docs.rs/rust_xlsxwriter/latest/rust_xlsxwriter/struct.Worksheet.html#method.write_number_with_format

第四引数には書式の構造体は`Format`構造体の`set_num_format`メソッドで生成します。`write_number_with_format`メソッドと`Format`構造体の`set_num_format`メソッドを使用して数値をカンマ区切りにするサンプルコードを載せます。


```Rust:Rust
use std::path::Path;
use rust_xlsxwriter::Workbook;

let mut book = Workbook::new();
let comma_format= Format::new().set_num_format("#,##0");

let sheet = book.add_worksheet();
sheet.set_freeze_panes(1, 1)?;
sheet.write_string(0, 0, "Header1")?;
sheet.write_string(0, 1, "Header2")?;
for i in 1..101 {
    sheet.write_number(i as u32, 0, i as f64)?;
    sheet.write_number_with_format(i as u32, 1, (i * 10000) as f64, &comma_format)?;
}
book.save(Path::new("test.xlsx"))?;
```

![スクリーンショット 2023-04-30 14.31.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76958/6669d48d-d45f-99f3-2d4a-91bc55a253f9.png)

無事RustでもExcelのセルの書式の設定が実現できました。

書式の部分（`#,##0`）を変更したら％表示にしたり、小数点以下の書式も設定できます。また、太字にしたり斜体にすることもできます。

```Rust:Rust
let currency_format = Format::new().set_num_format("€#,##0.00");
sheet.write_number_with_format(0, 0, 1234.5, &currency_format)?;

let percentage_format = Format::new().set_num_format("0.0%");
sheet.write_number_with_format(1, 0, 0.3300, &percentage_format)?;

let bold_italic_format = Format::new().set_bold().set_italic();
sheet.write_number_with_format(2, 0, 1234.5, &bold_italic_format)?;
```

![スクリーンショット 2023-04-30 15.24.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76958/15403e7b-0e01-c641-1519-e31da2401516.png)

上記以外にもいろいろな書式を設定することができるのでちょっと試してみてはいかがでしょうか。