同一ワークブックの同時アクセスおよび例外送出について

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');