金子邦彦研究室プログラミングJavaServer Faces の sort table タグJavaServer Faces の sort table タグ

JavaServer Faces の sort table タグ

JavaServer Faces の sort table タグを使うことで、データを簡単にソートできる。 これは、データを、テーブル形式で表示するとともに、Web ブラウザ上で、ユーザが簡単にソートできるというものです。 これを実現するためには、Apache MyFaces のタグを使うとともに、Java プログラムの方で、ソートを実行するためのプログラムを準備する必要がある。

このページでは、データを簡単にソートできることのメリットを示したいので、わりと本格的なサンプルプログラムを載せています。 ソート以外にも下記の機能を持たせています。

準備事項

poi のインストールについて。 poi が必要なので、http://poi.apache.org/index.html から入手して下さい 解凍してください。 その後、Eclipse のプロジェクト の WEN-INF/lib の下に jar ファイルを置いてください。 同時に、Eclipse のプロジェクトを右クリックしして、「外部 JAR の追加」を行ってください。

Java Server Faces サンプルプログラム の手順を終えていること。 この Web ページで説明している. Eclipse の プロジェクトとパッケージを使うとともに、web.xml, faces-config.xml, index.jsp を使う。

要件と仕様の概要

呼び出し画面の画面イメージ

[image]
図.呼び出し画面

集計分析画面の画面イメージ


[image]
[image]
図.集計分析画面

画面と画面繊維

  1. 呼び出し画面

    集計分析画面で表示するレポート・データの条件(レポート番号の範囲)と、表示される属性の指定などを行う。

    下記の遷移がある。

  2. 集計分析画面

    行単位や列単位で「チェック」を行ったり、チェックした行や列の表示、非表示などを行ったり、 強調表示すべきキーワードの指定を行ったり、 ピボットテーブルの確認を行う。

    下記の遷移がある。

実装の方針

使用上の注意

実際の使用では、商品Dso, 商品Dao を使わずに、別の「ほにゃららDso」や「ほにゃららDao」を使うことになると思います。

  1. ほにゃららDso.java

    商品Dso.java を参考にして実装。 メソッドとして、コンストラクタ、get属性名リスト, ListDataModelに変換の 3つが必要(これらは、商品Dso.java のものが参考になる)。

  2. ほにゃららDao.java

    商品Dao.java を参考にして実装。 メソッドとして、呼び出し、呼び出し後置換の 2つが必要(これらは、商品Dao.java のものが参考になる)。

    特記事項: 「レポート番号の範囲で絞り込む」という処理、ほにゃららDao の「呼び出し」メソッドに実装されることになる。 しかし、商品Dso.java では、「レポート番号の範囲で絞り込む」処理は実装していない。 これは、商品Dso の動作確認が簡単にできるようにするためである(実装は簡単だが、実際には、データベース管理システムと連携して、SpringJDBC などで接続することになる)。

  3. 表示テーブル本体.java

    表示テーブル本体のメソッドのうち、呼び出し、再度の呼び出しの 2つについて、 「ほにゃららDso」に応じて書き換える。

  4. 表示テーブルヘッダ.java

    表示テーブルヘッダのコンストラクタを、 「ほにゃららDso」に応じて書き換える。

ソースコード

ExcelHandler.java


package hoge.hoge.com;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;

// poi が必要なので、http://poi.apache.org/index.html から入手して下さい
// 解凍してください。
// その後、WEN-INF/lib の下に jar ファイルを置いてください。
// 同時に、CLASSPATHを設定(解凍されて jar ファイルができたディレクトリ)するか、Eclipse のプロジェクトを右クリックしして、「外部 JAR の追加」を行ってください。

import org.apache.poi.hssf.usermodel.*;

public class ExcelHandler {
    String fileName;
    File excelFile;
    FileInputStream inStream;
    HSSFWorkbook excelBook;
    int numOfSheets;
    String [] sheetsName;
    HSSFSheet [] sheets;

    /* コンストラクタでは,ファイル名をセット */
    public ExcelHandler( String f ) {
        fileName = f;
    }
    
    public HSSFCellStyle createCellStyle() {
        if ( this.excelBook != null ) {
            return this.excelBook.createCellStyle();
        }
        else {
            return null;
        }
    }
    
    public HSSFSheet getSheetAt( int i ) {
        return this.sheets[i];
    }
    
