Excelファイルの読み書き

最終更新日: 2026年1月30日

基本的な使い方9.4.0

スクリプトの冒頭で、ExcelProcessorとその関連クラスを利用できるようにします。

  var ExcelProcessor = Java.type("jp.jasminesoft.jfc.app.etl.excel.ExcelProcessor");
  var CellMap = Java.type("jp.jasminesoft.jfc.app.etl.excel.CellMap");

モデルJSWQUOTATIONの内容をExcelファイルに出力する例を示します。ここでJSWQUOTATIONの項目TEMPLATEFILEはファイル型項目で、登録/更新時にこの項目にExcelファイルを指定する運用とします。つまりTEMPLATEFILE項目に添付されたExcelファイルに内容を書き込んで保存するという使い方です。スクリプトの記載場所は「ヘルパ>登録」「ヘルパ>更新」とします。

  var ExcelProcessor = Java.type("jp.jasminesoft.jfc.app.etl.excel.ExcelProcessor");
  var CellMap = Java.type("jp.jasminesoft.jfc.app.etl.excel.CellMap");
    
  ExcelProcessor.newInstnace(JSWQUOTATION.class)
  .apply(new CellMap('ITEM1', '見積書', 'K5'))
  .apply(new CellMap('ITEM2', '見積書', 'K6'))
  .apply(new CellMap('ITEM3', '見積書', 'C8'))
  .apply(new CellMap('ITEM4', '見積書', 'D12'))
  .apply(new CellMap('ITEM5', '見積書', 'D13'))
  .apply(new CellMap('ITEM6', '見積書', 'D14'))
  .apply(new CellMap('ITEM7', '見積書', 'D16'))
  .apply(new CellMap('ITEM8', '見積書', 'D17'))
  .apply(new CellMap('ITEM9', '見積書', 'D18'))
  .apply(new CellMap('ITEM10', '見積書', 'D19'))
  .apply(new CellMap('ITEM11', '見積書', 'D20'))
  .apply(new CellMap('ITEM12', '見積書', 'C48'))
  .toExcel(JSWQUOTATION.TEMPLATEFILEJshfilename, JSWQUOTATION, null);
  • ExcelProcessorクラスはコンストラクタに親となるクラスを指定します。
  • 続いてapplyメソッドを使って出力ルールを指定します。applyメソッドの引数はCellMapクラスのインスタンスになります。CellMapクラスのコンストラクタは「項目」「出力Excelファイルのシート名」「出力Excelファイルのセル位置」になります。
  • toExcelメソッドで出力を行います。第一引数は出力先ファイルです。ここでは自モデルのファイル型項目 "TEMPLATEFILE" の物理パスである "TEMPLATEFILE_jshfilename" 項目を指定します。ただしキャメル記法ルールにより、スクリプト中では "_jshfilename" が "Jshfilename" に変化しています。
  • 第二引数は対象モデル(ストアモデル)を指定します。
  • 第三引数は子モデルを指定します。ここでは子モデルは存在しないのでnullとします。

親子モデルの場合

親モデルPARENTと、これに紐づく子モデルCHILDが用意されているとします。親であるPARENTモデルの詳細画面にオリジナルボタンを用意します。イベント名をOriginal1としたとき、このボタンを押すとスクリプトファイル ShowPARENT_Original1.js が実行されます。このスクリプトで動的にExcelファイルを作成します。

