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