    /*
     * 既存のエクセルファイルのオープン.ファイル名は,コンストラクタ呼び出しにおいてセットしておくこと
     */
    public void fileopen()
    {
        try {
            excelFile = new File(fileName);
            inStream = new FileInputStream(excelFile);
            excelBook = new HSSFWorkbook(inStream);
            numOfSheets = excelBook.getNumberOfSheets();
           
            sheetsName = new String[numOfSheets];
            for (int i = 0; i < numOfSheets; i++) {
                sheetsName[i] = excelBook.getSheetName(i);
            }
            sheets = new HSSFSheet[numOfSheets];
            for (int i = 0; i < numOfSheets; i++) {
                sheets[i] = excelBook.getSheetAt(i);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void fileclose()
    {
        try {
            /* 書き込み結果のフラッシュ */
            FileOutputStream out = new FileOutputStream( excelFile );
            excelBook.write( out );
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }        
       
        /* instream のクローズ */
        if (inStream != null) {
            try {
                excelBook = null;
                numOfSheets = 0;
                inStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }        
    }
    /*
     * 新規エクセルファイルの作成.ファイル名は,コンストラクタ呼び出しにおいてセットしておくこと
     * シート数は1.シート名は,パラメータで設定.
     */
    public void createExcelWorkbook( int numOfSheets, String [] sheetName )
    {
        try {    
            /* エクセルワークブックの初期化 */
            HSSFWorkbook workBook = new HSSFWorkbook();
            /* ワークシートの作成 */
            for ( int i = 0; i < numOfSheets; i++ ) {
                HSSFSheet newSheet = workBook.createSheet();
                    workBook.setSheetName(i, sheetName[i], HSSFWorkbook.ENCODING_UTF_16);
                /* 左上のセルオブジェクトを作っておく */
                HSSFRow newRow = newSheet.createRow(0);
                newRow.createCell((short)0);
            }
       
            /* 書き出し */
            FileOutputStream out = new FileOutputStream( new File( fileName ) );
            workBook.write( out );
            out.close();

            fileopen();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /* HSSFCell オブジェクトの取得.
     * すでに fileopen() を実行しておくこと.
     * 範囲外のときは,HSSFCell オブジェクトの生成を試みる..
     */
    public HSSFCell getcell(short sheetNum, short x, int y)
    {
        if ( sheetNum >= numOfSheets )
            return null;
        if ( y > sheets[sheetNum].getLastRowNum() ) {
            for( int i = sheets[sheetNum].getLastRowNum() + 1; i <= y; i++ ) {
                sheets[sheetNum].createRow(i);
            }
        }
        HSSFRow row = sheets[sheetNum].getRow(y);
        if ( row == null )
            return null;
        if ( x >= row.getLastCellNum() ) {
            for( int i = row.getLastCellNum() + 1; i <= x; i++ ) {
                row.createCell((short)i);
            }            
        }
        HSSFCell cell = row.getCell(x);
        if ( cell == null ) {
            row.createCell(x);
            if ( cell == null )
                return null;
        }
        return cell;
    }
    /*
     * HSSFCell の値を System.out.print で表示
     */
    public void dispcell( HSSFCell cell )
    {
        if ( cell == null )
            return;
        int type = cell.getCellType();
        switch (type) {
        case HSSFCell.CELL_TYPE_BLANK :
            System.out.print("");   break;
        case HSSFCell.CELL_TYPE_BOOLEAN :
            System.out.print(cell.getBooleanCellValue());  break;
        case HSSFCell.CELL_TYPE_ERROR :
            System.out.print("ERROR");  break;
        case HSSFCell.CELL_TYPE_NUMERIC :
            System.out.print((int) cell.getNumericCellValue());  break;
        case HSSFCell.CELL_TYPE_STRING :
            System.out.print(cell.getStringCellValue());   break;
        case HSSFCell.CELL_TYPE_FORMULA :
            System.out.print(cell.getCellFormula());  break;
        default :
            System.out.print("");  break;
        }
    }
    /*
     * dispcell() を繰り返し実行して,全体を表示.
     */
    public void dispinfo() {
        try {
            for (short i = 0; i < numOfSheets; i++) {
                System.out.println("【" + sheetsName[i] + "】");
        
                for (int j = 0; j <= sheets[i].getLastRowNum(); j++) {
                    HSSFRow row = sheets[i].getRow(j);
                    if (row == null)
                        continue;
                    for (short k = 0; k < row.getLastCellNum(); k++) {
                        HSSFCell cell = getcell(i,k,j);
                        dispcell(cell);
                        System.out.print(" | ");
                    }
                    System.out.println("\n------------------" +
                                    "----------------------------------------");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
   
    void setBooleanCellValue( short sheetNum, short x, int y, boolean val ) {
        HSSFCell cell = getcell( sheetNum, x, y );
        if ( cell == null ) {
            return;
        }
        cell.setCellType( HSSFCell.CELL_TYPE_BOOLEAN );
        cell.setCellValue( val );
        return;
    }
    void setNumericCellValue( short sheetNum, short x, int y, double val ) {
        HSSFCell cell = getcell( sheetNum, x, y );
        if ( cell == null ) {
            return;
        }
        cell.setCellType( HSSFCell.CELL_TYPE_NUMERIC );
        cell.setCellValue( val );
        return;
    }
    void setStringCellValue( short sheetNum, short x, int y, String val ) {
        HSSFCell cell = getcell( sheetNum, x, y );
        if ( cell == null ) {
            return;
        }
        cell.setCellType( HSSFCell.CELL_TYPE_STRING );
        cell.setEncoding(HSSFCell.ENCODING_UTF_16);
        cell.setCellValue( val );
        return;
    }
    void setCalendarCellValue( short sheetNum, short x, int y, Calendar val ) {
        HSSFCell cell = getcell( sheetNum, x, y );
        if ( cell == null ) {
            return;
        }
        cell.setCellType( HSSFCell.CELL_TYPE_NUMERIC );
        cell.setCellValue( val );
        return;
    }
    void setDateCellValue( short sheetNum, short x, int y, Date val ) {
        HSSFCell cell = getcell( sheetNum, x, y );
        if ( cell == null ) {
            return;
        }
        cell.setCellType( HSSFCell.CELL_TYPE_NUMERIC );
        cell.setCellValue( val );
        return;
    }
    void setShortCellValue( short sheetNum, short x, int y, short val ) {
        HSSFCell cell = getcell( sheetNum, x, y );
        if ( cell == null ) {
            return;
        }
        cell.setCellType( HSSFCell.CELL_TYPE_NUMERIC );
        cell.setCellValue( val );
        return;
    }
    void setFormulaCellValue( short sheetNum, short x, int y, String val ) {
        HSSFCell cell = getcell( sheetNum, x, y );
        if ( cell == null ) {
            return;
        }
        cell.setCellType( HSSFCell.CELL_TYPE_FORMULA );
        cell.setCellFormula( val );
        return;
    }

}

OpenDataList.java


/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package hoge.hoge.com;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.TreeSet;

import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import javax.faces.component.UIComponent;
import javax.faces.component.UIData;
import javax.faces.component.html.HtmlDataTable;
import javax.faces.event.ActionEvent;

import org.apache.jasper.tagplugins.jstl.core.Set;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFSheet;

//poi が必要なので、http://poi.apache.org/index.html から入手して下さい
import hoge.hoge.com.ExcelHandler;

public class OpenDataList extends SortableList
{

    private String getSort_when_sort = null;
    private boolean isAscending_when_sort = false;
    private 表示テーブルヘッダ header;
    private 表示テーブル本体 body;
    private String 表示ピボットテーブル;
    private static final int SORT_ASCENDING = 1;
    private static final int SORT_DESCENDING = -1;

    public OpenDataList()
    {
        super(null);
        // 表示テーブルヘッダは、オブジェクトの生成時に中身を初期化 (表示テーブルヘッダのコンストラクタで、初期化の処理を行う)
        header = new 表示テーブルヘッダ();
        // 表示テーブル本体は、オブジェクト生成時は、まだ、中身は空。
        body = new 表示テーブル本体();
    }

    //==========================================================================
    // ゲッター
    //==========================================================================
    public DataModel getData()
    {
        if ( this.getSort_when_sort != null ) {
            if ( getSort_when_sort.equals(getSort()) && isAscending_when_sort == isAscending() ) {
                // ソート条件が同じなので、ソートしなおす必要がない
                return this.body.get情報();
            }
        }
       
        this.getSort_when_sort = getSort();
        this.isAscending_when_sort = isAscending();
        sort(getSort(), isAscending());
        return this.body.get情報();
    }

    void setData(DataModel datamodel)
    {
        System.out.println("preserved datamodel updated");
        // just here to see if the datamodel is updated if preservedatamodel=true
    }

    public DataModel get表示テーブルヘッダ()
    {
        return header.get情報();
    }

    public String get表示ピボットテーブル() {
        if ( this.表示ピボットテーブル != null ) {
            return 表示ピボットテーブル;
        }
        else {
            // 仕方が無いので、空文字を返す
            return "";
        }
    }

    //==========================================================================
    // メソッド
    //==========================================================================
    void 呼び出し( int 開始レポート番号, int 終了レポート番号 ) {
        // 指定された範囲のレポート呼び出しを行う
        // この結果、前回の呼び出し結果は消えます。
        this.body.呼び出し( 開始レポート番号, 終了レポート番号 );
    }
    
    void 再度の呼び出し( int 開始レポート番号, int 終了レポート番号, String キーワード, String 追加キーワード )
    // 行チェックマップ、行表示マップの初期化はしない
    {
        // 指定された範囲のレポートの再度の呼び出しを行う
        // この結果、前回の呼び出し結果は消えます。
        this.body.再度の呼び出し( 開始レポート番号, 終了レポート番号, キーワード, 追加キーワード );
    }
    
    void エクスポート( String ファイル名, String ワークシート名, int 開始レポート番号, int 終了レポート番号 ) {
        // Excel ファイルに書き出す
        // ファイル名は、「"c:\\a.xls"」のように記述してください
        ExcelHandler handler = new ExcelHandler( ファイル名 );
        
        /*
         * 新規エクセルファイルの作成 (すでにファイルが存在すれば上書き)
         */
        handler = new ExcelHandler( ファイル名 );
        System.out.println(ファイル名);
        String [] names = new String[1];
        names[0] = ワークシート名;
        handler.createExcelWorkbook( /* numOfSheets */ 1, /* sheetName */ names );
        
        // Excelの先頭部分
           Calendar c = Calendar.getInstance( new Locale( "ja" ) );
        handler.setStringCellValue( /* 最初のワークシート番号は 0 番 */ (short)0,
                (short)0, 0, "作成日: " + c.get( Calendar.YEAR ) + "年 "
                                        + c.get( Calendar.MONTH ) + "月 "
                                        + c.get( Calendar.DAY_OF_MONTH ) + "日 " );
        handler.setStringCellValue( /* 最初のワークシート番号は 0 番 */ (short)0,
                (short)0, 1, "インシデントレポート 集計分析結果");
        handler.setStringCellValue( /* 最初のワークシート番号は 0 番 */ (short)0,
                (short)0, 2, "開始レポート番号: " + 開始レポート番号);
        handler.setStringCellValue( /* 最初のワークシート番号は 0 番 */ (short)0,
                (short)0, 3, "終了レポート番号: " + 終了レポート番号);
           
        // スタイルオブジェクト
        HSSFCellStyle style = handler.createCellStyle();
        // 罫線の指定
        style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        style.setBorderRight(HSSFCellStyle.BORDER_THIN);
        style.setBorderTop(HSSFCellStyle.BORDER_THIN);
        // 回り込み表示の指定
        style.setWrapText( true );
       
        // 幅の指定 (データの中身に応じて、幅を自動調整する)
        final int FACTOR = 650; // 1文字あたりの幅
        HSSFSheet sheet = handler.getSheetAt(0);
        for(short i=0; i<(this.header.getユーザ属性数() + 1);i++) {
            if ( ( i > 0 ) && ( this.header.is非表示(i) ) ) {
                // 非表示なので、幅0に設定しておく
                sheet.setColumnWidth( /* column */ i, /* width */ (short)0 );
            }
            else {
                int maxLength = this.body.maxLength(i);
                if ( maxLength > ( ( ( ( 32767 / FACTOR ) - 1 ) * 4 ) ) ) {
                    // 最大に長くする
                    sheet.setColumnWidth( /* column */ i, /* width */ (short)32767 );
                }
                else if ( maxLength > 20 ) {
                    // 4行で表示できるくらい
                    sheet.setColumnWidth( /* column */ i, /* width */ (short)(maxLength * FACTOR / 4) );
                }
                else if ( maxLength < 4 ) {
                    // あまり狭くしすぎない
                    sheet.setColumnWidth( /* column */ i, /* width */ (short)(4 * FACTOR) );
                }
                else {
                    sheet.setColumnWidth( /* column */ i, /* width */ (short)(maxLength * FACTOR) );
                }
            }
        }
        
        // 表示ラベルの指定
        for(short i=0; i<(this.header.getユーザ属性数() + 1);i++) {
            handler.setStringCellValue( /* 最初のワークシート番号は 0 番 */ (short)0,
                    i, /* 行番号 */ (short)4, this.header.get表示ラベル(i) );
            // スタイルの指定
            HSSFCell cell = handler.getcell( (short)0, i, (short)4 );
            cell.setCellStyle(style);
        }
        
        // 本体の出力
        List<List<Object>> items = this.body.getWrappedData();
        // 「= 5」で、行は5つ下にずらす
        short 行番号 = 5;
        for(int i=0;i < items.size();i++) {
            ArrayList<Object> tuple = (ArrayList<Object>)items.get(i);
            if ( tuple == null ) {
                // error
                return;
            }
            if ( this.body.is任意の行の行表示( i ) ) {
                for(short j=0; j<tuple.size(); j++) {
                    // データ書き込み

                    handler.setStringCellValue( /* 最初のワークシート番号は 0 番 */ (short)0,
                            j, (short)行番号, tuple.get(j).toString());
                    // スタイルの指定
                    HSSFCell cell = handler.getcell( (short)0, j, (short)行番号 );
                    cell.setCellStyle(style);
                }
                行番号++;
            }
        }
        

        /* クローズ */
        handler.fileclose();
        
        return;
    }
       
    void ピボットテーブルの生成( String ピボットテーブル行の属性, String ピボットテーブル列の属性 ) {
        if ( ( ピボットテーブル行の属性 == null ) || ( ピボットテーブル列の属性 == null ) ) {
            // 何もしない
            return;
        }
        int num1 = this.header.get列番号by表示ラベル(ピボットテーブル行の属性);
        int num2 = this.header.get列番号by表示ラベル(ピボットテーブル列の属性);
        if ( ( num1 >= 0 ) && ( num2 >= 0 ) ) {
            this.ピボットテーブルの生成( num1, num2 );
        }
    }
    void ピボットテーブルの生成( int ピボットテーブル行属性にすべき列番号, int ピボットテーブル列属性にすべき列番号 ) {
        // 本体データの取得
        List<List<Object>> items = this.body.getWrappedData();
        
        // 各属性のドメインを求める
        TreeSet<String> ピボットテーブル行属性ドメイン = new TreeSet<String>();
        TreeSet<String> ピボットテーブル列属性ドメイン = new TreeSet<String>();
        
        for(int i=0;i < items.size();i++) {
            ArrayList<Object> tuple = (ArrayList<Object>)items.get(i);
            if ( tuple == null ) {
                // error
                return;
            }

            ピボットテーブル行属性ドメイン.add( tuple.get( ピボットテーブル行属性にすべき列番号 ).toString() );
            ピボットテーブル列属性ドメイン.add( tuple.get( ピボットテーブル列属性にすべき列番号 ).toString() );
        }
        
        // 各属性のドメインから、「文字列」と「番号(0から始まる)」の対応表を作る。
        // 同時に、「表示テーブル」のヘッダを埋める。
        HashMap<String, Integer> ピボットテーブル行属性マップ = new HashMap<String, Integer>();
        HashMap<String, Integer> ピボットテーブル列属性マップ = new HashMap<String, Integer>();
        int num = 1; // 1から始める。0行目、0列目は空けておきたい
        for( Iterator<String> it1 = ピボットテーブル行属性ドメイン.iterator(); it1.hasNext(); ) {
            String s = it1.next();
            ピボットテーブル行属性マップ.put( s, num );
            num++;
        }
        num = 1; // 1から始める。0行目、0列目は空けておきたい
        for( Iterator<String> it2 = ピボットテーブル列属性ドメイン.iterator(); it2.hasNext(); ) {
            String s = it2.next();
            ピボットテーブル列属性マップ.put( s, num );
            num++;
        }
        
        // 本体データを、2次元配列に格納. 0行目、0列目はヘッダが入る。
        int[][] pivottable = new int[ピボットテーブル行属性ドメイン.size() + 1][ピボットテーブル列属性ドメイン.size() + 1];
        
        for(int i=0;i < items.size();i++) {
            ArrayList<Object> tuple = (ArrayList<Object>)items.get(i);
            if ( tuple == null ) {
                // error
                return;
            }
            
            pivottable[ピボットテーブル行属性マップ.get(tuple.get( ピボットテーブル行属性にすべき列番号 ).toString())]
                      [ピボットテーブル列属性マップ.get(tuple.get( ピボットテーブル列属性にすべき列番号 ).toString())]++;
        }
        
        //
        // データを、表示テーブルに転記
        //
        // 1行目
        this.表示ピボットテーブル = new String();
        this.表示ピボットテーブル = this.表示ピボットテーブル.concat("<table border=\"1\"><tr><td>");
        for( Iterator<String> it2 = ピボットテーブル列属性ドメイン.iterator(); it2.hasNext(); ) {
            String s = it2.next();
            this.表示ピボットテーブル = this.表示ピボットテーブル.concat( "</td><td>").concat( s );
        }
        this.表示ピボットテーブル =  this.表示ピボットテーブル.concat( "</td></tr>" );
        // 2行目以降
        int i = 1;
        for( Iterator<String> it1 = ピボットテーブル行属性ドメイン.iterator(); it1.hasNext(); ) {
            String s = it1.next();
            this.表示ピボットテーブル = this.表示ピボットテーブル.concat("<tr>").concat("<td>").concat( s );
            for( int j = 1; j < ピボットテーブル列属性ドメイン.size() + 1; j++ ) {
                this.表示ピボットテーブル = this.表示ピボットテーブル.concat( "</td><td>").concat( String.valueOf( /* int */ pivottable[i][j] ) );
            }
            this.表示ピボットテーブル = this.表示ピボットテーブル.concat( "</td></tr>" );
            i++;
        }
        this.表示ピボットテーブル = this.表示ピボットテーブル.concat("</table>");

            System.out.println( this.表示ピボットテーブル );
    }
    
    
    void 非表示一括実行( List<String> 表示属性名リスト ) {
        // 表示しない属性については、ヘッダ内にある「列チェック」と「非表示」をまとめてチェックする
        this.header.非表示一括実行( 表示属性名リスト );
    }
    
    void チェックした列は表示しない() {
        this.header.チェックした列は表示しない();
    }
    
    void 全ての列を表示() {
        this.header.全ての列を表示();
    }    
    
    void チェックした行は表示しない() {
        this.body.チェックした行は表示しない();
    }
    
    void チェックした行のみを表示する() {
        this.body.チェックした行のみを表示する();
    }
    
    void 全ての行を表示() {
        this.body.全ての行を表示();
    }    
    
    public void set任意の列の表示幅( int 列番号, int 表示幅 ) {
        this.header.set表示幅( 列番号, 表示幅 );
    }
    
    public int get任意の列の表示幅( int 列番号 ) {
        return this.header.get表示幅( 列番号 );
    }
    
    public boolean is任意の列の非表示( int 列番号 )
    {
        this.header.is非表示( 列番号 );
        return this.header.is非表示(列番号);
    }
   
    public boolean is行表示() {
        return this.body.is行表示();
    }
   
    public int getユーザ属性数() {
        return this.header.getユーザ属性数();
    }
    
    public int maxLength( int 列番号 ) {
        // 指定された列番号の全データについて、データを文字列表現に変換した時の最大長
        return this.body.maxLength( 列番号 );
    }
    
    public ArrayList<SelectItem> get属性アイテムリスト() {
        return this.header.get属性アイテムリスト();
    }
   
    public ArrayList<String> get属性名リスト() {
        return this.header.get属性名リスト();
    }
   
    public int getRowIndex()
    // エラー時には -1 を返す。成功時には、0 以上の整数を返す
    {
        if ( this.header.get情報().isRowAvailable() ) {
            return this.header.get情報().getRowIndex();
        }
        else {
            // error
            return -1;
        }
    }
   
    public 表示テーブルヘッダ属性項目 getRowData()
    // エラー時には null を返す。成功時には、表示テーブルヘッダ属性項目オブジェクトを返す
    {
        if ( this.header.get情報().isRowAvailable() ) {
            return (表示テーブルヘッダ属性項目) this.header.get情報().getRowData();
        }
        else {
            // error
            return null;
        }
    }
   
    private int getColumnIndex(final String columnName)
    {
        int columnIndex = -1;
        List headers = (List) this.header.get情報().getWrappedData();
        for (int i=0;i<headers.size() && columnIndex==-1;i++)
        {
            表示テーブルヘッダ属性項目 header = (表示テーブルヘッダ属性項目) headers.get(i);
            if (header.get表示ラベル().equals(columnName))
            {
                columnIndex = i;
            }
        }
        return columnIndex;
    }
   
    public String get表示幅()
    {
        表示テーブルヘッダ属性項目 item = this.getRowData();
        if ( item != null ) {
            return item.get表示幅();
        }
        else {
            return null;
        }
    }

    public boolean is入力テキストで表示()
    // error 時には false を返す
    {
        表示テーブルヘッダ属性項目 item = this.getRowData();
        if ( item != null ) {
            return this.is行表示() && item.is入力テキストで表示();
        }
        else {
            return false;
        }
    }

    public boolean is出力テキストで表示()
    // error 時には false を返す
    {
        表示テーブルヘッダ属性項目 item = this.getRowData();
        if ( item != null ) {
            return this.is行表示() && item.is出力テキストで表示();
        }
        else {
            return false;
        }
    }
   
    public String get行チェック表示ラベル() {
        return this.body.get行チェック表示ラベル();
    }
   
    public String get行チェック背景色() {
        return this.body.get行チェック背景色();
    }
   
    public Integer getId() {
        return this.body.getId();
    }
   
    public void toggle列チェック() {
        表示テーブルヘッダ属性項目 item = this.getRowData();
        // 管理属性である id の「列チェック」は toggle できない、ということにする
        if ( this.getRowIndex() == 0 ) {
            return;
        }
           else if ( item != null ) {
               item.toggle列チェック済み();
           }
    }
    
    public void toggle行チェック() {
        this.body.toggle行チェック();
    }
    
       public Object getColumnValue()
    {
           // JSF から呼び出されるメソッド(値の取得のため)
        return this.body.getColumnValue( this.getRowIndex() );
    }

    public void setColumnValue(Object value)
    {
        this.body.setColumnValue( this.getRowIndex(), value );
        return;
    }
   
    //==========================================================================
    // Protected Methods
    //==========================================================================

    protected boolean isDefaultAscending(String sortColumn)
    {
        return true;
    }

    protected void sort(final String column, final boolean ascending)
    {
        if (column != null)
        {
            int columnIndex = getColumnIndex(column);
            int direction = (ascending) ? SORT_ASCENDING : SORT_DESCENDING;
            sort(columnIndex, direction);
        }
    }

    protected void sort(final int columnIndex, final int direction)
    {
        Comparator comparator = new Comparator()
        {
            public int compare(Object o1, Object o2)
            {
                int result = 0;
                Object column1 = ((List)o1).get(columnIndex);
                Object column2 = ((List)o2).get(columnIndex);
                if (column1 == null && column2 != null)
                    result = -1;
                else if (column1 == null && column2 == null)
                    result = 0;
                else if (column1 != null && column2 == null)
                    result = 1;
                else
                    result = ((Comparable)column1).compareTo(column2) * direction;
                return result;
            }
        };
        Collections.sort((List)this.body.get情報().getWrappedData(), comparator);
    }
}

SortableList.java


/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package hoge.hoge.com;

/**
 * Convenient base class for sortable lists.
 * @author Thomas Spiegl (latest modification by $Author: grantsmith $)
 * @version $Revision: 472610 $ $Date: 2006-11-08 20:46:34 +0100 (Wed, 08 Nov 2006) $
 */
public abstract class SortableList
{
    private String _sort;
    private boolean _ascending;

    protected SortableList(String defaultSortColumn)
    {
        _sort = defaultSortColumn;
        _ascending = isDefaultAscending(defaultSortColumn);
    }

    /**
     * Sort the list.
     */
    protected abstract void sort(String column, boolean ascending);

    /**
     * Is the default sort direction for the given column "ascending" ?
     */
    protected abstract boolean isDefaultAscending(String sortColumn);


    public void sort(String sortColumn)
    {
        if (sortColumn == null)
        {
            throw new IllegalArgumentException("Argument sortColumn must not be null.");
        }

        if (_sort.equals(sortColumn))
        {
            //current sort equals new sortColumn -> reverse sort order
            _ascending = !_ascending;
        }
        else
        {
            //sort new column in default direction
            _sort = sortColumn;
            _ascending = isDefaultAscending(_sort);
        }

        sort(_sort, _ascending);
    }

    public String getSort()
    {
        return _sort;
    }

    public void setSort(String sort)
    {
        _sort = sort;
    }

    public boolean isAscending()
    {
        return _ascending;
    }

    public void setAscending(boolean ascending)
    {
        _ascending = ascending;
    }
}

アクション.java


package hoge.hoge.com;

import java.util.List;

import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

public class アクション {
    private 呼び出し画面フォーム lookupForm;
    private 集計分析画面フォーム analyzeForm;
    private OpenDataList openDataList;
    private 表示テーブルビジネスロジック tableLogic;
    
    // 以下のうち,セッターはJSFが呼び出す.
    // つまり、オブジェクトが自動的に生成される
    public 呼び出し画面フォーム getLookupForm() {
        return lookupForm;
    }

    public void setLookupForm(呼び出し画面フォーム lookupForm) {
        this.lookupForm = lookupForm;
    }
    
    public 集計分析画面フォーム getAnalyzeForm() {
        return analyzeForm;
    }

    public void setAnalyzeForm(集計分析画面フォーム analyzeForm) {
        this.analyzeForm = analyzeForm;
    }

    public OpenDataList getOpenDataList() {
        return openDataList;
    }

    public void setOpenDataList(OpenDataList openDataList) {
        this.openDataList = openDataList;
    }
    
    public 表示テーブルビジネスロジック getTableLogic() {
        return tableLogic;
    }

    public void setTableLogic(表示テーブルビジネスロジック tableLogic) {
        this.tableLogic = tableLogic;
    }

    //
    // アクション・コントロール・メソッド
    //
    
    //
    // lookup呼び出し画面
    //
    
    public String この条件で呼び出し() {
        // JFS で HttpServletRequest, HttpSession を取得 (決まり文句)
        ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
        HttpServletRequest request = (HttpServletRequest)context.getRequest();
        HttpSession session = request.getSession();
       
        try {
            Integer 開始レポート番号 = Integer.valueOf( this.lookupForm.get開始レポート番号_必須() );
            Integer 終了レポート番号 = Integer.valueOf( this.lookupForm.get終了レポート番号_必須() );
            List<String> 表示属性名リスト = this.lookupForm.get表示属性名リスト();
            String ソート属性と順序 = this.lookupForm.getソート属性と順序();
            
            // 実際の処理は、ビジネスロジックに委ねる
            tableLogic.この条件で呼び出す( openDataList, /* 表示方法 */ "横は1画面に収める", 開始レポート番号, 終了レポート番号, 表示属性名リスト, ソート属性と順序 );
        }
        catch (NumberFormatException e) {
            // 失敗
            return "lookup";    
        }
           
        // 成功
        return "analyze";
    }

    public String 全ての属性にチェック() {
        // JFS で HttpServletRequest, HttpSession を取得 (決まり文句)
        ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
        HttpServletRequest request = (HttpServletRequest)context.getRequest();
        HttpSession session = request.getSession();
       
        // フォームの書き換え
        lookupForm.set表示属性名リスト( openDataList.get属性名リスト() );

        // いつも成功(画面遷移は1通り)
        return "lookup";
    }
    
    public String 集計分析画面に戻る() {
        // JFS で HttpServletRequest, HttpSession を取得 (決まり文句)
        ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
        HttpServletRequest request = (HttpServletRequest)context.getRequest();
        HttpSession session = request.getSession();
       
        // 何もせず、画面遷移するだけ

        // いつも成功(画面遷移は1通り)
        return "analyze";
    }
    
    //
    // analyze集計分析画面
    //
    public String この条件で再表示() {
        // JFS で HttpServletRequest, HttpSession を取得 (決まり文句)
        ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
        HttpServletRequest request = (HttpServletRequest)context.getRequest();
        HttpSession session = request.getSession();
       
        if (     ( this.lookupForm.get開始レポート番号_必須() == null ) ||
                ( this.lookupForm.get終了レポート番号_必須() == null ) ) {
            // null になることはありえない. エラー
            return "analyze";
        }
       
        // 実際の処理は、ビジネスロジックに委ねる
        Integer 開始レポート番号 = Integer.valueOf( this.lookupForm.get開始レポート番号_必須() );
        Integer 終了レポート番号 = Integer.valueOf( this.lookupForm.get終了レポート番号_必須() );
        tableLogic.この条件で再表示( openDataList,
                this.analyzeForm.get行操作(),
                this.analyzeForm.get列操作(),
                this.analyzeForm.getキーワード(),
                this.analyzeForm.get追加キーワード(),
                this.analyzeForm.get表示方法(),
                開始レポート番号, 終了レポート番号 );
       
           // 特記事項: 再表示により、集計分析画面フォームの「行操作」、「列操作」はクリアされる
        this.analyzeForm.set列操作( null );
        this.analyzeForm.set行操作( null );
       
        // いつも成功(画面遷移は1通り)
        return "analyze";
    }
    
    public String 呼び出し画面に戻る() {
        // JFS で HttpServletRequest, HttpSession を取得 (決まり文句)
        ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
        HttpServletRequest request = (HttpServletRequest)context.getRequest();
        HttpSession session = request.getSession();
       
        // 何もせず、画面遷移するだけ

        // いつも成功(画面遷移は1通り)
        return "lookup";
    }
    
    public String エクスポート() {
        // JFS で HttpServletRequest, HttpSession を取得 (決まり文句)
        ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
        HttpServletRequest request = (HttpServletRequest)context.getRequest();
        HttpSession session = request.getSession();

        if (     ( this.lookupForm.get開始レポート番号_必須() == null ) ||
                ( this.lookupForm.get終了レポート番号_必須() == null ) ) {
            // null になることはありえない. エラー
            return "analyze";
        }
       
        Integer 開始レポート番号 = Integer.valueOf( this.lookupForm.get開始レポート番号_必須() );
        Integer 終了レポート番号 = Integer.valueOf( this.lookupForm.get終了レポート番号_必須() );
        
        // 実際の処理は、ビジネスロジックに委ねる
        tableLogic.エクスポート( openDataList, 開始レポート番号, 終了レポート番号 );

        // いつも成功(画面遷移は1通り)
        return "analyze";
    }
    
    
    public String ピボットテーブルを表示() {
        // JFS で HttpServletRequest, HttpSession を取得 (決まり文句)
        ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
        HttpServletRequest request = (HttpServletRequest)context.getRequest();
        HttpSession session = request.getSession();
        
        // 実際の処理は、ビジネスロジックに委ねる
        tableLogic.ピボットテーブルを表示( openDataList, this.analyzeForm.getピボットテーブル行の属性(), this.analyzeForm.getピボットテーブル列の属性() );

        // いつも成功(画面遷移は1通り)
        return "analyze";
    }
    
    public String 列チェック() {
        // JFS で HttpServletRequest, HttpSession を取得 (決まり文句)
        ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
        HttpServletRequest request = (HttpServletRequest)context.getRequest();
        HttpSession session = request.getSession();
       
        // 実際の処理は、ビジネスロジックに委ねる
        tableLogic.toggle列チェック( openDataList );

        // いつも成功(画面遷移は1通り)
        return "analyze";
    }
    
    public String 行チェック() {
        // JFS で HttpServletRequest, HttpSession を取得 (決まり文句)
        ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
        HttpServletRequest request = (HttpServletRequest)context.getRequest();
        HttpSession session = request.getSession();
       
        // 実際の処理は、ビジネスロジックに委ねる
        tableLogic.toggle行チェック( openDataList );

        // いつも成功(画面遷移は1通り)
        return "analyze";
    }
}

呼び出し画面フォーム.java


package hoge.hoge.com;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

// アクションフォーム・クラス
//   入力フォームデータの格納を行うとともに、アクション・コントロール・メソッドも持つ
public class 呼び出し画面フォーム {

    private String 開始レポート番号_必須 = null;
    private String 終了レポート番号_必須 = null;
    private List<String> 表示属性名リスト = null;
    private String ソート属性と順序 = "レポート番号・昇順(古いものを上に)";
    // JSP 内の「<h:inputHidden value="index" binding="#{lookupForm.hiddenInput}"/>」でバインディング
    public javax.faces.component.html.HtmlInputHidden hiddenInput = null;

    // メソッド
   
    //呼び出し画面フォーム() {
        // デフォルト値を設定するために、reset を呼び出す。
        // this.reset();
    //}
   
    public void reset() {
        // デフォルト値に戻す
        this.開始レポート番号_必須 = null;
        this.終了レポート番号_必須 = null;
        this.表示属性名リスト = null;
        this.ソート属性と順序 = "レポート番号・昇順(古いものを上に)";
    }

    //
    // セッターとゲッター
    //
    
    public String get開始レポート番号_必須() {
        return 開始レポート番号_必須;
    }

    public void set開始レポート番号_必須(String 開始レポート番号_必須) {
        this.開始レポート番号_必須 = 開始レポート番号_必須;
    }
    
    public String get終了レポート番号_必須() {
        return 終了レポート番号_必須;
    }

    public void set終了レポート番号_必須(String 終了レポート番号_必須) {
        this.終了レポート番号_必須 = 終了レポート番号_必須;
    }

    public List<String> get表示属性名リスト() {
        return 表示属性名リスト;
    }

    public void set表示属性名リスト(List<String> 表示属性名リスト) {
        this.表示属性名リスト = 表示属性名リスト;
    }

    public String getソート属性と順序() {
        return ソート属性と順序;
    }

    public void setソート属性と順序(String ソート属性と順序) {
        this.ソート属性と順序 = ソート属性と順序;
    }

    public javax.faces.component.html.HtmlInputHidden getHiddenInput() {
        return hiddenInput;
    }

    public void setHiddenInput(
            javax.faces.component.html.HtmlInputHidden hiddenInput) {
        this.hiddenInput = hiddenInput;
    }
}

集計分析画面フォーム.java


package hoge.hoge.com;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

// アクションフォーム・クラス
//   入力フォームデータの格納を行うとともに、アクション・コントロール・メソッドも持つ
public class 集計分析画面フォーム {

    private String 行操作 = null;
    private String 列操作 = null;
    private String キーワード = null;
    private String 追加キーワード = null;
    private String 表示方法 = "横は1画面に収める";
    // ピボットテーブル
    private String ピボットテーブル行の属性 = null;
    private String ピボットテーブル列の属性 = null;
    // JSP 内の「<h:inputHidden value="index" binding="#{analyzeForm.hiddenInput}"/>」でバインディング
    public javax.faces.component.html.HtmlInputHidden hiddenInput = null;

    // メソッド
   
    //集計分析画面フォーム() {
        // デフォルト値を設定するために、reset を呼び出す。
        // this.reset();
    //}
   
    public void reset() {
        // デフォルト値に戻す
        this.行操作 = null;
        this.列操作 = null;
        this.キーワード = null;
        this.追加キーワード = null;
        this.表示方法 = "横は1画面に収める";
        this.ピボットテーブル行の属性 = null;
        this.ピボットテーブル列の属性 = null;
    }

    //
    // セッターとゲッター
    //

    public String get行操作() {
        return 行操作;
    }

    public void set行操作(String 行操作) {
        this.行操作 = 行操作;
    }

    public String get列操作() {
        return 列操作;
    }

    public void set列操作(String 列操作) {
        this.列操作 = 列操作;
    }

    public String getキーワード() {
        return キーワード;
    }

    public void setキーワード(String キーワード) {
        this.キーワード = キーワード;
    }

    public String get追加キーワード() {
        return 追加キーワード;
    }

    public void set追加キーワード(String 追加キーワード) {
        this.追加キーワード = 追加キーワード;
    }

    public String get表示方法() {
        return 表示方法;
    }

    public void set表示方法(String 表示方法) {
        this.表示方法 = 表示方法;
    }

    public String getピボットテーブル行の属性() {
        return ピボットテーブル行の属性;
    }

    public void setピボットテーブル行の属性(String ピボットテーブル行の属性) {
        this.ピボットテーブル行の属性 = ピボットテーブル行の属性;
    }

    public String getピボットテーブル列の属性() {
        return ピボットテーブル列の属性;
    }

    public void setピボットテーブル列の属性(String ピボットテーブル列の属性) {
        this.ピボットテーブル列の属性 = ピボットテーブル列の属性;
    }

    public javax.faces.component.html.HtmlInputHidden getHiddenInput() {
        return hiddenInput;
    }

    public void setHiddenInput(
            javax.faces.component.html.HtmlInputHidden hiddenInput) {
        this.hiddenInput = hiddenInput;
    }
}

商品Dao.java


package hoge.hoge.com;

import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

//使用法: 全面的に書き換え。

public class 商品Dao {
    static ArrayList<商品Dso> 呼び出し結果;
    
    static ArrayList<商品Dso> 呼出し後置換( int 開始レポート番号, int 終了レポート番号, String キーワード, String 追加キーワード ) {
        呼び出し( 開始レポート番号, 終了レポート番号 );
        
        final String キーワードtag1 = "<span style=\"font-size:large;font-weight:bold;background-color:yellow\">";
        final String キーワードtag2 = "</span>";
        final String 追加キーワードtag1 = "<span style=\"font-size:large;font-weight:bold;background-color:aqua\">";
        final String 追加キーワードtag2 = "</span>";
        
        for(int i=0;i < 呼び出し結果.size();i++) {
            商品Dso item = 呼び出し結果.get(i);
            if ( item == null ) {
                // error
                return 呼び出し結果;
            }
            
            // 「キーワード」、「追加キーワード」には、カンマで区切られた単語が入っている。それぞれの単語について置換
            // ■■■■■■■■■■■■ 「get説明」, 「set説明」とあるところは、書き変えてください ■■■■■■■■■■■■■
            // ■■■■■■■■■■■■ どの属性を処理するか、という意味です。 String として定義されている属性のみ OK ■■■■■■■■■■■■■
            String s = item.get説明(); // 「キーワード」、「追加キーワード」の置き換え結果を入れる
            if ( (!キーワード.equals("")) ) {
                StringTokenizer st = new StringTokenizer( キーワード, /* 区切り文字 */ "," );
                while (st.hasMoreTokens()) {
                    String token = st.nextToken();
                    s = s.replaceAll( token, キーワードtag1 + token + キーワードtag2 );
                    System.out.println( token );
                    System.out.println( s );
                    }
                // 「説明」属性を上書き
                item.set説明( s );
            }            

               if ( (!追加キーワード.equals("")) ) {
                StringTokenizer st = new StringTokenizer( 追加キーワード, /* 区切り文字 */ "," );
                while (st.hasMoreTokens()) {
                    String token = st.nextToken();
                    s = s.replaceAll( token, 追加キーワードtag1 + token + 追加キーワードtag2 );
                    System.out.println( token );
                    System.out.println( s );
                    }
                // 「説明」属性を上書き
                item.set説明( s );
               }
            // ■■■■■■■■■■■■ 書き換えはここまで ■■■■■■■■■
        }
        return 呼び出し結果;
    }
    
    static ArrayList<商品Dso> 呼び出し( int 開始レポート番号, int 終了レポート番号 ) {
        
        // ■■■■■■■■■■■■ 処理プログラム (今は仮の実装になっています) ■■■■■■■■■■■■■
        
        呼び出し結果 = new ArrayList<商品Dso>();
        
        呼び出し結果.add( new 商品Dso( 1001,     "りんご", "300円", false,
                "りんごは、赤くて、甘くて、おいしい果物。青森県の特産品。ビタミンたっぷり" ) );
        呼び出し結果.add( new 商品Dso( 1002,    "白菜", "180円", true,
                "鍋にあう。美味しい食べ物" ) );
        呼び出し結果.add( new 商品Dso( 1003,    "にんじん", "100円", true,
                "にんじんは、赤い野菜。健康に良い。甘味がある。新鮮なにんじんは苦味が少ないので、子供での食べることができる。固いので、星型に切ったり、ハート型に切ったりして、お弁当の楽しい飾りになる" ) );
        呼び出し結果.add( new 商品Dso( 1004,    "キャベツ", "450円", true,
                "スープにすると美味しい") );
        呼び出し結果.add( new 商品Dso( 1005,    "みかん", "130円", false,
                "冬に、こたつでみかんを食べると、なかなかやめられない" ) );
        呼び出し結果.add( new 商品Dso( 1006,    "いちご", "650円", false,
                "甘くて酸っぱい、おいしい果物。ケーキに載せることも多い" ) );

        return 呼び出し結果;
    }
}

商品Dso.java


package hoge.hoge.com;

import java.io.Serializable;
import java.util.ArrayList;

import javax.faces.model.ListDataModel;

//使用法: 全面的に書き換え。 属性名リスト、ユーザ属性数、id の部分は残すこと

// Dso は 「Serializable」である必要がある(DataTable での表示等のため)
public class 商品Dso implements Serializable {
    private static final long serialVersionUID = 1L;
    private static ArrayList<String> 属性名リスト = null; // 属性名リスト
    private static int ユーザ属性数 = 0; // 属性名リスト
    
    // 管理属性
    private Integer id = null; // この属性は必ず定義すること (この行は書き変えないでください)
    

    // ■■■■■■■■■■■■ ユーザ定義属性 をここに定義して下さい ■■■■■■■■■■■■■
    // ■■■■■■■■■■■■ Integer, String, Boolean などを使ってください (int, boolean は避ける) ■■■■■■■■■■■■
    private String 商品名 = null;
    private String 単価 = null;
    private Boolean 野菜か = null;
    private String 説明 = null;

    // ■■■■■■■■■■■■ パラメータは、id とユーザ定義属性 を並べてください ■■■■■■■■■■■■■
    public 商品Dso(Integer id, String 商品名, String 単価, Boolean 野菜か, String 説明) {
        super();
        this.属性名リスト = null;
        // 管理属性「id」と、ユーザ属性の初期化 (this.id = id の行は必ず残しておくこと)
        this.id = id;
        // ■■■■■■■■■■■■ ユーザ定義属性 の初期化の処理をここに定義して下さい ■■■■■■■■■■■■■
        this.商品名 = 商品名;
        this.単価 = 単価;
        this.野菜か = 野菜か;
        this.説明 = 説明;
    }
    
    static public ArrayList<String> get属性名リスト() {
        if ( 属性名リスト == null ) {
            属性名リスト = new ArrayList<String>();
            // ■■■■■■■■■■■■ ユーザ定義の属性名を並べて下さい ■■■■■■■■■■■■■
            // ユーザ属性名の追加
            属性名リスト.add("商品名");
            属性名リスト.add("単価");
            属性名リスト.add("野菜か");
            属性名リスト.add("説明");
            // ■■■■■■■■■■■■ ユーザ定義属性の属性数 を正しく書いてください ■■■■■■■■■■■■■
            ユーザ属性数 = 4;
            //  ■■■■■■■■■■■■ 特記事項: lookup.jsp の「<t:checkbox for="checkbox1" index="ほげほげ" />」のところの数を調整してください
        }
        
        return 属性名リスト;
    }
    
    //
    public static ListDataModel ListDataModelに変換( ArrayList<商品Dso> data ) {
        // 「id」が、開始レポート番号から、終了レポート番号の範囲にあるものを絞り込んで、「this.情報」属性にセットする
        
        ArrayList rowList = new ArrayList();
        for(int i=0; i<data.size(); i++) {
            ArrayList<Object> tuple = new ArrayList<Object>();
            
            // ■■■■■■■■■■■■ 挿入処理を書きなおしてください ■■■■■■■■■■■■■
            // ■■■■■■■■■■■■ 挿入の順序は、最初が「id」、あとは、get属性名リストに書いたユーザ属性の順序に一致させてください ■■■■■■■■■■■■■
            // データを id, 商品名, 単価, 野菜か、の順で挿入する
            tuple.add( data.get(i).getId() );
            tuple.add( data.get(i).get商品名() );
            tuple.add( data.get(i).get単価() );
            tuple.add( data.get(i).get野菜か() );
            tuple.add( data.get(i).get説明() );
            // ■■■■■■■■■■■■ 書きなおしは、ここまで ■■■■■■■■■■■■■
            
            rowList.add(tuple);
        }
        return new ListDataModel(rowList);
    }
        
    static int getユーザ属性数() {
        return ユーザ属性数;
    }
   
    //
    // セッターとゲッター(決まり文句)
    //
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String get商品名() {
        return 商品名;
    }

    public void set商品名(String 商品名) {
        this.商品名 = 商品名;
    }

    public String get単価() {
        return 単価;
    }

    public void set単価(String 単価) {
        this.単価 = 単価;
    }

    public Boolean get野菜か() {
        return 野菜か;
    }

    public void set野菜か(Boolean 野菜か) {
        this.野菜か = 野菜か;
    }

    public String get説明() {
        return 説明;
    }

    public void set説明(String 説明) {
        this.説明 = 説明;
    }
    
    
}

表示テーブルビジネスロジック.java


package hoge.hoge.com;

import java.io.IOException;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;

public class 表示テーブルビジネスロジック {
    String 以前のキーワード = null;
    String 以前の追加キーワード = null;
            
       void toggle列チェック( OpenDataList openDataList ) {
           // 列がチェックされたときの処理
           openDataList.toggle列チェック();
       }
       
       void toggle行チェック( OpenDataList openDataList ) {
           // 行がチェックされたときの処理
           openDataList.toggle行チェック();
       }
       
       
       void この条件で呼び出す( OpenDataList openDataList, String 表示方法, int 開始レポート番号, int 終了レポート番号, List<String> 表示属性名リスト, String ソート属性と順序 ) {
           // lookup呼び出し画面での、「この条件で呼び出す」ボタン
           
           // ヘッダにある「チェック済み」、「非表示」属性の更新
           openDataList.非表示一括実行( 表示属性名リスト );
       
        // ソート設定
        if ( ソート属性と順序 != null ) {
            if ( ソート属性と順序.equals("レポート番号・昇順(古いものを上に)") ) {
                openDataList.setSort("id");
                openDataList.setAscending(true);
            }
            if ( ソート属性と順序.equals("レポート番号・降順(新しいものを上に)") ) {
                openDataList.setSort("id");
                openDataList.setAscending(false);
            }
            if ( ソート属性と順序.equals("商品名・昇順(あいうえお順)") ) {
                openDataList.setSort("商品名");
                openDataList.setAscending(true);
            }
        }

           // データ本体の呼び出し
           openDataList.呼び出し( 開始レポート番号, 終了レポート番号 );
       
           this.表示幅の再調整( openDataList, 表示方法 );
       }
       
       void この条件で再表示( OpenDataList openDataList, String 行操作, String 列操作, String キーワード, String 追加キーワード, String 表示方法, int 開始レポート番号, int 終了レポート番号 ) {
           
           if ( 行操作 != null ) {
               if ( 行操作.equals( "チェックした「行」は表示しない" ) ) {
                      openDataList.チェックした行は表示しない();    
               }
               if ( 行操作.equals( "チェックした「行」のみを表示する" ) ) {
                      openDataList.チェックした行のみを表示する();    
               }
               if ( 行操作.equals( "全ての「行」を表示" ) ) {
                      openDataList.全ての行を表示();                   
               }
           }
           
           if ( 列操作 != null ) {
               if ( 列操作.equals( "チェックした「列」は表示しない" ) ) {
                      openDataList.チェックした列は表示しない();    
               }
               if ( 列操作.equals( "全ての「列」を表示" ) ) {
                      openDataList.全ての列を表示();                   
               }
           }
           
           if ( ( キーワード != null ) || ( 追加キーワード != null ) ) {
               if ( キーワード == null ) {
                   キーワード = "";
               }
               if ( 追加キーワード == null ) {
                   追加キーワード = "";
               }
               if ( ( this.以前のキーワード != キーワード ) || ( this.以前の追加キーワード != 追加キーワード ) ) {
                   this.以前のキーワード = キーワード;
                   this.以前の追加キーワード = 追加キーワード;
                   // キーワードは、単語をカンマで区切るが、カンマは「」に統一
                   openDataList.再度の呼び出し( 開始レポート番号, 終了レポート番号,
                           /* キーワード */ キーワード.replaceAll( "、", ",").replaceAll( ", ", ",").replaceAll( ",", ","),
                           /* 追加キーワード */ 追加キーワード.replaceAll( "、", ",").replaceAll( ", ", ",").replaceAll( ",", ","));
               }
           }
           this.表示幅の再調整( openDataList, 表示方法 );
       }
       
       void 表示幅の再調整( OpenDataList openDataList, String 表示方法 ) {
           
        int total_width;
        if ( 表示方法.equals("横は1画面に収める") ) {
            total_width = 980;
        }
        else {
            total_width = 980 * 2;
        }
        
        final int 倍率 = 16;
        final double default_width = total_width / openDataList.getユーザ属性数(); // 幅の平均
        int 列番号=0;
        int 長いデータの幅の合計 = 0;
        double width;
        
        for (列番号=0;列番号 < openDataList.getユーザ属性数();列番号++) {
            // 非表示ならば 幅は 0 でよい
            if ( openDataList.is任意の列の非表示( 列番号 + 1 ) ) {
                width = 0;
            }
            else {
                // 幅は、データの「長さ」から決める
                double len = openDataList.maxLength( 列番号 + 1 ) * 倍率;
                // データの長さが短い(「幅の平均」よりも短い)ときは、調整する。
                if ( len < default_width ) {
                    width = len;
                }
                // データの長さが長いときは、取りあえず 0 にしておく。
                else if ( len > ( default_width * 4 ) ) {
                    width = 0;
                    長いデータの幅の合計 = 長いデータの幅の合計 + (int)len;
                }
                else {
                    width = default_width;
                }
            }
            openDataList.set任意の列の表示幅( 列番号 + 1, (int)width );
        }
       
        // 幅の合計を求めてみる
        int total = 0;
        for (列番号=0;列番号 < openDataList.getユーザ属性数();列番号++) {
            total = total + openDataList.get任意の列の表示幅( 列番号 + 1 );
        }
       
        // 長いデータについての調整
        for (列番号=0;列番号 < openDataList.getユーザ属性数();列番号++) {
            if ( ! openDataList.is任意の列の非表示( 列番号 + 1 ) ) {
                // 幅は、データの「長さ」から決める
                double len = openDataList.maxLength( 列番号 + 1 ) * 倍率;
                if ( len > ( default_width * 4 ) ) {
                    // 幅の余り ( total_width - total ) を、len 値に比例して配分
                    openDataList.set任意の列の表示幅( 列番号 + 1, (total_width - total) * ((int)len) / 長いデータの幅の合計 );
                }
            }
        }
       }
       
       void エクスポート( OpenDataList openDataList, int 開始レポート番号, int 終了レポート番号 ) {
           Calendar c = Calendar.getInstance( new Locale( "ja" ) );
           // ファイル名には、日時を付ける
           String ファイル名 = "c:\\インシデント集計分析"
                + c.get( Calendar.YEAR ) + "年 "
                    + c.get( Calendar.MONTH ) + "月 "
                    + c.get( Calendar.DAY_OF_MONTH ) + "日 "
                    + c.get( Calendar.HOUR_OF_DAY ) + "時 "
                    + c.get( Calendar.MINUTE ) + "分 "
                    + c.get( Calendar.SECOND ) + "秒"
                    + ".xls";
           openDataList.エクスポート( ファイル名,
                                   /* ワークシート名 */ "work sheet 1",
                                   開始レポート番号, 終了レポート番号);
        try {
            Runtime.getRuntime().exec(new String[] {"C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE",
                    ファイル名});
        } catch (IOException e) {
            e.printStackTrace();
        }
       }
       
       void ピボットテーブルを表示( OpenDataList openDataList, String ピボットテーブル行の属性, String ピボットテーブル列の属性 ) {
        openDataList.ピボットテーブルの生成( ピボットテーブル行の属性, ピボットテーブル列の属性 );
       }
}

表示テーブルヘッダ.java


package hoge.hoge.com;

// 使用法: 表示テーブルヘッダ() 内の「商品Dso」を書き換え

import java.util.ArrayList;
import java.util.List;

import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;
import java.util.HashMap;

public class 表示テーブルヘッダ {
    private DataModel 情報; // id と ユーザ属性 (注) <t:columns> タグで表示したいので、DataModel クラスにする必要がある
    private int ユーザ属性数;
    private ArrayList<SelectItem> 属性アイテムリスト = null; // lookup呼び出し画面でのチェックボックス表示に使う. 属性「情報」から生成
    private ArrayList<String> 属性名リスト = null; // 属性「情報」から生成
    
    表示テーブルヘッダ() {
        // 表示テーブルヘッダは、「表示テーブルヘッダ属性項目」のリストを持つ。このリストは、第一要素は id が入る(これは管理属性)。第2要素以降は、ユーザが自由に定義できる属性。
        List headerList = new ArrayList();
       
        // 表示テーブルヘッダ属性項目の初期化
       
        // ■管理属性の分■ (決まり文句)
        // 下記の行は、管理属性の定義なので、プログラムのこの行を削除しないこと。 new ArrayList() の直後に実行すること。
        // headerList.add(new 表示テーブルヘッダ属性項目("行チェック",    "0",    false,false,true));
        headerList.add(new 表示テーブルヘッダ属性項目("id",        "0",    false,false,false)); // ■ 「レポート番号」のこと。
       
        // ■ユーザ定義属性の分■
        // ■■■■■■■■■■■■ 「商品Dso」とある箇所(3か所あります)を書き換えて使ってください ■■■■■■■■■
        for(int i=0;i < 商品Dso.get属性名リスト().size();i++) {
            // 表示ラベル, 表示幅, 編集可能, チェック済み, 非表示の順
            headerList.add( new 表示テーブルヘッダ属性項目( 商品Dso.get属性名リスト().get(i), "0",    false,false,false ) );
        }
        this.ユーザ属性数 = 商品Dso.getユーザ属性数();
        // ■■■■■■■■■■■■ 書き換えはここまで ■■■■■■■■■
       
        this.情報 = new ListDataModel(headerList);
    }

    //
    // これ以降は決まり文句 (基本的には、ここままで動くので、無理に変更する必要はない)
    //

    private 表示テーブルヘッダ属性項目 lookupByName( String 表示ラベル )
    {
        // 「情報」属性の全要素に関する操作
        // 「表示テーブルヘッダ属性項目」オブジェクトの検索
        List<表示テーブルヘッダ属性項目> headers = (List) this.get情報().getWrappedData();
        for (int i=0;i < headers.size();i++) {
                表示テーブルヘッダ属性項目 item = headers.get(i);
                if ( item.get表示ラベル().equals( 表示ラベル ) ) {
                    // 見つかった!
                    return item;
                }
        }
        // not found !
        return null;
    }
    
    public int get列番号by表示ラベル( String 表示ラベル )
    {
        // 「情報」属性の全要素に関する操作
        // 「表示テーブルヘッダ属性項目」オブジェクトの検索
        List<表示テーブルヘッダ属性項目> headers = (List) this.get情報().getWrappedData();
        for (int i=0;i < headers.size();i++) {
                表示テーブルヘッダ属性項目 item = headers.get(i);
                if ( item.get表示ラベル().equals( 表示ラベル ) ) {
                    // 見つかった!
                    return i;
                }
        }
        // not found !
        return -1;
    }
    
    public ArrayList<SelectItem> get属性アイテムリスト() {
        // 「情報」属性の要素のうち、ユーザ属性に関する操作
        // 「表示テーブルヘッダ」の中のユーザ属性の「表示ラベル」を使い、ArrayList<SelectItem> オブジェクトを作る。これは、JSF でのチェックボックス表示に使う
        if ( this.属性アイテムリスト == null ) {
            this.属性アイテムリスト = new ArrayList<SelectItem>();
            
            List<表示テーブルヘッダ属性項目> headers = (List) this.get情報().getWrappedData();
            for (int i=0;i < this.ユーザ属性数;i++)
            {
                表示テーブルヘッダ属性項目 item = headers.get(i + 1);
                // new SelectItem では、"値", "(表示される)ラベル" の順で記述
                this.属性アイテムリスト.add( new SelectItem( item.get表示ラベル(), item.get表示ラベル() ));
            }
        }
        return this.属性アイテムリスト;
    }
    
    public ArrayList<String> get属性名リスト() {
        // 「情報」属性の要素のうち、ユーザ属性に関する操作
        // 「表示テーブルヘッダ」の中のユーザ属性の「表示ラベル」を使い、ArrayList<String> オブジェクトを作る。
        if ( this.属性名リスト == null ) {
            this.属性名リスト = new ArrayList<String>();
            
            List<表示テーブルヘッダ属性項目> headers = (List) this.get情報().getWrappedData();
            for (int i=0;i < this.ユーザ属性数;i++)
            {
                表示テーブルヘッダ属性項目 item = headers.get(i + 1);
                // new SelectItem では、"値", "(表示される)ラベル" の順で記述
                this.属性名リスト.add( item.get表示ラベル() );
            }
        }
        return this.属性名リスト;
    }
    
    public void 非表示一括実行( List<String> 表示属性名リスト ) {
    // 「情報」属性の要素のうち、ユーザ属性に関する操作
    // 「表示属性名リスト」に書かれていない属性名は、「列チェック済み」を true に、「非表示」を true に。
        
    // まずは、全ての「列チェック済み」を false に、「非表示」を false に。
        List<表示テーブルヘッダ属性項目> headers = (List) this.get情報().getWrappedData();
        for (int i=0;i < this.ユーザ属性数;i++) {
                表示テーブルヘッダ属性項目 item = headers.get(i + 1);
                item.set列チェック済み( true );
                item.set非表示( true );
        }
       
        for (int j=0;j < 表示属性名リスト.size();j++) {
            表示テーブルヘッダ属性項目 item = this.lookupByName( 表示属性名リスト.get(j) );
            if ( item != null ) {
                item.set列チェック済み( false );
                item.set非表示( false );
            }
        }
    }
    
    void チェックした列は表示しない() {
        // 「情報」属性の要素のうち、ユーザ属性に関する操作
        List<表示テーブルヘッダ属性項目> headers = (List) this.get情報().getWrappedData();
        for (int i=0;i < this.ユーザ属性数;i++) {
            表示テーブルヘッダ属性項目 item = headers.get(i + 1);
            if ( item.is列チェック済み() ) {
                item.set非表示( true );
            }
        }
    }
    
    void 全ての列を表示() {
        // 「情報」属性の要素のうち、ユーザ属性に関する操作
        List<表示テーブルヘッダ属性項目> headers = (List) this.get情報().getWrappedData();
        for (int i=0;i < this.ユーザ属性数;i++) {
            表示テーブルヘッダ属性項目 item = headers.get(i + 1);
            item.set非表示( false );
        }
    }    
    
    
    public void set表示幅( int 列番号, int 表示幅 ) {
        // 注意:ユーザ属性の列番号は、1から始まる整数である
        List<表示テーブルヘッダ属性項目> headers = (List) this.get情報().getWrappedData();
        表示テーブルヘッダ属性項目 item = headers.get(列番号);
        
        if ( item != null ) {
            item.set表示幅( String.valueOf( 表示幅 ) );
        }
    }
    
    public int get表示幅( int 列番号 ) {
        // 注意:ユーザ属性の列番号は、1から始まる整数である
        List<表示テーブルヘッダ属性項目> headers = (List) this.get情報().getWrappedData();
        表示テーブルヘッダ属性項目 item = headers.get(列番号);
        
        if ( item != null ) {
            return Integer.parseInt( item.get表示幅() );
        }
        else {
            return -1;
        }
    }
    
    public String  get表示ラベル( int 列番号 ) {
        // 注意:ユーザ属性の列番号は、1から始まる整数である
        List<表示テーブルヘッダ属性項目> headers = (List) this.get情報().getWrappedData();
        表示テーブルヘッダ属性項目 item = headers.get(列番号);
        
        if ( item != null ) {
            return item.get表示ラベル();
        }
        else {
            return "";
        }
    }
    
    public boolean is非表示( int 列番号 )
    {
        // 注意:ユーザ属性の列番号は、1から始まる整数である
        List<表示テーブルヘッダ属性項目> headers = (List) this.get情報().getWrappedData();
        表示テーブルヘッダ属性項目 item = headers.get(列番号);

        if ( item != null ) {
            return item.is非表示();
        }
        else {
            return false;
        }
    }
   
    // ゲッター
    public DataModel get情報() {
        return 情報;
    }

    public int getユーザ属性数() {
        return ユーザ属性数;
    }
}

表示テーブルヘッダ属性項目.java


/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package hoge.hoge.com;

public class 表示テーブルヘッダ属性項目
// 表示テーブルの各属性に関する情報の管理
{
    public 表示テーブルヘッダ属性項目()
    {
    }
                                        // それぞれの属性(列)について
    private String 表示ラベル = null;        //   表示されるラベル
    private String 表示幅 = null;        //   表示幅
    private boolean 編集可能 = false;    //   編集可能か? (true または false)
    private boolean 列チェック済み = false;    //   「チェック」されたか (true または false)
    private boolean 非表示 = true;    //   表示するか? (true または false)
   
    public 表示テーブルヘッダ属性項目(String label, String width, boolean editable, boolean checked, boolean rendered)
    {
        this.表示ラベル = label;
        this.表示幅 = width;
        this.編集可能 = editable;
        this.列チェック済み = checked;
        this.非表示 = rendered;
    }
   
    public void toggle列チェック済み() {
        this.列チェック済み = !(this.列チェック済み);
    }

    public boolean is出力テキストで表示() {
        if ( ( this.編集可能 == false ) && ( this.非表示 == false ) ) {
            return true;
        }
        else {
            return false;
        }
    }
   
    public boolean is入力テキストで表示() {
        if ( ( this.編集可能 == true ) && ( this.非表示 == true ) ) {
            return true;
        }
        else {
            return false;
        }
    }
   
    public boolean is表示() {
        return !this.非表示;
    }
   
    public String get列チェック表示ラベル() {
    //   「チェック」されたかを表示するときのラベル
        if ( this.列チェック済み ) {
            return "■";
        }
        else {
            return "□";
        }
    }
    public String get列チェック背景色() {
    //   「チェック」されたかを表示するときの背景色
        if ( this.列チェック済み ) {
            return "#ff0000"; // 赤
        }
        else {
            return "#c0c0c0"; // 灰色
        }
    }
    
    // セッター、ゲッター

    public String get表示ラベル() {
        return 表示ラベル;
    }

    public void set表示ラベル(String 表示ラベル) {
        this.表示ラベル = 表示ラベル;
    }

    public String get表示幅() {
        return 表示幅;
    }

    public void set表示幅(String 表示幅) {
        this.表示幅 = 表示幅;
    }

    public boolean is編集可能() {
        return 編集可能;
    }

    public void set編集可能(boolean 編集可能) {
        this.編集可能 = 編集可能;
    }

    public boolean is列チェック済み() {
        return 列チェック済み;
    }

    public void set列チェック済み(boolean 列チェック済み) {
        this.列チェック済み = 列チェック済み;
    }

    public boolean is非表示() {
        return 非表示;
    }

    public void set非表示(boolean 非表示) {
        this.非表示 = 非表示;
    }
}

表示テーブル本体.java

package hoge.hoge.com;

//使用法: 「商品Dso」を書き換え

import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.regex.*;

import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;

import com.sun.org.apache.xalan.internal.xsltc.compiler.Pattern;

public class 表示テーブル本体 {
    private DataModel 情報;
    private HashMap<Integer, Boolean> 行チェックマップ; // id が Integer, 行チェックが Boolean
    private HashMap<Integer, Boolean> 行表示マップ; // id が Integer, 行表示が Boolean
    
    //
    public List<List<Object>> getWrappedData() {
        // 属性「情報」に格納されているデータを、List<List<Object>> 形式で返すために、getWrappedData を使用
        if ( this.情報 != null ) {
            return (List<List<Object>>) this.get情報().getWrappedData();
        }
        else {
            return null;
        }
    }
   
    void 呼び出し( int 開始レポート番号, int 終了レポート番号 ) {
        // ■■■■■■■■■■■■ 「商品Dso」, 「商品Dao」とある箇所を書き換えて使ってください ■■■■■■■■■
        this.情報 = 商品Dso.ListDataModelに変換( 商品Dao.呼び出し( 開始レポート番号, 終了レポート番号 ) );        
        // ■■■■■■■■■■■■ 書き換えはここまで ■■■■■■■■■
        
        List<List<Object>> items = this.getWrappedData();
        for(int i=0;i < items.size();i++) {
            ArrayList<Object> tuple = (ArrayList<Object>)items.get(i);
            if ( tuple == null ) {
                // error
                return;
            }
            Integer id = (Integer) tuple.get(0); // 先頭要素が id
            // 行チェックマップに登録しておく
            行チェックマップ.put( id, Boolean.FALSE);
            
            // 行表示マップに登録しておく
            行表示マップ.put( id, Boolean.TRUE);
        }
        return;
    }
    
    void 再度の呼び出し( int 開始レポート番号, int 終了レポート番号, String キーワード, String 追加キーワード )
    // 行チェックマップ、行表示マップの初期化はしない
    {
        // ■■■■■■■■■■■■ 「商品Dso」, 「商品Dao」とある箇所を書き換えて使ってください ■■■■■■■■■
        this.情報 = 商品Dso.ListDataModelに変換( 商品Dao.呼出し後置換( 開始レポート番号, 終了レポート番号, キーワード, 追加キーワード ) );
        // ■■■■■■■■■■■■ 書き換えはここまで ■■■■■■■■■
    }
    
    表示テーブル本体() {
        // オブジェクト生成時には、まだ、中身は空
        this.行チェックマップ = new HashMap<Integer,Boolean>();
        this.行表示マップ = new HashMap<Integer,Boolean>();
        this.情報 = null;
    }
    
    //
    // これ以降は決まり文句 (基本的には、ここままで動くので、無理に変更する必要はない)
    //

    void チェックした行は表示しない() {
        this.全ての行を表示();
        
        List<List<Object>> items = this.getWrappedData();
        for(int i=0;i < items.size();i++) {
            ArrayList<Object> tuple = (ArrayList<Object>)items.get(i);
            if ( tuple == null ) {
                // error
                return;
            }
            Integer id = (Integer) tuple.get(0); // 先頭要素が id
            行表示マップ.put(id, !行チェックマップ.get(id)); // チェックした行は表示しないので ! が付く
        }
        return;
    }
    
    void チェックした行のみを表示する() {
        this.全ての行を非表示();
        
        List<List<Object>> items = this.getWrappedData();
        for(int i=0;i < items.size();i++) {
            ArrayList<Object> tuple = (ArrayList<Object>)items.get(i);
            if ( tuple == null ) {
                // error
                return;
            }
            Integer id = (Integer) tuple.get(0); // 先頭要素が id
            行表示マップ.put(id, 行チェックマップ.get(id)); // チェックした行は表示するので ! が付かない
        }
        return;
    }
    
    void 全ての行を表示 () {
        this.全ての行を設定( Boolean.TRUE );
        return;
    }
    
    void 全ての行を非表示 () {
        this.全ての行を設定( Boolean.FALSE );
        return;
    }
    
    void 全ての行を設定 ( Boolean val ) {
        // TRUE なら すべての行を表示する
        // FALSE ならすべての行を表示しない
        List<List<Object>> items = this.getWrappedData();
        for(int i=0;i < items.size();i++) {
            ArrayList<Object> tuple = (ArrayList<Object>)items.get(i);
            if ( tuple == null ) {
                // error
                return;
            }
            Integer id = (Integer) tuple.get(0); // 先頭要素が id
            行表示マップ.put(id, val);
        }
        return;
    }
    
    public String get行チェック表示ラベル() {
        // getRowData() で取得した「行」に対して行う
        // HashMap に格納されている「行チェック」を見て、行がチェックされているかされていないかで違う文字を返す
        if (this.get情報().isRowAvailable()) {
            // getRowData() で、最近クリックした、あるいはレンダリング中の「行「を知る
            ArrayList<Object> tuple = ((ArrayList)this.get情報().getRowData());
            Integer id = (Integer) tuple.get(0); // 先頭要素が id
            if( 行チェックマップ.get(id).booleanValue() ) {
                // true
                return "■";
            }
            else {
                // false
                return "□";
            }
        }
        else {
            return "";
        }
    }
   
    public String get行チェック背景色() {
        // getRowData() で取得した「行」に対して行う
        // HashMap に格納されている「行チェック」を見て、行がチェックされているかされていないかで違う色を返す
        if (this.get情報().isRowAvailable()) {
            // getRowData() で、最近クリックした、あるいはレンダリング中の「行「を知る
            ArrayList<Object> tuple = ((ArrayList)this.get情報().getRowData());
            Integer id = (Integer) tuple.get(0); // 先頭要素が id
            if( 行チェックマップ.get(id).booleanValue() ) {
                // true
                return "#ff0000"; // 赤
            }
            else {
                // false
                return "#c0c0c0"; // 灰色
            }
        }
        else {
            return "";
        }
    }

    public void toggle行チェック() {
        // getRowData() で取得した「行」に対して行う
        // HashMap に格納されている「行チェック」の true, false を反転させる
        if (this.get情報().isRowAvailable()) {
            // getRowData() で、最近クリックした、あるいはレンダリング中の「行」を知る
            ArrayList<Object> tuple = ((ArrayList)this.get情報().getRowData());
            Integer id = (Integer) tuple.get(0); // // 先頭要素が id
            if( 行チェックマップ.get(id).booleanValue() ) {
                // true
                行チェックマップ.put( id, Boolean.FALSE);
            }
            else {
                // false
                行チェックマップ.put( id, Boolean.TRUE);
            }
        }
    }

    public Integer getId() {
        // . getRowData() で取得した「行」に対して取得
        if (this.get情報().isRowAvailable()) {
            // getRowData() で、最近クリックした、あるいはレンダリング中の「行「を知る
            // get(0) ・・・ 戦闘要素に id が入っている
            return (Integer)((ArrayList)this.get情報().getRowData()).get(0);  // 先頭要素が id
        }
        else {
            return null;
        }
    }
   
    public Object getColumnValue( /* 何列目か */ int rowIndex )
    // データ値の取得. getRowData() で取得した「行」に対して取得
    {
        Object columnValue = null;
        if ( this.get情報().isRowAvailable() && rowIndex >= 0 )
        {
            ArrayList<Object> tuple = ((ArrayList)this.get情報().getRowData());
            columnValue = tuple.get( rowIndex );       
        }
        return columnValue;
    }

    public void setColumnValue( /* 何列目か */ int rowIndex, Object value )
    // データ値の更新. getRowData() で取得した「行」に対して取得
    {
      if ( this.get情報().isRowAvailable() && rowIndex >= 0 ) {
          ArrayList<Object> tuple = ((ArrayList)this.get情報().getRowData());
        tuple.set( rowIndex, value );
      }
    }
   
    public boolean is行表示() {
        // getRowData() で取得した「行」に対して行う
        // HashMap に格納されている「行チェック」の true, false 取得する
        
        if (this.get情報().isRowAvailable()) {
            // getRowData() で、最近クリックした、あるいはレンダリング中の「行」を知る
            ArrayList<Object> tuple = ((ArrayList)this.get情報().getRowData());
            Integer id = (Integer) tuple.get(0); // // 先頭要素が id
            return 行表示マップ.get(id).booleanValue();
        }
        else {
            return false;
        }
    }
   
    public Boolean is任意の行の行表示( int 行番号 ) {
        List<List<Object>> items = this.getWrappedData();
        ArrayList<Object> tuple = (ArrayList<Object>)items.get(行番号);
        if ( tuple == null ) {
            return Boolean.FALSE;
        }
        Integer id = (Integer) tuple.get(0); // 先頭要素が id
        return 行表示マップ.get(id);
    }
   
    public void set行表示( int 行番号, boolean val ) {
        List<List<Object>> items = this.getWrappedData();
        ArrayList<Object> tuple = (ArrayList<Object>)items.get(行番号);
        if ( tuple == null ) {
            return;
        }
        Integer id = (Integer) tuple.get(0); // 先頭要素が id
        行表示マップ.put(id, val);
    }
   
    public int maxLength( int 列番号 ) {
        // 指定された列番号の全データについて、データを文字列表現に変換した時の最大長
        int len = 0;
        List<List<Object>> items = this.getWrappedData();
        for (int i=0;i < items.size();i++) {
            List<Object> item = (List<Object>)items.get(i);
            Object obj = item.get(列番号);
            // 文字列に強制的に変換 (Boolean, Integer データなどを、文字列表現に変換、ということ)
            String s = String.valueOf( obj );
            if ( len < s.length() ) {
                len = s.length();
            }
        }
        return len;
    }
   
    // ゲッター
    public DataModel get情報() {
        return this.情報;
    }
}

analyze.JSP


<%@ page session="false" contentType="text/html;charset=utf-8"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="https://myfaces.apache.org/tomahawk" prefix="t"%>
<html>

<head>
                <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
                <!-- タイトルは,■■画面名■■に応じて,「報告者の情報」のように付けてください  (「a1」などは取る)-->
                <title>レポート・集計分析画面</title>
</head>

<%@ include file="ラベル設定関数.jsp"%>

<!-- body タグ内のsetLabelの form1, checkbox1 等の部分は,■■form部品に応じて■■書き換えて下さい-->
  <body onLoad="jikoku();setColor();checkInterruption();setLabel('form1:checkbox1','form1:radio1')">

 
    <f:view>
      <h:messages />
      <h:form id="form1">
        <!-- value="ほにゃらら" の部分は,value="a1", "a16a" のように、ページIDを付ける -->
        <h:inputHidden value="analyze" binding="#{analyzeForm.hiddenInput}"/>
       
        <H1>
          <center>
            インシデントレポート・集計分析画面
          </center>
        </H1>

       
       
        <t:dataTable id="data"
                         border="1"
                     rowOnClick="this.style.backgroundColor='#FFE0E0'"
                     rowOnDblClick="this.style.backgroundColor='#E0E0E0'"
                     var="row"
                     value="#{openDataList.data}"
                     preserveDataModel="false"
                     sortColumn="#{openDataList.sort}"
                     sortAscending="#{openDataList.ascending}"
                     preserveSort="true">
          <h:column>
            <!-- commandButton タグで、ボタンを付ける。ボタンのクリック時には、action 属性で指定したメソッドが呼び出される -->
            <t:commandButton rendered="#{openDataList.行表示}" action="#{action.行チェック}" immediate="true" style="background-color:#{openDataList.行チェック背景色}" value="#{openDataList.行チェック表示ラベル}"/>
          </h:column>
         
          <t:columns id="columns" value="#{openDataList.表示テーブルヘッダ}" var="item" style="width:#{openDataList.表示幅}px">
            <f:facet name="header">
              <h:panelGrid columns="2">
                <t:commandSortHeader columnName="#{item.表示ラベル}" arrow="true" immediate="true">
                  <h:outputText rendered="#{item.表示}" value="#{item.表示ラベル}" />
                </t:commandSortHeader>
                <t:commandButton rendered="#{item.表示}" action="#{action.列チェック}" value="#{item.列チェック表示ラベル}" style="background-color:#{item.列チェック背景色}" immediate="true"/>
              </h:panelGrid>
            </f:facet>
           
            <!-- row is also available -->
            <h:inputText rendered="#{openDataList.入力テキストで表示}" value="#{openDataList.columnValue}" />
            <h:outputText escape="false" rendered="#{openDataList.出力テキストで表示}" value="#{openDataList.columnValue}" />
          </t:columns>
         
          <h:column>
            <f:facet name="header1">
              <t:commandSortHeader arrow="true" immediate="true" columnName="id" >
                <h:outputText value="id"/>
              </t:commandSortHeader>
            </f:facet>
           
            <!-- commandLink タグで、リンクを付ける。リンクのクリック時には、action 属性で指定したメソッドが呼び出される -->
            <t:commandLink action="#{action.行チェック}" immediate="true">
              <h:outputText rendered="#{openDataList.行表示}" value="#{openDataList.id}"/>
            </t:commandLink>                               
          </h:column>
         
        </t:dataTable>
       
        <br/>
       
        <!-- ここは決まり文句  -->
        <f:subview id="submit_top">
          <center>
            <%@ include file="呼び出し画面に戻るエクスポート.jsp"%>
          </center>
        </f:subview>
       
        <br/>
               
        <TABLE frame="box" border="1" cellspacing="0" cellpadding="0" width="90%" 
               bgcolor="#f0f0f8" bordercolor="#777777">
          <tr>
            <td align="center" bgcolor="#f5f5ff">

              <!--○○○列操作 (radio1)○○○-->
              <TABLE rules="null" border="0" cellspacing="0" cellpadding="12" width="97%">
                <TR><TD colspan="2" style=" border-bottom:1px dashed #000">
                    <!--■タイトル表示■-->
                    <span style="color:#121250;font-size:large;font-weight:bold">列操作</span>
                    <!--■注意書き(全角のかっこ).例えば「(複数回答可)」,「(内線番号を記入)」など)-->
                    <span style="color:#121250;font-size:medium;font-weight:bold"></span>
                    <!--■「(必須)」を書く  ・・・  ここでの「必須」は,記入したかのバリデーションのこと.データベースの「非空」制約とは違う■-->
                    <span style="color:#8b0000;font-size:medium;font-weight:bold"></span>
                </TD></TR>
                <TR><TD width="0%"/><TD width="100%">
                    <span style="color:#121250;font-size:medium;">           
                 
              <%/* ■「radioほにゃらら」と,value="#{formdata.ほにゃらら}"を書く■ */%>
                      <!-- layout="spread" にしているので,チェックボックスを作るが表示はされない(2カラム表示を可能にするための工夫) -->
                      <t:selectOneRadio id="radio1" value="#{analyzeForm.列操作}" layout="spread" >
                        <f:selectItem itemValue="チェックした「列」は表示しない" itemLabel="チェックした「列」は表示しない" />
                        <f:selectItem itemValue="全ての「列」を表示" itemLabel="全ての「列」を表示" />
                      </t:selectOneRadio>
                     
                      <!-- ラジオボタンは1カラム(columns="1"), 2カラム(colmuns="2"), 4カラム(colmuns="4")のいずれか.複数カラムにすることがありえるので,panelGrid を使用 -->
                      <!-- 基本は4カラム -->
                      <h:panelGrid columns="1">
                        <%/* ■1カラムのときは,以下のf:vervatimは3つとも取り除く■ */%>
                        <%/* ■以下,「for="radioほにゃらら"」  部分は,t:selectOneRadioの「id="radioほにゃらら"」は一致させること.index は 0 から始まるく■ */%>
                        <t:radio for="radio1" index="0" />
                        <t:radio for="radio1" index="1" />                 
                      </h:panelGrid>                 
                     
                    </span>           
                </TD></TR>
              </TABLE>

          </td></tr><tr><td align="center" bgcolor="#f5f5ff">
            <!--○○○行操作 (radio2)○○○-->
              <TABLE rules="null" border="0" cellspacing="0" cellpadding="12" width="97%">
                <TR><TD colspan="2" style=" border-bottom:1px dashed #000">
                    <!--■タイトル表示■-->
                    <span style="color:#121250;font-size:large;font-weight:bold">行操作</span>
                    <!--■注意書き(全角のかっこ).例えば「(複数回答可)」,「(内線番号を記入)」など)-->
                    <span style="color:#121250;font-size:medium;font-weight:bold"></span>
                    <!--■「(必須)」を書く  ・・・  ここでの「必須」は,記入したかのバリデーションのこと.データベースの「非空」制約とは違う■-->
                    <span style="color:#8b0000;font-size:medium;font-weight:bold"></span>
                </TD></TR>
                <TR><TD width="0%"/><TD width="100%">
                    <span style="color:#121250;font-size:medium;">           
                 
              <%/* ■「radioほにゃらら」と,value="#{formdata.ほにゃらら}"を書く■ */%>
                      <!-- layout="spread" にしているので,チェックボックスを作るが表示はされない(2カラム表示を可能にするための工夫) -->
                      <t:selectOneRadio id="radio2" value="#{analyzeForm.行操作}" layout="spread" >
                        <f:selectItem itemValue="チェックした「行」は表示しない" itemLabel="チェックした「行」は表示しない" />
                        <f:selectItem itemValue="チェックした「行」のみを表示する" itemLabel="チェックした「行」のみを表示する" />
                        <f:selectItem itemValue="全ての「行」を表示" itemLabel="全ての「行」を表示" />
                      </t:selectOneRadio>
                     
                      <!-- ラジオボタンは1カラム(columns="1"), 2カラム(colmuns="2"), 4カラム(colmuns="4")のいずれか.複数カラムにすることがありえるので,panelGrid を使用 -->
                      <!-- 基本は4カラム -->
                      <h:panelGrid columns="1">
                        <%/* ■1カラムのときは,以下のf:vervatimは3つとも取り除く■ */%>
                        <%/* ■以下,「for="radioほにゃらら"」  部分は,t:selectOneRadioの「id="radioほにゃらら"」は一致させること.index は 0 から始まるく■ */%>
                        <t:radio for="radio2" index="0" />
                        <t:radio for="radio2" index="1" />   
                        <t:radio for="radio2" index="2" />              
                      </h:panelGrid>                 
                     
                    </span>           
                </TD></TR>
              </TABLE>
             
             
          </td></tr><tr><td align="center" bgcolor="#f5f5ff">
              <!--○○○キーワード (textarea1, textarea2)○○○-->
              <TABLE rules="null" border="0" cellspacing="0" cellpadding="12" width="97%">
                <TR><TD colspan="2" style=" border-bottom:1px dashed #000">
                    <!--■タイトル表示■-->
                    <span style="color:#121250;font-size:large;font-weight:bold">キーワード</span>
                    <!--■注意書き(全角のかっこ).例えば「(複数回答可)」,「(内線番号を記入)」など)-->
                    <span style="color:#121250;font-size:medium;font-weight:bold"></span>
                    <!--■「(必須)」を書く  ・・・  ここでの「必須」は,記入したかのバリデーションのこと.データベースの「非空」制約とは違う■-->
                    <span style="color:#8b0000;font-size:medium;font-weight:bold"></span>
                </TD></TR>
                <TR><TD width="0%"/><TD width="100%">
                    <span style="color:#121250;font-size:medium;">           
               
   
                      <h:outputLabel for="textarea1" value="キーワード (キーワードを強調表示す.キーワードは複数可です。カンマ(「、」または「,」)で区切ってください)"/>
                      <br/>
                      <h:inputTextarea id="textarea1" cols="80" rows="3" value="#{analyzeForm.キーワード}"/>
                      <br/>
                      <h:outputLabel for="textarea2" value="追加キーワード (追加キーワードを強調表示す.追加キーワードは複数可です。カンマ(「、」または「,」)で区切ってください)"/>
                      <br/>
                      <h:inputTextarea id="textarea2" cols="80" rows="3" value="#{analyzeForm.追加キーワード}"/>
                    </span>           
                </TD></TR>
              </TABLE>
             
                        </td></tr><tr><td align="center" bgcolor="#f5f5ff">
            <!--○○○行操作 (radio2)○○○-->
              <TABLE rules="null" border="0" cellspacing="0" cellpadding="12" width="97%">
                <TR><TD colspan="2" style=" border-bottom:1px dashed #000">
                    <!--■タイトル表示■-->
                    <span style="color:#121250;font-size:large;font-weight:bold">表示方法</span>
                    <!--■注意書き(全角のかっこ).例えば「(複数回答可)」,「(内線番号を記入)」など)-->
                    <span style="color:#121250;font-size:medium;font-weight:bold"></span>
                    <!--■「(必須)」を書く  ・・・  ここでの「必須」は,記入したかのバリデーションのこと.データベースの「非空」制約とは違う■-->
                    <span style="color:#8b0000;font-size:medium;font-weight:bold"></span>
                </TD></TR>
                <TR><TD width="0%"/><TD width="100%">
                    <span style="color:#121250;font-size:medium;">           
                 
              <%/* ■「radioほにゃらら」と,value="#{formdata.ほにゃらら}"を書く■ */%>
                      <!-- layout="spread" にしているので,チェックボックスを作るが表示はされない(2カラム表示を可能にするための工夫) -->
                      <t:selectOneRadio id="radio5" value="#{analyzeForm.表示方法}" layout="spread" >
                        <f:selectItem itemValue="横は1画面に収める" itemLabel="横は1画面に収める" />
                        <f:selectItem itemValue="横は1画面に収めない" itemLabel="横は1画面に収めない" />
                      </t:selectOneRadio>
                     
                      <!-- ラジオボタンは1カラム(columns="1"), 2カラム(colmuns="2"), 4カラム(colmuns="4")のいずれか.複数カラムにすることがありえるので,panelGrid を使用 -->
                      <!-- 基本は4カラム -->
                      <h:panelGrid columns="1">
                        <%/* ■1カラムのときは,以下のf:vervatimは3つとも取り除く■ */%>
                        <%/* ■以下,「for="radioほにゃらら"」  部分は,t:selectOneRadioの「id="radioほにゃらら"」は一致させること.index は 0 から始まるく■ */%>
                        <t:radio for="radio5" index="0" />
                        <t:radio for="radio5" index="1" />                 
                      </h:panelGrid>                 
                     
                    </span>           
                </TD></TR>
              </TABLE>
             
             
            </td>
          </tr>
        </TABLE>

        <br/>
       
        <!-- ここは決まり文句  -->
        <f:subview id="submit_bottom">
          <center>
            <%@ include file="呼び出し画面に戻るエクスポート.jsp"%>
          </center>
        </f:subview>

    <h3>
    作業上の注意事項
    </h3>
    <UL>
    <LI> 上記の表示結果に「漏れ」が無いことを「発見者報告者」リストと照合してください</LI>
    <LI> エクセルにエクスポートした後、作業を続けてください</LI>
    </UL>
    <h3>
    使用法
    </h3>
    <p>
      「属性名」をクリックすると、昇順、降順での<STRONG>ソート</STRONG>になる.
      例えば、「野菜か」を第一に、「単価」を第二にして、ソートをしたいときには、先に「単価」をクリックし、その後「野菜か」をクリックしてください。
    <p>
      属性名の右横、番号の左横のボタンをクリックすると<STRONG>チェック</STRONG>されます。
    <p>
      番号をクリックすると<STRONG>チェック</STRONG>されます。

   <p>
     データを クリック、ダブルクリックすると色が付き、目印になります (データをソートしたり、再表示すると、<STRONG>色が消えます</STRONG>)。
    
   <p>
  エクスポートを実行すると、新しい Excel ファイルができる。
 
  <hr>
 
        <H1>
          <center>
            インシデントレポート・ピボットテーブルの確認
          </center>
        </H1>

                    <!--■タイトル表示■-->
                    <span style="color:#121250;font-size:large;font-weight:bold">ピボットテーブル行の属性</span>
                    <!--■注意書き(全角のかっこ).例えば「(複数回答可)」,「(内線番号を記入)」など)-->
                    <span style="color:#121250;font-size:medium;font-weight:bold"></span>
                    <!--■「(必須)」を書く  ・・・  ここでの「必須」は,記入したかのバリデーションのこと.データベースの「非空」制約とは違う■-->
                    <span style="color:#8b0000;font-size:medium;font-weight:bold">(必須)</span>                 
 
                      <%/* ■「checkboxほにゃらら」と,value="#{formdata.ほにゃらら}"を書く■ */%>
                      <!-- layout="spread" にしているので,チェックボックスを作るが表示はされない(2カラム表示を可能にするための工夫) -->
                      <t:selectOneRadio id="radio3" value="#{analyzeForm.ピボットテーブル行の属性}" layout="spread" styleClass="selectOneRadio">
                        <f:selectItems value="#{openDataList.属性アイテムリスト}" />
                      </t:selectOneRadio>
                     
                      <!-- チェックボックスは1カラム(columns="1"), 2カラム(colmuns="2"), 4カラム(colmuns="4")のいずれか.複数カラムにすることがありえるので,panelGrid を使用 -->
                      <!-- 基本は4カラム -->
                      <h:panelGrid columns="4">
                        <%/* ■以下,「for="checkboxほにゃらら"」  部分は,t:selectManyCheckboxの「id="checkほにゃらら"」は一致させること.index は 0 から始まるく■ */%>
                        <t:radio for="radio3" index="0" />
                        <t:radio for="radio3" index="1" />
                        <t:radio for="radio3" index="2" />
                        <t:radio for="radio3" index="3" />
                      </h:panelGrid>        

                    <!--■タイトル表示■-->
                    <span style="color:#121250;font-size:large;font-weight:bold">ピボットテーブル列の属性</span>
                    <!--■注意書き(全角のかっこ).例えば「(複数回答可)」,「(内線番号を記入)」など)-->
                    <span style="color:#121250;font-size:medium;font-weight:bold"></span>
                    <!--■「(必須)」を書く  ・・・  ここでの「必須」は,記入したかのバリデーションのこと.データベースの「非空」制約とは違う■-->
                    <span style="color:#8b0000;font-size:medium;font-weight:bold">(必須)</span>
                   
                      <%/* ■「checkboxほにゃらら」と,value="#{formdata.ほにゃらら}"を書く■ */%>
                      <!-- layout="spread" にしているので,チェックボックスを作るが表示はされない(2カラム表示を可能にするための工夫) -->
                      <t:selectOneRadio id="radio4" value="#{analyzeForm.ピボットテーブル列の属性}" layout="spread" styleClass="selectOneRadio">
                        <f:selectItems value="#{openDataList.属性アイテムリスト}" />
                      </t:selectOneRadio>
                     
                      <!-- チェックボックスは1カラム(columns="1"), 2カラム(colmuns="2"), 4カラム(colmuns="4")のいずれか.複数カラムにすることがありえるので,panelGrid を使用 -->
                      <!-- 基本は4カラム -->
                      <h:panelGrid columns="4">
                        <%/* ■以下,「for="checkboxほにゃらら"」  部分は,t:selectManyCheckboxの「id="checkほにゃらら"」は一致させること.index は 0 から始まるく■ */%>
                        <t:radio for="radio4" index="0" />
                        <t:radio for="radio4" index="1" />
                        <t:radio for="radio4" index="2" />
                        <t:radio for="radio4" index="3" />
                      </h:panelGrid>
            
            <br/>
            <h:commandButton id="button1" value="ピボットテーブルを表示" action="#{action.ピボットテーブルを表示}" />
            <h:outputText escape="false" value="#{openDataList.表示ピボットテーブル}" />
           
            <br/>
            ※ (表示、非表示には関係なく)データの件数を数えます
      </h:form>

   
    </f:view>

 
  </body>

</html>

lookup.JSP

<%@ page contentType="text/html;charset=utf-8" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="https://myfaces.apache.org/tomahawk" prefix="t" %>

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
    <!-- タイトルは,■■画面名■■に応じて,「報告者の情報」のように付けてください  (「a1」などは取る)-->
    <title>インシデントレポート・呼び出し画面</title>
  </head>

  <%@ include file="ラベル設定関数.jsp"%>
 
  <!-- body タグ内のsetLabelの form1, checkbox1 等の部分は,■■form部品に応じて■■書き換えて下さい-->
  <body onLoad="setColor();setLabel('form1:checkbox1','form1:radio1')">
    <f:view>
      <h:form id="form1">
        <!-- value="ほにゃらら" の部分は,value="a1", "a16a" のように、ページIDを付ける -->
        <h:inputHidden value="lookup" binding="#{lookupForm.hiddenInput}"/>
       
        <H1>
          <center>
            インシデントレポート・呼び出し画面
          </center>
        </H1>
       

       
        <TABLE frame="box" border="1" cellspacing="0" cellpadding="0" width="90%" 
               bgcolor="#f0f0f8" bordercolor="#777777">
          <tr>
            <td align="center" bgcolor="#f5f5ff">

             
              <!--○○○レポート番号の範囲 (text1, text2)○○○-->
              <TABLE rules="null" border="0" cellspacing="0" cellpadding="12" width="97%">
                <TR><TD colspan="2" style=" border-bottom:1px dashed #000">
                    <!--■タイトル表示■-->
                    <span style="color:#121250;font-size:large;font-weight:bold">レポート番号の範囲</span>
                    <!--■注意書き(全角のかっこ).例えば「(複数回答可)」,「(内線番号を記入)」など)-->
                    <span style="color:#121250;font-size:medium;font-weight:bold">(半角の数字で記入)</span>
                    <!--■「(必須)」を書く  ・・・  ここでの「必須」は,記入したかのバリデーションのこと.データベースの「非空」制約とは違う■-->
                    <span style="color:#8b0000;font-size:medium;font-weight:bold">(必須)</span>
                </TD></TR>
                <TR><TD width="0%"/><TD width="100%">
                    <span style="color:#121250;font-size:medium;">           
               
   
                      <h:outputLabel for="text1" value="開始レポート番号(必須)"/>
                      <h:inputText id="text1" size="8" value="#{lookupForm.開始レポート番号_必須}"/>
                      <br/>
                      <h:outputLabel for="text2" value="終了レポート番号(必須)"/>
                      <h:inputText id="text2" size="8" value="#{lookupForm.終了レポート番号_必須}"/>
                    </span>           
                </TD></TR>
              </TABLE>
       
   
          </td></tr><tr><td align="center" bgcolor="#f5f5ff">
              <!--○○○表示属性 (checkbox1)○○○-->
              <TABLE rules="null" border="0" cellspacing="0" cellpadding="12" width="97%">
                <TR><TD colspan="2" style=" border-bottom:1px dashed #000">
                    <!--■タイトル表示■-->
                    <span style="color:#121250;font-size:large;font-weight:bold">表示属性</span>
                    <!--■注意書き(全角のかっこ).例えば「(複数回答可)」,「(内線番号を記入)」など)-->
                    <span style="color:#121250;font-size:medium;font-weight:bold">(複数選択可)(表示属性として選ばなかった属性も、簡単に表示できる)</span>
                    <!--■「(必須)」を書く  ・・・  ここでの「必須」は,記入したかのバリデーションのこと.データベースの「非空」制約とは違う■-->
                    <span style="color:#8b0000;font-size:medium;font-weight:bold"></span>
                </TD></TR>
                <TR><TD width="0%"/><TD width="100%">
                    <span style="color:#121250;font-size:medium;">           
                 
 
                      <%/* ■「checkboxほにゃらら」と,value="#{formdata.ほにゃらら}"を書く■ */%>
                      <!-- layout="spread" にしているので,チェックボックスを作るが表示はされない(2カラム表示を可能にするための工夫) -->
                      <t:selectManyCheckbox id="checkbox1" value="#{lookupForm.表示属性名リスト}" layout="spread" styleClass="selectManyCheckbox">
                        <f:selectItems value="#{openDataList.属性アイテムリスト}" />
                      </t:selectManyCheckbox>
                     
                      <!-- チェックボックスは1カラム(columns="1"), 2カラム(colmuns="2"), 4カラム(colmuns="4")のいずれか.複数カラムにすることがありえるので,panelGrid を使用 -->
                      <!-- 基本は4カラム -->
                      <h:panelGrid columns="4">
                        <%/* ■以下,「for="checkboxほにゃらら"」  部分は,t:selectManyCheckboxの「id="checkほにゃらら"」は一致させること.index は 0 から始まるく■ */%>
                        <t:checkbox for="checkbox1" index="0" />
                        <t:checkbox for="checkbox1" index="1" />
                        <t:checkbox for="checkbox1" index="2" />
                        <t:checkbox for="checkbox1" index="3" />
                      </h:panelGrid>
                      <h:commandButton id="button1" value="全ての属性にチェック" action="#{action.全ての属性にチェック}" />
                    </span>           
                </TD></TR>
              </TABLE>

             
          </td></tr><tr><td align="center" bgcolor="#f5f5ff">
              <!--○○○ソート属性と順序 (radio1)○○○-->
              <TABLE rules="null" border="0" cellspacing="0" cellpadding="12" width="97%">
                <TR><TD colspan="2" style=" border-bottom:1px dashed #000">
                    <!--■タイトル表示■-->
                    <span style="color:#121250;font-size:large;font-weight:bold">ソート属性と順序</span>
                    <!--■注意書き(全角のかっこ).例えば「(複数回答可)」,「(内線番号を記入)」など)-->
                    <span style="color:#121250;font-size:medium;font-weight:bold"></span>
                    <!--■「(必須)」を書く  ・・・  ここでの「必須」は,記入したかのバリデーションのこと.データベースの「非空」制約とは違う■-->
                    <span style="color:#8b0000;font-size:medium;font-weight:bold"></span>
                </TD></TR>
                <TR><TD width="0%"/><TD width="100%">
                    <span style="color:#121250;font-size:medium;">           
                 
 
                      <%/* ■「radioほにゃらら」と,value="#{formdata.ほにゃらら}"を書く■ */%>
                      <!-- layout="spread" にしているので,チェックボックスを作るが表示はされない(2カラム表示を可能にするための工夫) -->
                      <t:selectOneRadio id="radio1" value="#{lookupForm.ソート属性と順序}" layout="spread" >
                        <f:selectItem itemValue="レポート番号・昇順(古いものを上に)" itemLabel="レポート番号・昇順(古いものを上に)" />
                        <f:selectItem itemValue="レポート番号・降順(新しいものを上に)" itemLabel="レポート番号・昇順(新しいものを上に)" />
                        <f:selectItem itemValue="商品名・昇順(あいうえお順)" itemLabel="商品名・昇順(あいうえお順)" />
                      </t:selectOneRadio>
                     