Designerでオリジナルボタンを定義してください。スクリプトファイルはcustomize/webapp/WEB-INF/script/PARENTフォルダにShowPARENT_Original1.jsとして保存します。

  var ExcelProcessor = Java.type("jp.jasminesoft.jfc.app.etl.excel.ExcelProcessor");
  var CellMap = Java.type("jp.jasminesoft.jfc.app.etl.excel.CellMap");
  var ChildRecordMultiRowMap = Java.type("jp.jasminesoft.jfc.app.etl.excel.ChildRecordMultiRowMap");
  var Path = Java.type("java.nio.file.Path");
  var Paths = Java.type("java.nio.file.Paths");
  var Files = Java.type("java.nio.file.Files");

  var OUTPUTDIR = "../../upload_dir/PARENT";// 出力先フォルダ。Wagbyのファイル型は通常upload_dir/モデルIDフォルダに保存される仕様。
  var FILENAME = "YOUR_TEMPLATE_EXCELFILE.xlsx";// Excelのテンプレートファイルとして用意しておく。
  var TEMPLATEFOLDER = "/WEB-INF/classes/exceltemplate/";// 上のテンプレートファイルが格納されているフォルダ
  // テンプレートファイルを読み込む。   
  var templatefilepath;
  var resloader = p.request.getAttribute(Packages.jp.jasminesoft.jfc.IActionParameter.ScriptFileResourceLoaderRequestName);
  if (resloader != null) {
    try {
      var res = resloader.getResource(TEMPLATEFOLDER + FILENAME);
      file = res.getFile();
      templatefilepath = file.toPath();
    } catch (e) {
    }
  }
  var outputDir = Paths.get(OUTPUTDIR);
  if (!Files.exists(outputDir)) {
    try {
      Files.createDirectory(outputDir);
    } catch (e) {
      scriptLogger.error("出力先フォルダの作成に失敗しました。"+OUTPUTDIR, e);
    }
  }
  var PARENTClass = Java.type("jp.jasminesoft.wagby.model.PARENT.PARENT");//親クラス
  var CHILDClass = Java.type("jp.jasminesoft.wagby.model.CHILD.CHILD");//子クラス(外部キーで親と紐づく)
  var CHILDAry = p.request.getAttribute("CHILD_ary");//親クラスの詳細画面では、紐づく子クラスが 子クラス名_ary という名前でrequestに保持されている。

  //print("PARENT="+PARENT);
  //print(java.util.Arrays.asList(CHILDAry));
  scriptLogger.info("Excel出力を行います。テンプレートファイルは"+templatefilepath+"を使います。");

  var outputfilename = PARENT.TITLE + "_" + FILENAME;//ファイル名に親モデルのTITLE項目を含めている。
  try {
    ExcelProcessor.newInstnace(PARENTClass.class)
    .apply(new CellMap('COMPANYNAME', 'テンプレート', 'C3'))
    .apply(new CellMap('DEPTNAME', 'テンプレート', 'C4'))
    .applyChildRecordMap(
      CHILDClass.class,
      new ChildRecordMultiRowMap(
        'テンプレート',
        6,
        CHILDAry.length,
        "[{'B':'PLANDAY'},{'C':'KBNPRODUCT'},{'D':'PRODUCTNAME'}]",
        1
      )
    )
    .toExcel(templatefilepath, outputDir, outputfilename, PARENT, CHILDAry);
    var info = new Jfcinfo();
    info.content = "ファイル"+FILENAME+"を出力しました。";
    p.errors.addJfcinfo(info);
    scriptLogger.info("ファイル"+FILENAME+"を出力しました。");
  } catch (e) {
    var error = new Jfcerror();
    error.content = "Excel出力"+FILENAME+"に失敗しました。";
    p.errors.addJfcerror(error);
    scriptLogger.error("Excel出力"+FILENAME+"に失敗しました。", e);
  } 
  return "redirect:showPARENT.do?ID="+PARENT.ID;
}
  • この例では、開発者はあらかじめ出力用のテンプレートファイルを用意する運用としました。ここではYOUR_TEMPLATE_EXCELFILE.xlsxとしています。ファイル名は適切に設定してください。このテンプレートファイルをcustomize/resources/exceltemplateフォルダに保存します。するとビルド時にWEB-INF/classesフォルダにコピーされます。
  • 出力先フォルダはWagbyが標準で用意しているupload_dir/<モデルID>フォルダとします。実行時の起点がwagbyapp/binであるため、スクリプト中では "../../upload_dir/PARENT" としています。このフォルダにはファイル型項目の物理ファイルが保存されるというWagbyのルールがあります。
  • ExcelProcessorクラスはコンストラクタに親となるクラスを指定します。
  • 続いてapplyメソッドを使って出力ルールを指定します。applyメソッドの引数はCellMapクラスのインスタンスになります。CellMapクラスのコンストラクタは「(親の)項目」「テンプレートExcelのシート名」「テンプレートExcelのセル位置」になります。
  • 親に紐づく子がある場合、applyChildRecordMapメソッドを使って子の情報を指定できます。最初の引数は子のクラスです。次の引数はChildRecordMultiRowMapクラスのインスタンスで、これは連続した複数行を表現します。
  • ChildRecordMultiRowMapの引数は「テンプレートExcelのシート名」「テンプレートExcelの開始行」「対象オブジェクトの数」「行内のセルのルール」となります。
  • 「行内のセルのルール」はJSON形式で記述します。具体的には [] という配列表記の内部に {'セルの列','子モデルの項目'} をコンマ区切りで列挙します。

セルを修飾する

CellDecorationクラスを使って書き込みするExcelファイルのセルを修飾することができます。

  var CellDecoration = Java.type("jp.jasminesoft.jfc.app.etl.excel.CellDecoration");
  ...
  var decoration = new CellDecoration();
  decoration.setBorderTop(true);   //セルの上のボーダー(罫線)
  decoration.setBorderBottom(true);//セルの下のボーダー(罫線)
  decoration.setBorderLeft(true);  //セルの左のボーダー(罫線)
  decoration.setBorderRight(true); //セルの右のボーダー(罫線)
  decoration.setBackgroundColor(new java.awt.Color(255,200,150));// 背景色をRGBの数値で指定
  ...
  ExcelProcessor.newInstnace(SAMPLE.class)
  .applyChildRecordMap(
    (SAMPLECHILD.class,
    new ChildRecordMultiRowMap(
      'テンプレート',
      3,
      SAMPLECHILDAry.length,
      "[{'C':'KIGYO'},{'D':'KIGYO2'},{'E':'PURCHASE'},{'F':'PATHWAY'},{'G':'PARENTPN'},{'H':'LEVEL'},{'I':'CDPN'},{'J':'CNAME'}]",
      1, // ステップ。N行=1データ
      decoration,
      false // 偶数行のみ背景色を指定するかどうか
    )
  )
  .toExcel(templatefilepath, outputDir, outputfilename, SAMPLE, SAMPLECHILDAry);
  • セル修飾は親子関係の子の部分に適用できます。具体的にはセルの上/下/左/右のボーダー(罫線)の有無と背景色を指定できます。
  • ChildRecordMultiRowMapクラスのコンストラクタの引数が追加されています。「ステップ」は複数行を一つのまとまりとみなす場合に2以上の値を指定します。例えば2行で1データを表現する場合は "2" と指定します。
  • 最後の引数は偶数行のみ背景色を指定するかどうかを指定します。trueとすると背景色がなし/ありで交互に設定されるようになります。

Excelファイルからの読み込み

toExcelメソッドに代わって、fromExcelメソッドを使うことでExcelファイルのセルにある値を読み込んでストアモデルに値をセットすることができます。