同一ワークブックの同時アクセスおよび例外送出について
Note
OSBXLでは、 同一Excelファイルに対し、createWorkBook や openWorkBook から WorkBook#close メソッドまでの単一性、逐次性が保証 されます。
それ故、ファイルの同時アクセスの問題を心配する必要がありません。
Node上で非同期処理も可能です。同一Excelファイルへの複数アクセスに関しては、逐次処理となります(待ち受けキューの先頭から処理されます)
Note
OSBXLでは、 バックエンド側でバリデーション例外が起きた時、例外が送出され 、コードでハンドリング可能です。
(try ~ catch ロジックで、例外ハンドリング出来ます。)
非同期処理および例外処理のサンプル
以下のコードは、非同期処理で、2並列同時実行を行う例です。
createWorkBookでファイルを新規作成しますが、既にファイルが存在した場合、openWorkBookでファイルオープンに切り替えます。
import { nodeosbxl, enums, dto } from 'nodeosbxl';
import * as fs from 'fs'
if (fs.existsSync("hello.xlsx")) {
fs.rmSync("hello.xlsx");
}
// 2並列
const requestArray = [1, 2];
// nodeosbxlのインスタンス
let app = new nodeosbxl.App();
// 非同期処理関数
async function asyncFunc(item: Number) {
console.log(`asyncFunc${item} called`);
// Promiseを返却する非同期処理ロジック
return new Promise<void>((resolve, reject) => {
let wb = null;
try {
// 新規ワークブックを作成しようとします。
//(同一Excelファイルの複数アクセスに対しては、バックエンド側(C++)側でロックをかけるため、アクセスの早い順に単一処理されます)
// つまり、同一Excelファイルに対し、createWorkBook や openWorkBook から WorkBook#close メソッドまでの単一性、逐次性が保証されます。
// それ故、Webのサーバーサイドのプログラムなどでは、同一ファイルの複数アクセスについて、考慮する必要がありません。
wb = app.createWorkBook("hello.xlsx", enums.XlFont.MS_PGOTHIC, 12.0);
}
// nodeosbxlでは、サーバー側でのバリデーション失敗時に例外送出されます。
// このサンプルでは、同時にfuncメソッドを2つ並列処理しますが、2つ目の並列処理が実行された際に、例外を投げます。
// 上の説明に書いた、createWorkBook や openWorkBook から WorkBook#close メソッドまでの単一性が保証されているため、
// 1つ目の並列処理が終わった時点で、ファイルが作成され、2つ目の並列処理のcreateWorkBookに失敗するからです。
catch (error) {
// 例外内容を出力します。
console.error(error);
// openWorkBook に切り替えます。
wb = app.openWorkBook("test1.xlsx");
}
let ws = wb.openWorkSheet("Sheet1");
for (var i = 1; i < 10; i++) {
for (var j = 1; j < 10; j++) {
const num = Math.floor(Math.random() * (100 - 1 + 1) + 1);
// ワークシートのセルに値を設定します。
ws.getCells(i, j).setNumberValue(num);
var colorobject = new dto.ColorObject();
colorobject.setThemeColor(enums.XlThemeColor.ThemeColorAccent1, 0.2);
// ワークシートのセルの背景色を設定します。
ws.getCells(i, j).getFill().setCellColorObject(colorobject);
}
}
// 行コピーを行います。
ws.copyRow("Sheet1", 1, 2, 20, enums.XlCopyContentType.CopyContentTypeAll);
// ワークブックを保存します。
wb.save();
// ワークブックを閉じ、ワークブックのメモリを解放します。
wb.close();
console.log(`${item} done`);
resolve();
})
}
// Promise格納用オブジェクト
const promises: any = [];
// 非同期関数の準備
requestArray.forEach((request) => {
promises.push(asyncFunc(request));
});
// 非同期関数の実行
Promise.all(promises)
.then(result => {
console.log('all done');
})
.catch(err => {
console.log('error happens');
})
console.log('main executed');