                      <!-- ラジオボタンは1カラム(columns="1"), 2カラム(colmuns="2"), 4カラム(colmuns="4")のいずれか.複数カラムにすることがありえるので,panelGrid を使用 -->
                      <!-- 基本は4カラム -->
                      <h:panelGrid columns="1">
                        <%/* ■1カラムのときは,以下のf:vervatimは3つとも取り除く■ */%>
                        <%/* ■以下,「for="radioほにゃらら"」  部分は,t:selectOneRadioの「id="radioほにゃらら"」は一致させること.index は 0 から始まるく■ */%>
                        <t:radio for="radio1" index="0" />
                        <t:radio for="radio1" index="1" />
                        <t:radio for="radio1" index="2" />                    
                      </h:panelGrid>                 
                     
                    </span>           
                </TD></TR>
              </TABLE>
             
            </td>
          </tr>
        </TABLE>
 
       
        <!-- ここは決まり文句  -->
        <f:subview id="submit_bottom">
          <center>
            <%@ include file="この条件で呼び出し集計分析画面に戻る.jsp"%>
          </center>
        </f:subview>

      </h:form>
    </f:view>
   
    <p>
      「この条件で呼び出し」をクリックすると、インシデントレポートを呼び出して、集計分析画面に遷移します。(前回の呼び出し結果は消えます)。
    <p>
      「集計分析画面に戻る」をクリックすると、集計分析画面に遷移し、前回の呼び出し結果を表示す.
  </body>
</html>

この条件で呼び出し集計分析画面に戻る.JSP


<%@ page contentType="text/html;charset=utf-8" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>

<table rules="null" border="0"  cellspacing="8" cellpadding="0" width="100%">
  <tr>
    <td align="right">
      <h:commandButton value="この条件で呼び出し"
                       action="#{action.この条件で呼び出し}"
                       style="width:320px;height:60px;color:#121250;background-color:#ffe6fa;font-size:x-large;"/>
    </td>
    <td align="left">
      <h:commandButton value="集計分析画面に戻る"
                       action="#{action.集計分析画面に戻る}"
                       style="width:320px;height:60px;color:#121250;background-color:#e6e6fa;font-size:x-large;"/>
    </td>
  </tr>
</table>

ラベル設定関数.JSP


<%@ page contentType="text/html;charset=utf-8" %>
<!-- 現在時刻表示関数 ここから-->
<script type="text/javascript">
<!--
function setLabel(){
  var table = document.getElementsByTagName("table");
  for( var argNum=0; argNum<arguments.length; argNum++ ){
    var num = 0;
    for ( var i=0; i<table.length; i++ ){
      if(table[i].id == arguments[argNum]){
        var labels = table[i].getElementsByTagName("label");
        for ( var j=0; j<labels.length; j++ ){
          var inputTag = labels[j].getElementsByTagName("input");
          inputTag[0].setAttribute( "id", arguments[argNum] + ":id" + num );
          labels[j].setAttribute( "for", arguments[argNum] + ":id" + num );
          num++;
        }
      }
    }
  }
  document.body.innerHTML = document.body.parentNode.innerHTML;
}

呼び出し画面に戻るエクスポート.JSP


<%@ page contentType="text/html;charset=utf-8" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>

<table rules="null" border="0"  cellspacing="8" cellpadding="0" width="100%">
  <tr>
    <td align="right">
      <h:commandButton value="この条件で再表示"
                       action="#{action.この条件で再表示}"
                       style="width:320px;height:60px;color:#121250;background-color:#ffe6fa;font-size:x-large;"/>
    </td>
    <td>
      <h:commandButton value="エクスポート"
                       action="#{action.エクスポート}"
                       style="width:200px;height:60px;color:#121250;background-color:#e6e6fa;font-size:x-large;"/>
    </td>
    <td align="left">
      <h:commandButton value="呼び出し画面に戻る"
                       action="#{action.呼び出し画面に戻る}"
                       style="width:280px;height:60px;color:#121250;background-color:#e6e6fa;font-size:x-large;"/>
    </td>
  </tr>
</table>

WEB-INF/faces-config.xml

<?xml version="1.0"?>
<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN" "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
<faces-config>
    <managed-bean>
        <managed-bean-name>lookupForm</managed-bean-name>
        <managed-bean-class>hoge.hoge.com.呼び出し画面フォーム</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>
    <managed-bean>
        <managed-bean-name>analyzeForm</managed-bean-name>
        <managed-bean-class>hoge.hoge.com.集計分析画面フォーム</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>    
    <managed-bean>
        <managed-bean-name>openDataList</managed-bean-name>
        <managed-bean-class>hoge.hoge.com.OpenDataList</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>
    
