ラベル Excel の投稿を表示しています。 すべての投稿を表示
ラベル Excel の投稿を表示しています。 すべての投稿を表示

2024年11月22日金曜日

Danfo.jsとGrid.jsを使ってExcelをアップロードせずにプレビューする

TensorFlow.jsとの関連でDanfo.jsを使う機会がありました。DataFramesやTensorsを扱うのが主な用途のようですが、Excelを読むAPIがあったので、Grid.jsと組み合わせてExcelのプレビューを実装してみました。プレビューはブラウザで完結しているので、Excelファイルはサーバーにアップロードしません。

作成したアプリケーションは以下のように動作します。


今回作成したサンプルのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/preview-excel-with-danfo-js-and-grid-js.zip

空のAPEXアプリケーションにデフォルトで作成されるホーム・ページに、すべての機能を実装しています。

ページ・プロパティのJavaScriptのファイルURLに以下を記述します。Danfo.jsとGrid.jsのライブラリをページにロードしています。

https://cdn.jsdelivr.net/npm/danfojs/lib/bundle.min.js
https://cdn.jsdelivr.net/npm/gridjs/dist/gridjs.production.min.js

ファンクションおよびグローバル変数の宣言に以下を記述します。変数elemは、Excelの内容をプレビューするリージョンを保持します。

var elem;

ページ・ロード時に実行に以下を記述します。プレビューは静的コンテンツのリージョン(に子ノードを作成して)にプレビューしますが、その要素をelemに取得します。Grid.jsによるグリッド上でページ送りをする際にページ番号をクリックしますが、そのときにページの送信が行われないように、イベントのデフォルトの動作をキャンセルしています。
elem = document.getElementById("grid");
// Grid.jsでページングする際にページの送信を行わない。
elem.addEventListener('click', function(event) {
    event.preventDefault();
});
Grid.jsが必要とするCSS設定ファイルを、CSSのファイルURLに設定します。

https://cdn.jsdelivr.net/npm/gridjs/dist/theme/mermaid.min.css

ページ・プロパティへの設定は以上です。


プレビューするExcelファイルを選択するページ・アイテムをP1_EXCELとして作成します。タイプはファイルのアップロードです。このサンプル・アプリケーションでは、選択したファイルをサーバーにアップロードすることはありません。

サーバーに送信する場合は、ストレージのタイプやファイルをパージするタイミングなどを適切に設定します。


プレビューを表示するリージョンを作成します。タイプは静的コンテンツ、外観のテンプレートとして、装飾の無いBlank with Attributes (No Grid)を選んでいます。静的IDとしてgridを設定します。


ページ・アイテムP1_EXCELで選択したファイルを、リージョンGridにプレビューするボタンを作成します。

ボタン名はPREVIEW、動作のアクションは動的アクションで定義を選択します。


ボタンPREVIEWをクリックしたときに、以下のJavaScriptのコードを実行します。



以上でアプリケーションは完成です。アプリケーションを実行すると、記事の先頭のGIF動画のように動作します。

今回の記事は以上です。

Oracle APEXのアプリケーション作成の参考になれば幸いです。

完

2023年7月3日月曜日

Excelをアップロードしてフォームの穴埋めを行う

 以下のような簡単なExcelシートをAPEXアプリケーションにアップロードし、その内容でフォームの穴埋めをします。


以下のように動作するアプリケーションを作成します。


クラシック・レポートを使ってブラウザで穴埋めする実装と、APEXコレクションを使ってサーバー側で穴埋めする実装の2種類を試してみます。

アプリケーション作成ウィザードを起動し、空のアプリケーションを作成します。名前はExcel Formとします。




クラシック・レポートを使う



空白ページを作成します。ページ定義の名前はClassic Reportとします。


フォームの穴埋めに使うExcelファイルを指定するページ・アイテムを作成します。

識別の名前はP2_FILE、タイプはファイル参照...を選びます。設定の記憶域のタイプとしてTable APEX_APPLICATION_TEMP_FILES、ファイルをパージするタイミングとしてEnd of Sessionを選びます。表示形式は任意ですが、ここではInline File Browseを選択しています。

セッション・ステートのストレージはセッションごと(永続)を選択します。


ファイルをアップロードするボタンを作成します。

識別のボタン名はSUBMIT、ラベルはSubmitとします。動作のアクションはページの送信です。


Excelシートから取り出した値を保持するページ・アイテムを作成します。

ページ・アイテムP2_NAMEに氏名、P2_DEPTに所属、P2_PURPOSEに目的、P2_AMOUNTに金額を保持します。P2_NAME、P2_DEPT、P2_PURPOSEのタイプはテキスト・フィールド、P2_AMOUNTは数値フィールドとします。

セッション・ステートのストレージはリクエストごと(メモリーのみ)とします。


クラシック・レポートのリージョンを作成し、アップロードされたExcelを表形式にします。

リージョンを作成し、識別のタイトルとしてDocument、タイプとしてクラシック・レポートを選択します。ソースのタイプとしてSQL問合せを選択し、SQL問合せとして以下を記述します。

詳細の静的IDとしてdocumentを設定します。


属性の遅延ロードはオフにします。


クラシック・レポートから値を取り出し、ページ・アイテムに設定します。

ページ・プロパティのJavaScriptのページ・ロード時に実行に、以下を記述します。



ページの表示時に一瞬レポートが表示されます。それを抑止するために、ページのテンプレート・オプションを開き、Deferred Page Renderingにチェックを入れます。


以上で実装は完了です。


遅延ロードをオンにする



クラシック・レポートの遅延ロードがオンの場合は、クラシック・レポートの表示はページのロードとは非同期で実行されます。そのため、JavaScriptによる穴埋め処理は動的アクションのイベントリフレッシュ後に実行する必要があります。

ページ番号2のコピーをページ番号3として作成し、クラシック・レポートの遅延ロードをオンにします。

クラシック・レポートに動的アクションを作成します。

タイミングのイベントとしてリフレッシュ後を選択します。


TRUEアクションとしてJavaScriptコードの実行を選択し、設定のコードとして以下を記述します。



ページ・プロパティのJavaScriptのページ・ロード時に実行に記載されたコードは削除します。


以上で実装は完了です。

遅延ロードをオンにしている場合、レポートのリフレッシュ後に一瞬レポートが表示される状況を抑止するのは難しそうです。


APEXコレクションを使う



ページ番号3のコピーをページ番号4として作成し、クラシック・レポートのリージョンを削除します。

アップロードされたExcelからAPEXコレクションを作成し、それからフォームの穴埋めを行います。

プロセス・ビューを表示させ、新規にプロセスを作成します。

識別の名前はFill Form、タイプとしてコードを実行を選択します。ソースのPL/SQLコードに以下を記述します。


サーバー側の条件のボタン押下時にSUBMITを指定します。


サーバー側で実行されるプロセスでページ・アイテムに値を設定しているため、穴埋めに使用されるページ・アイテムのセッション・ステートのストレージはセッションごと(永続)にする必要があります。


反対に、アップロードするファイルを参照するページ・アイテムの設定のファイルをパージするタイミングはEnd of Request、セッション・ステートのストレージはリクエストごと(メモリーのみ)に変更できます。


以上で実装は完了です。

クラシック・レポートを使った実装を紹介していますが、APEXコレクションを使った実装が一番扱いやすいと思います。

今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/fill-form-excel.zip

Oracle APEXのアプリケーション作成の参考になれば幸いです。

完