    001/*
    002 * Copyright (c) 2009 The openGion Project.
    003 *
    004 * Licensed under the Apache License, Version 2.0 (the "License");
    005 * you may not use this file except in compliance with the License.
    006 * You may obtain a copy of the License at
    007 *
    008 *     http://www.apache.org/licenses/LICENSE-2.0
    009 *
    010 * Unless required by applicable law or agreed to in writing, software
    011 * distributed under the License is distributed on an "AS IS" BASIS,
    012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
    013 * either express or implied. See the License for the specific language
    014 * governing permissions and limitations under the License.
    015 */
    016package org.opengion.hayabusa.report;
    017
    018import org.opengion.hayabusa.common.HybsSystem;
    019import org.opengion.hayabusa.common.HybsSystemException;
    020import org.opengion.fukurou.util.LogWriter;
    021import org.opengion.hayabusa.db.DBTableModel;
    022import org.opengion.hayabusa.db.DBColumn;
    023import org.opengion.hayabusa.resource.ResourceManager;
    024import org.opengion.fukurou.util.StringUtil;
    025import org.opengion.fukurou.util.FileUtil;
    026import org.opengion.fukurou.util.Closer ;
    027
    028import java.io.File;
    029import java.io.BufferedReader;
    030import java.io.PrintWriter;
    031
    032/**
    033 * DBTableReport インターフェース のデフォルト実装クラスです。
    034 * writeReport() を、オーバーライドすれば，各種出力フォーマットに合わせた
    035 * サブクラスを実現する事が可能です。
    036 *
    037 * @og.group 帳票システム
    038 *
    039 * @version  4.0
    040 * @author       Kazuhiko Hasegawa
    041 * @since    JDK5.0,
    042 */
    043public abstract class AbstractDBTableReport implements DBTableReport {
    044        private static final String ENCODE = HybsSystem.REPORT_ENCODE ;
    045
    046        protected String[]              headerKeys      = null;         // 固定部の key 部分を指定する。カンマで複数指定できる。
    047        protected String[]              headerVals      = null;         // 固定部の key に対応する値を指定する。
    048        protected String[]              footerKeys      = null;         // 繰り返し部の終了後に表示する key 部分を指定する。カンマで複数指定できる。
    049        protected String[]              footerVals      = null;         // 繰り返し部の終了後に表示する key に対する値を指定する。
    050        protected boolean               pageEndCut      = false;        // ボディー部(繰り返し部)がなくなったときに、それ以降のページを出力するか指定する。
    051        protected int                   maxRowCount     = 0;            // 自動計算方式を採用
    052        protected int                   pageRowCount    = 0;    // 過去のページの最大件数。 3.7.0.1 (2005/01/31)
    053        protected int                   lineCopyCnt     = 0;            // LINE_COPY した際の加算行番号。 4.0.0 (2007/06/08)
    054        protected ResourceManager resource  = null;             // 4.0.0 (2005/01/31)
    055        protected PrintWriter   writer          = null;
    056        protected BufferedReader reader         = null;
    057        protected File                  templateFile            = null;         // 3.8.0.0 (2005/06/07)
    058        protected File                  firstTemplateFile       = null;         // 3.8.0.0 (2005/06/07)
    059        protected String                htmlDir         = null;
    060        protected String                htmlFileKey     = null;
    061        protected String                ykno            = null;         // 3.8.5.1 (2006/04/28) 追加
    062        protected DBTableModel  table           = null;
    063
    064        protected int                   pageCount       = 0;
    065        protected int                   maxPageCount = 1000;
    066        protected boolean               rowOver         = false;        // データ件数分のカラムを要求されると、true にセットされる。
    067        protected boolean               dataOver        = false;        // 3.8.1.2 (2005/12/19) データがなくなると、true にセットされる。
    068
    069        // 3.6.0.0 (2004/09/24) フォーマットエラーの判定(formatErr)を、子クラスから移動します。
    070        private boolean  formatErr      = false;                // フォーマットエラーの判定
    071
    072        // 3.6.1.0 (2005/01/05) 帳票ＩＤ追加
    073        protected String                listId          = null;
    074
    075        // 3.7.0.1 (2005/01/31) ページブレイク時の処理
    076        private static final String PAGEBREAK = "PAGEBREAK";
    077        private int                             pbClmNo         = -1;           // PAGEBREAK カラムの番号
    078        private boolean                 pageBreak       = false;        // PAGEBREAK = "1" が見つかった時、true
    079        private int                             tableSize       = 0;
    080
    081        /**
    082         * DBTableModel から データを作成して,PrintWriter に書き出します。
    083         *
    084         */
    085        public void writeReport() {
    086                setHeaderFooter();
    087                initReader();
    088                initWriter();
    089                String str ;
    090                while( (str = readLine()) != null ) {
    091                        println( changeData( str ) );
    092                }
    093                close();
    094        }
    095
    096        /**
    097         * 入力文字列 を読み取って、出力します。
    098         * tr タグを目印に、１行(trタグ間)ずつ取り出します。
    099         * 読み取りを終了する場合は、null を返します。
    100         * 各サブクラスで実装してください。
    101         *
    102         * @return      出力文字列
    103         */
    104        abstract protected String readLine() ;
    105
    106        /**
    107         * 入力文字列 を加工して、出力します。
    108         * {&#064;XXXX} をテーブルモデルより読み取り、値をセットします。
    109         * 各サブクラスで実装してください。
    110         *
    111         * @param       inLine  入力文字列
    112         *
    113         * @return      出力文字列
    114         */
    115        abstract protected String changeData( final String inLine ) ;
    116
    117        /**
    118         * 入力文字列 を読み取って、出力します。
    119         * 各サブクラスで実装してください。
    120         *
    121         * @param line 出力文字列
    122         */
    123        abstract protected void println( final String line ) ;
    124
    125        /**
    126         * リソースマネージャーをセットします。
    127         * これは、言語(ロケール)に応じた DBColumn をあらかじめ設定しておく為に
    128         * 必要です。
    129         * リソースマネージャーが設定されていない、または、所定のキーの DBColumn が
    130         * リソースに存在しない場合は、内部で DBColumn オブジェクトを作成します。
    131         *
    132         * @og.rev 4.0.0.0 (2005/01/31) lang ⇒ ResourceManager へ変更
    133         *
    134         * @param  resource リソースマネージャー
    135         */
    136        public void setResourceManager( final ResourceManager resource ) {
    137                this.resource = resource;
    138        }
    139
    140        /**
    141         * 帳票ＩＤ をセットします。
    142         * この帳票ＩＤを利用して、画像ファイル等のセーブディレクトリを求めます。
    143         *
    144         * @og.rev 3.6.1.0 (2005/01/05) 新規作成
    145         *
    146         * @param   listId 帳票ＩＤ
    147         */
    148        public void setListId( final String listId ) {
    149                this.listId = listId ;
    150        }
    151
    152        /**
    153         * DBTableModel をセットします。
    154         *
    155         * @og.rev 3.7.0.1 (2005/01/31) ページブレイク時の処理
    156         *
    157         * @param       table   DBTableModelオブジェクト
    158         */
    159        public void setDBTableModel( final DBTableModel table ) {
    160                this.table = table;
    161                // 3.7.0.1 (2005/01/31) ページブレイク時の処理
    162                tableSize = table.getRowCount();
    163                pbClmNo   = table.getColumnNo( PAGEBREAK,false );               // 存在しない場合は、-1
    164
    165//              try {
    166//                      pbClmNo = table.getColumnNo( PAGEBREAK );
    167//              }
    168//              catch( HybsSystemException e ) {
    169//                      pbClmNo = -1;
    170//              }
    171        }
    172
    173        /**
    174         * 雛型ファイル名をセットします。
    175         *
    176         * @og.rev 3.6.0.0 (2004/09/17) メソッド名の変更。setInputFile ⇒ setTemplateFile
    177         * @og.rev 3.8.0.0 (2005/06/07) 引数を String  ⇒ File に変更
    178         *
    179         * @param   inFile 雛型ファイル名
    180         */
    181        public void setTemplateFile( final File inFile ) {
    182                templateFile = inFile;
    183        }
    184
    185        /**
    186         * 最初のページのみに使用する雛型ファイル名をセットします。
    187         *
    188         * @og.rev 3.6.0.0 (2004/09/17) 新規追加
    189         * @og.rev 3.8.0.0 (2005/06/07) 引数を String  ⇒ File に変更
    190         *
    191         * @param   inFile 最初のページの雛型ファイル名
    192         */
    193        public void setFirstTemplateFile( final File inFile ) {
    194                firstTemplateFile = inFile;
    195        }
    196
    197        /**
    198         * 変換後ファイルを出力するディレクトリ名をセットします。
    199         * ディレクトリが存在しない場合は、新規に作成します。
    200         *
    201         * @og.rev 3.7.1.1 (2005/05/23) フォルダがない場合は、複数階層分のフォルダを自動で作成します。
    202         *
    203         * @param   outDir 出力ディレクトリ
    204         */
    205        public void setOutputDir( final String outDir ) {
    206                htmlDir = outDir;
    207
    208                File dir = new File(htmlDir);
    209                if( ! dir.exists() && ! dir.mkdirs() ) {
    210                        String errMsg = "ディレクトリの作成に失敗しました。[" + htmlDir + "]";
    211                        throw new HybsSystemException( errMsg );
    212                }
    213        }
    214
    215        /**
    216         * 変換後ファイルキーをセットします。
    217         * キーとは、拡張子の無い状態までのファイル名です。
    218         * 変換後ファイルは、複数発生します。
    219         * 実際に出力されるファイル名は、outFile + "_連番.html" となります。
    220         *
    221         * @param   outFile 出力ファイル名の共通部
    222         */
    223        public void setOutputFileKey( final String outFile ) {
    224                htmlFileKey = outFile;
    225        }
    226
    227        /**
    228         * 帳票起動された要求番号をセットします。
    229         *
    230         * @og.rev 3.8.5.1 (2006/04/28) 新規追加
    231         *
    232         * @param   ykno 要求番号
    233         */
    234        public void setYkno( final String ykno ) {
    235                this.ykno = ykno;
    236        }
    237
    238        /**
    239         * 固定部の key 部分を指定します。
    240         * カンマで複数指定できます。
    241         *
    242         * @og.rev 3.5.6.0 (2004/06/18) 配列の設定は、arraycopy して取り込みます。
    243         *
    244         * @param   hKeys 固定部のキー
    245         */
    246        public void setHeaderKeys( final String[] hKeys ) {
    247                if( hKeys != null ) {
    248                        int size = hKeys.length ;
    249                        headerKeys = new String[size];
    250                        System.arraycopy( hKeys,0,headerKeys,0,size );
    251                }
    252                else {
    253                        headerKeys = null;
    254                }
    255        }
    256
    257        /**
    258         * 固定部のkey に対応する値を指定します。
    259         * カンマで複数指定で、リクエスト情報でも設定できます。
    260         *
    261         * @og.rev 3.5.6.0 (2004/06/18) 配列の設定は、arraycopy して取り込みます。
    262         *
    263         * @param   hVals 固定部の値
    264         */
    265        public void setHeaderVals( final String[] hVals ) {
    266                if( hVals != null ) {
    267                        int size = hVals.length ;
    268                        headerVals = new String[size];
    269                        System.arraycopy( hVals,0,headerVals,0,size );
    270                }
    271                else {
    272                        headerVals = null;
    273                }
    274        }
    275
    276        /**
    277         * 雛型帳票に対する、実際の行番号を求めます。
    278         * これは、雛型の複数回読みをサポートする為、実際の雛型のrow番号と
    279         * DBTableModel から取得すべき row番号が、異なる為です。
    280         * オーバーフロー時は、Exception を避ける為、-1 を返します。
    281         *
    282         * @og.rev 3.5.6.0 (2004/06/18) noDataflag の追加。
    283         * @og.rev 3.5.6.3 (2004/07/12) noDataflag の廃止。
    284         * @og.rev 3.6.0.4 (2004/10/14) FIRST 雛型時の対応追加。
    285         * @og.rev 3.7.0.1 (2005/01/31) ページブレイク処理に対応。
    286         * @og.rev 3.8.1.2 (2005/12/19) PAGE_END_CUT用にdataOverフラグを追加
    287         *
    288         * @param       row 固定部の値(オーバーフロー時は、-1 )
    289         *
    290         * @return      実際の行番号
    291         */
    292        protected int getRealRow( final int row ) {
    293
    294                // 3.7.0.1 (2005/01/31) ページブレイク処理に対応。
    295                int realRow = pageRowCount + row + lineCopyCnt ;
    296                if( maxRowCount <= realRow ) { maxRowCount = realRow + 1; }
    297
    298                if( realRow >= (tableSize-1) ) {                     // 行番号が最大値と同じ(データは存在)
    299                        rowOver = true;
    300                        if( realRow >= tableSize ) { // さらに、データは存在しない。
    301                                realRow = -1;           // 3.5.6.3 (2004/07/12) オーバーフロー
    302                                dataOver = true;        // 3.8.1.2 (2005/12/19)
    303                        }
    304                }
    305
    306                return realRow ;
    307        }
    308
    309        /**
    310         * 指定のキーについて、その値を取得します。
    311         * 値の取得方法として、
    312         * 　　{&#064;xxx_no} 形式の場合は、DBTableModel から、
    313         * 　　{&#064;XXXX} 形式で、かつ、rowOver が false の場合は、ヘッダーから、
    314         * 　　{&#064;XXXX} 形式で、かつ、rowOver が true の場合は、フッターから、
    315         * 取得します。
    316         * rowOver は、{&#064;xxx_no} 形式の番号欄(no)が、DBTableModel のデータ件数よりも
    317         * 大きい場合に、セットされます。
    318         *
    319         * @og.rev 3.5.6.0 (2004/06/18) noDataflag の追加。
    320         * @og.rev 3.5.6.3 (2004/07/12) noDataflag の廃止。
    321         * @og.rev 3.6.0.0 (2004/09/24) フォーマットエラーの判定(formatErr)を、子クラスから移動します。
    322         * @og.rev 3.7.0.1 (2005/01/31) ページブレイク時の処理追加。
    323         * @og.rev 3.7.0.2 (2005/02/18) HTML のエスケープ文字対応
    324         * @og.rev 3.7.1.1 (2005/05/09) セル内の改行 <br> は、エスケープしない。
    325         * @og.rev 3.8.0.0 (2005/06/07) Shift-JIS で中国語を扱う。(Unicodeエスケープ文字は、エスケープしない)
    326         * @og.rev 3.8.5.1 (2006/04/28) YKNO を特別扱いする。
    327         *
    328         * @param   key 指定のキー
    329         *
    330         * @return  指定のキーの値
    331         */
    332        protected String getValue( final String key ) {
    333                if( pageBreak ) { return ""; }          // 3.7.0.1 (2005/01/31) ページブレイク時の処理
    334
    335                int sp = key.lastIndexOf( '_' );
    336                if( sp >= 0 ) {
    337                        try {
    338                                int row = Integer.parseInt( key.substring( sp+1 ) );
    339                                int realRow = getRealRow( row );
    340
    341                                if( realRow >= 0 ) { // 3.5.6.3 (2004/07/12)
    342                                        formatErr = false;      // 3.6.0.0 (2004/09/24)
    343                                        int col = table.getColumnNo( key.substring( 0,sp ),false );
    344                                        if( col < 0 ) {
    345                                                // 超暫定対策：I 変数で、行番号を出力する。
    346                                                if( "I".equals( key.substring( 0,sp ) ) ) {
    347                                                        return String.valueOf( realRow+1 );             // 行番号は物理行＋１
    348                                                }
    349                                                else {
    350                                                        String errMsg = "カラム名が存在しません:[" + key + "]" ;
    351                                                        System.out.println( errMsg );
    352                                                        LogWriter.log( errMsg );
    353                                                        return "" ;
    354                                                }
    355                                        }
    356
    357                                        String val = table.getValue( realRow,col );
    358
    359                                        // 3.7.0.1 (2005/01/31) ページブレイク時の処理追加
    360                                        if( pbClmNo == col ) {
    361                                                if( ! rowOver ) {
    362                                                        String val2 = table.getValue( realRow+1,pbClmNo );      // 先読み
    363                                                        if( val != null && ! val.equals( val2 ) ) {
    364                                                                pageBreak = true;
    365                                                        }
    366                                                }
    367                                                return "";      // ページブレイクカラムは、すべて""に変換する。
    368                                        }
    369                                        // 3.7.1.1 (2005/05/09) セル内の改行 <br> は、エスケープしない。
    370                                        val = StringUtil.htmlFilter( val );
    371                                        val = StringUtil.replace( val,"&lt;br&gt;","<br>" );
    372                                        // 3.8.0.0 (2005/06/07) Shift-JIS で中国語を扱う。(Unicodeエスケープ文字は、エスケープしない)
    373                                        val = StringUtil.replace( val,"&amp;#","&#" );  // 中国語変換対応 &amp;# は変換しない
    374                                        return table.getDBColumn( col ).getRendererValue( val );
    375                                }
    376                        }
    377                        catch ( NumberFormatException ex ) {    // 4.0.0 (2005/01/31)
    378                                String errMsg = "警告：ヘッダーに'_'カラム名が使用  "
    379                                                        + "key=[" + key + "]  "
    380                                                        + ex.getMessage() ;
    381                                LogWriter.log( errMsg );
    382                                // フォーマットエラーは、何もしない。
    383                                // 通常のカラム名にアンダーバーが使用されている可能性があるため。
    384                        }
    385                        catch ( RuntimeException ex ) {
    386                                String errMsg = "カラムデータ取得処理で、エラーが発生しました。  "
    387                                                        + "key=[" + key + "]  "
    388                                                        + ex.getMessage() ;
    389                                LogWriter.log( errMsg );
    390                                // フォーマットエラーは、何もしない。
    391                        }
    392                }
    393
    394                // 3.8.5.1 (2006/04/28) YKNO を特別扱いする。
    395                if( "YKNO".equals( key ) ) { return ykno; }
    396
    397                String rtnVal ;
    398                if( rowOver ) { rtnVal = getFooterValue( key ); }
    399                else          { rtnVal = getHeaderValue( key ); }
    400
    401                if( rtnVal == null ) { rtnVal = ""; }
    402                return rtnVal ;
    403        }
    404
    405        /**
    406         * 固定部のkey に対応する値を取得します。
    407         *
    408         * @param   key String
    409         *
    410         * @return   固定部の値
    411         */
    412        private String getHeaderValue( final String key ) {
    413                if( headerKeys == null ||
    414                        headerVals == null ||
    415                        key        == null ) { return null; }
    416
    417                for( int i=0; i<headerKeys.length; i++ ) {
    418                        if( key.equals( headerKeys[i] ) ) { return headerVals[i]; }
    419                }
    420                return null;
    421        }
    422
    423        /**
    424         * 繰り返し部の終了後に表示する key 部分を指定します。
    425         * カンマで複数指定できます。
    426         *
    427         * @og.rev 3.5.6.0 (2004/06/18) 配列の設定は、arraycopy して取り込みます。
    428         *
    429         * @param   fKeys 繰り返し部の終了後に表示する key
    430         */
    431        public void setFooterKeys( final String[] fKeys ) {
    432                if( fKeys != null ) {
    433                        int size = fKeys.length ;
    434                        footerKeys = new String[size];
    435                        System.arraycopy( fKeys,0,footerKeys,0,size );
    436                }
    437                else {
    438                        footerKeys = null;
    439                }
    440        }
    441
    442        /**
    443         * 繰り返し部の終了後に表示する key 部分を取得します。
    444         *
    445         * @param   key String
    446         *
    447         * @return   繰り返し部の終了後に表示する key
    448         */
    449        private String getFooterValue( final String key ) {
    450                if( footerKeys == null ||
    451                        footerVals == null ||
    452                        key        == null ) { return null; }
    453
    454                for( int i=0; i<footerKeys.length; i++ ) {
    455                        if( key.equals( footerKeys[i] ) ) { return footerVals[i]; }
    456                }
    457                return null;
    458        }
    459
    460        /**
    461         * 固定部のkey に対応する値を指定します。
    462         * カンマで複数指定で、リクエスト情報でも設定できます。
    463         *
    464         * @og.rev 3.5.6.0 (2004/06/18) 配列の設定は、arraycopy して取り込みます。
    465         *
    466         * @param   fVals 繰り返し部の終了後に表示する値
    467         */
    468        public void setFooterVals( final String[] fVals ) {
    469                if( fVals != null ) {
    470                        int size = fVals.length ;
    471                        footerVals = new String[size];
    472                        System.arraycopy( fVals,0,footerVals,0,size );
    473                }
    474                else {
    475                        footerVals = null;
    476                }
    477        }
    478
    479        /**
    480         * ボディー部(繰り返し部)がなくなったときに、それ以降を表示するかどうかを指定します。
    481         * true では、それ以降を出力しません。
    482         * デフォルト "true" (なくなった時点で、出力しない。)です。
    483         *
    484         * @param   pageEndCut 繰り返し部の終了後に継続処理するかどうか (true:処理しない/false:処理する)
    485         */
    486        public void setPageEndCut( final boolean pageEndCut ) {
    487                this.pageEndCut = pageEndCut ;
    488        }
    489
    490        /**
    491         * BufferedReader を、初期化します。
    492         * これは、雛型ファイルの終端まで読取り、処理した場合、もう一度
    493         * 初めから読み込みなおす処理を行います。
    494         * 基本的に、書き込みも初期化する必要があります。
    495         *
    496         * メモリ上に読み込んで、繰り返し利用するかどうかは、実装依存です。
    497         *
    498         * @og.rev 3.1.3.0 (2003/04/10) "DEFAULT" エンコーディング名のサポートを廃止。
    499         * @og.rev 3.5.5.9 (2004/06/07) FileUtil.getBufferedReader を使用
    500         * @og.rev 3.6.0.0 (2004/09/17) 最初のページのみに使用する雛型ファイル名を追加します。
    501         * @og.rev 3.6.0.0 (2004/09/24) フォーマットエラーの判定(formatErr)を、子クラスから移動します。
    502         *
    503         */
    504        protected void initReader() {
    505                Closer.ioClose( reader );               // 4.0.0 (2006/01/31) close 処理時の IOException を無視
    506
    507                if( reader == null && firstTemplateFile != null ) {
    508                        reader = FileUtil.getBufferedReader(firstTemplateFile,ENCODE);
    509                }
    510                else {
    511                        if( formatErr ) {
    512                                String errMsg = "Error in HTML File. " + HybsSystem.CR
    513                                                                + "Excel containing two or more sheets is not supporting."
    514                                                                + HybsSystem.CR
    515                                                                + "or HTML template File is not in '{@xxxx_0}' key word." ;
    516                                throw new HybsSystemException( errMsg );
    517                        }
    518                        reader = FileUtil.getBufferedReader(templateFile,ENCODE);
    519                        formatErr = true;               // 初期化します。クリアしなければエラー
    520                }
    521        }
    522
    523        /**
    524         * PrintWriter を、初期化します。
    525         * これは、雛型ファイルを終端まで読取り、処理した場合、出力ファイル名を
    526         * 変えて、別ファイルとして出力する為のものです。
    527         * 基本的に、読取も初期化する必要があります。
    528         *
    529         * メモリ上に読み込んで、繰り返し利用するかどうかは、実装依存です。
    530         *
    531         * @og.rev 3.0.0.1 (2003/02/14) ページの最大ページ数の制限を追加。暴走停止用
    532         * @og.rev 3.1.3.0 (2003/04/10) "DEFAULT" エンコーディング名のサポートを廃止。
    533         * @og.rev 3.5.5.9 (2004/06/07) FileUtil.getPrintWriter メソッドを使用
    534         * @og.rev 3.7.0.1 (2005/01/31) ページブレイク処理に対応。
    535         * @og.rev 3.8.0.0 (2005/06/07) FileUtil#getPrintWriter を利用。
    536         * @og.rev 3.8.5.3 (2006/06/30) EXCEL最大シート数のエラーメッセージを変更。
    537         *
    538         */
    539        protected void initWriter() {
    540                if( writer != null ) {
    541                        writer.flush();
    542                        writer.close();
    543                        writer = null;
    544                        pageCount++ ;
    545                        if( pageCount >= maxPageCount ) {
    546                                String errMsg = "EXCELのページ(シート)が最大ページ数(1000)をオーバーしました。"
    547                                                                + HybsSystem.CR
    548                                                                + "この数は、DB_MAX_ROW_COUNT ではなく、LISTID_999.htmlのオーバーを意味します。"
    549                                                                + HybsSystem.CR;
    550                                throw new HybsSystemException( errMsg );
    551                        }
    552                }
    553
    554                int pgCnt = pageCount + 1000;           // 桁合わせの為、下３桁を利用します。
    555
    556                String subName = String.valueOf( pgCnt ).substring( 1 );
    557                String filename = htmlFileKey + "_" + subName + ".html" ;
    558
    559                // 3.8.0.0 (2005/06/07) FileUtil#getPrintWriter を利用。
    560                writer = FileUtil.getPrintWriter( new File( htmlDir,filename ),ENCODE );
    561
    562                // 3.7.0.1 (2005/01/31) ページブレイク時の処理
    563                pageRowCount = maxRowCount ;    // そのページの頭のデータ行数をセット
    564                pageBreak    = false;                   // pageBreak フラグを元に戻す。
    565        }
    566
    567        /**
    568         * ヘッダーフッターのレンデラーデータを設定します。
    569         * カンマで複数指定で、リクエスト情報でも設定できます。
    570         *
    571         */
    572        protected void setHeaderFooter() {
    573
    574                DBColumn clm ;
    575                if( headerKeys != null ) {
    576                        for( int i=0; i<headerKeys.length; i++ ) {
    577                                clm = resource.getDBColumn( headerKeys[i] );
    578                                if( clm != null ) {
    579                                        headerVals[i] = clm.getRendererValue( headerVals[i] );
    580                                }
    581                        }
    582                }
    583
    584                if( footerKeys != null ) {
    585                        for( int i=0; i<footerKeys.length; i++ ) {
    586                                clm = resource.getDBColumn( footerKeys[i] );
    587                                if( clm != null ) {
    588                                        footerVals[i] = clm.getRendererValue( footerVals[i] );
    589                                }
    590                        }
    591                }
    592        }
    593
    594        /**
    595         * リーダー、ライターの終了処理を行います。
    596         *
    597         */
    598        private void close() {
    599                if( writer != null ) {
    600                        writer.flush();
    601                        writer.close();
    602                        writer = null;
    603                }
    604                Closer.ioClose( reader );               // 4.0.0 (2006/01/31) close 処理時の IOException を無視
    605                reader = null;
    606        }
    607}