    <managed-bean>
        <managed-bean-name>tableLogic</managed-bean-name>
        <managed-bean-class>hoge.hoge.com.表示テーブルビジネスロジック</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>
    
    <managed-bean>
        <managed-bean-name>action</managed-bean-name>
        <managed-bean-class>hoge.hoge.com.アクション</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
        <managed-property>
              <property-name>lookupForm</property-name>
              <property-class>hoge.hoge.com.呼び出し画面フォーム</property-class>
              <value>#{lookupForm}</value>
           </managed-property>
           <managed-property>
              <property-name>analyzeForm</property-name>
              <property-class>hoge.hoge.com.集計分析画面フォーム</property-class>
              <value>#{analyzeForm}</value>
           </managed-property>
           <managed-property>
              <property-name>openDataList</property-name>
              <property-class>hoge.hoge.com.OpenDataList</property-class>
              <value>#{openDataList}</value>
           </managed-property>
           <managed-property>
              <property-name>tableLogic</property-name>
              <property-class>hoge.hoge.com.表示テーブルビジネスロジック</property-class>
              <value>#{tableLogic}</value>
           </managed-property>        
    </managed-bean>
    
<navigation-rule>
    <from-view-id>*</from-view-id>
    <navigation-case>
        <from-outcome>lookup</from-outcome>
        <to-view-id>/lookup.jsp</to-view-id>
    </navigation-case>
    <navigation-case>
        <from-outcome>analyze</from-outcome>
        <to-view-id>/analyze.jsp</to-view-id>
    </navigation-case>
</navigation-rule>
</faces-config>

WEB-INF/web.xml

Java Server Faces サンプルプログラムの Web ページ に記載の web.xml を使用