バックエンドから50音を取得する
ここから、ようやくRustでバックエンドをコーディングしていきます。まだバックエンドでなければできない機能ではないのですが、バックエンドからフロントエンドに50音を取得してみます。
「main.js」と「main.rs」を記述して「$ cargo-tauri dev」コマンドで実行し、テーブル表左上の「開く」ボタンをクリックすれば、図1と同じ50音がテーブル表に表示されます。バックエンドから送られたデータですが、まだxlsxファイルのデータではありません。
JavaScriptからバックエンドを呼び出す
TAURIコマンド「get_data」関数を呼び出して、5列10行の数値とともに50音の文字列配列を取得します。その3つを取得したら初期データと同様に「setData」関数に「列数」引数と「行数」引数と「セルの文字列配列」引数を渡します。
・「src」→「main.js」ファイルのサンプルコード
6 | let data = await invoke("get_data",{}); |
7 | setData(data[0],data[1],data[2]); |
【サンプルコードの解説】
非同期で「get_data」メッセージを送って戻り値を「data」変数に取得します。
「setData」関数にdata配列を3つの引数にして渡します。
Rustからフロントエンドへ50音を返す
先ほどJavaScriptから呼び出したTAURIコマンド「get_data」関数はRustでバックエンドにコーディングします。この関数で(5列,10行,50音の文字列配列)タプルを取得できます。この関数は後ほど「50音.xlsx」ファイルに保存する際にも使います。
・「src-tauri」→「src」→「main.rs」ファイルのサンプルコード
01 | #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] |
04 | fn get_data() -> (u32,u32,Vec<String>) { |
06 | "あ".to_string(),"い".to_string(),"う".to_string(),"え".to_string(),"お".to_string(), |
07 | "か".to_string(),"き".to_string(),"く".to_string(),"け".to_string(),"こ".to_string(), |
08 | "さ".to_string(),"し".to_string(),"す".to_string(),"せ".to_string(),"そ".to_string(), |
09 | "た".to_string(),"ち".to_string(),"つ".to_string(),"て".to_string(),"と".to_string(), |
10 | "な".to_string(),"に".to_string(),"ぬ".to_string(),"ね".to_string(),"の".to_string(), |
11 | "は".to_string(),"ひ".to_string(),"ふ".to_string(),"へ".to_string(),"ほ".to_string(), |
12 | "ま".to_string(),"み".to_string(),"む".to_string(),"め".to_string(),"も".to_string(), |
13 | "や".to_string()," ".to_string(),"ゆ".to_string()," ".to_string(),"よ".to_string(), |
14 | "ら".to_string(),"り".to_string(),"る".to_string(),"れ".to_string(),"ろ".to_string(), |
15 | "わ".to_string()," ".to_string(),"を".to_string()," ".to_string(),"ん".to_string(),]; |
21 | tauri::Builder::default() |
22 | .invoke_handler(tauri::generate_handler![get_data]) |
23 | .run(tauri::generate_context!()) |
24 | .expect("error while running tauri application"); |
【サンプルコードの解説】
「get_data」関数で(5,10,50音)タプルを返します。
メイン関数のtauriビルダーでTAURIコマンド「get_data」関数を登録します。
バックエンドで50音をxlsxファイルに保存
ここからバックエンドならではの機能として「umya-spreadsheet」クレートを使った実装をしていきます。手を抜くならサンプルのxlsxファイルを用意してダウンロードしてもらえば良いのですが、せっかくなのでxlsxファイルに書き出す処理も併せて解説したいと思います。
「save_data」関数で50音を「50音.xlsx」ファイルに保存するのですが、この関数はTAURIコマンド関数にはしません。メイン関数の最初で呼び出して実行するだけです。
いったん、これを「$ cargo-tauri dev」コマンドで実行して「../50音.xlsx」ファイルを作成しておいてください。ただしこのファイルパスはリリースビルドする際にはあまり行儀がよくありません。ファイルダイアログで保存先を指定できるように改造すると良いでしょう。
・「src-tauri」→「src」→「main.rs」ファイルのサンプルコード
01 | #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] |
04 | use umya_spreadsheet::*; |
07 | let mut book = new_file(); |
08 | let _ = book.new_sheet("Sheet1"); |
09 | let (col,row,data) = get_data(); |
13 | book.get_sheet_by_name_mut("Sheet1").unwrap().get_cell_mut((c, r)).set_value(data[i].clone()); |
17 | let path = Path::new("../50音.xlsx"); |
18 | let _ = writer::xlsx::write(&book, path); |
25 | tauri::Builder::default() |
26 | .invoke_handler(tauri::generate_handler![get_data]) |
27 | .run(tauri::generate_context!()) |
28 | .expect("error while running tauri application"); |
【サンプルコードの解説】
「path」と「umya_spreadsheet」クレートを読み込みます。
save_data関数でブックを新規作成し、そのブックに"Sheet1"という名前のシートを新規作成します。50音をget_data関数から取得します。"Sheet1"の(c列,r行)タプルのセルにdata配列から取得した値をセットします。ブックを「../50音.xlsx」ファイルに保存します。
メイン関数でsave_data関数を呼び出します。
ファイルダイアログでxlsxファイルを読み込む
次のサンプルコードのように「main.js」「main.rs」ファイルを記述したら、やっとテーブル左上の「開く」ボタンをクリックすれば、ファイルダイアログでExcel独自形式のxlsxファイルが読み込まれ、Webページにテーブル表が表示されるようになります。
図3のように50音だけでなく、たいていのxlsxファイルのセルの文字列が読み込めます。ただしA~Zの26列までしかヘッダーは対応していませんが、行数はメモリの許す限り読み込めると思います。
図3:50音以外のxlsxファイルを読み込んだ画面
JavaScriptでファイルダイアログの表示
ファイルダイアログ(open関数)はフロントエンドのJavaScriptで表示します。xlsxファイルを開いたらバックエンドのTAURIコマンド「open_data」関数にそのファイル名を引数に渡して呼び出し、Excelデータから抜き出したデータを取得します。
・「src」→「main.js」ファイルのサンプルコード
01 | const { invoke } = window.__TAURI__.tauri; |
03 | const { open,save } = window.__TAURI__.dialog; |
11 | let data = await invoke("get_data",{}); |
12 | setData(data[0],data[1],data[2]); |
15 | // Rustからxlsxファイルを読み込む |
18 | { name: 'Excel', extensions: ['xlsx'] }, |
20 | }).then(async file => { |
21 | let data = await invoke("open_data", { path: file }); |
22 | setData(data[0],data[1],data[2]); |
【サンプルコードの解説】
TAURIのJavaScriptの「open」関数を読み込みます。
コメントアウトした50音の取得のコードを削除します。
open関数でファイルの種類をxlsx拡張子だけにしてファイルダイアログを開き、選択したファイルを「open_data」メッセージで読み込んで表示します。
Rustでxlsxファイルの読み込み
JavaScriptから渡された"open_data"メッセージでTAURIコマンド関数が呼ばれ、ファイルダイアログのファイル名のxlsxファイルを開いて(列数、行数、セルの文字列の配列)タプルを取得できます。Rustではタプルは「()」で囲みますが、JavaScriptでは配列もタプルも配列と同じ「[]」で囲みます。
・「src-tauri」→「src」→「main.rs」ファイルのサンプルコード
02 | // xlsxファイルを開くTAURIコマンド関数 |
04 | fn open_data(path: &str) -> (u32,u32,Vec<String>) { |
05 | let path = Path::new(path); |
06 | let mut book = reader::xlsx::read(path).unwrap(); |
07 | let ws = book.get_active_sheet_mut(); |
08 | let (col,row) = ws.get_highest_column_and_row(); |
09 | let mut data = Vec::new(); |
12 | data.push(ws.get_value((c,r))); |
21 | tauri::Builder::default() |
22 | .invoke_handler(tauri::generate_handler![get_data,open_data]) |
23 | .run(tauri::generate_context!()) |
24 | .expect("error while running tauri application"); |
【サンプルコードの解説】
「open_data」関数の引数のxlsxファイルをブックに読み込み、アクティブなシートをws(ワークシート)変数に代入します。最大列数と最大行数を取得して、その各(列,行)タプルのセルの文字列を「data」変数に追加します。(列数,行数,data配列)タプルを返します。
メイン関数でコメントアウトした「save_data」関数の呼び出しを削除し、tauriビルダーにTAURIコマンドopen_data関数を登録します。
おわりに
今回は、Excel独自形式のxlsxファイルを読み書きしてWebページのテーブル表にセルの文字列を表示してみました。クレートを使えばExcelデータをWebページで表示することも可能です。このような感じでクレートを使って様々なデータをWebページで表示してみると良いでしょう。