    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.plugin.io;
    017
    018// import java.io.File;
    019// import java.io.FileInputStream;
    020// import java.io.FileOutputStream;
    021// import java.io.IOException;
    022import java.io.PrintWriter;
    023// import java.util.Locale;
    024
    025// import org.apache.poi.ss.usermodel.Cell;
    026// import org.apache.poi.ss.usermodel.CreationHelper;
    027// import org.apache.poi.ss.usermodel.Font;
    028// import org.apache.poi.ss.usermodel.RichTextString;
    029// import org.apache.poi.ss.usermodel.Row;
    030// import org.apache.poi.ss.usermodel.Sheet;
    031// import org.apache.poi.ss.usermodel.Workbook;
    032// import org.apache.poi.ss.usermodel.WorkbookFactory;
    033
    034import org.opengion.fukurou.model.NativeType;
    035import org.opengion.fukurou.util.Closer;
    036import org.opengion.fukurou.util.StringUtil;
    037import org.opengion.hayabusa.common.HybsSystem;
    038import org.opengion.hayabusa.common.HybsSystemException;
    039import org.opengion.hayabusa.db.DBTableModel;
    040
    041import org.opengion.fukurou.model.ExcelModel;
    042
    043/**
    044 * ネイティブEXCELファイルの書き出しクラスです。
    045 *
    046 * DefaultTableWriter を継承していますので，ラベル，名前，データの出力部のみ
    047 * オーバーライドして，MIcrosoft Excelファイルの出力機能を実現しています。
    048 *
    049 * 出力形式は、openXML形式にも対応しています。
    050 * 出力ファイルの拡張子が、.xlsならExcel2003のバイナリ形式、.xlsxならExcel2007の
    051 * openXML形式で出力されます。
    052 *
    053 * @og.group ファイル出力
    054 *
    055 * @og.rev 4.3.4.3 (2008/12/22) 一部protected化
    056 * @og.rev 4.3.6.7 (2009/05/22) ooxml形式対応
    057 * @og.rev 6.0.1.2 (2014/08/08) ロジックの完全書き換え(保証もできない位･･･)
    058 *
    059 * @version  4.0
    060 * @author       Kazuhiko Hasegawa
    061 * @since    JDK5.0,
    062 */
    063public class TableWriter_Excel extends TableWriter_Default {
    064        //* このプログラムのVERSION文字列を設定します。   {@value} */
    065        private static final String VERSION = "6.0.1.2 (2014/08/08)" ;
    066
    067//      private Sheet   sheet                   = null;
    068        private int             nRowIndex               = 0;                            // 6.0.1.2 (2014/08/08) private化
    069        private String  filename                = null;                         // 3.5.4.3 (2004/01/05)
    070        private String  sheetName               = "Sheet1";                     // 3.5.4.3 (2004/01/05)
    071        private String  fontName                = null;                         // 3.8.5.3 (2006/08/07)
    072        private short   fontPoint               = -1;                           // 3.8.5.3 (2006/08/07)
    073        private String  refFilename             = null;                         // 3.5.4.3 (2004/01/05)
    074        private String  refSheetName    = null;                         // 3.5.4.3 (2004/01/05)
    075//      private CreationHelper createHelper     = null;                 // poi.xssf対応
    076        // 5.1.4.0 (2010/03/01) 行番号情報を、出力する(true)/しない(false)を指定
    077        private boolean         useNumber       = true;
    078        private int             skipRowCount    = 0;                            // 6.0.1.2 (2014/08/08) データの書き込み開始位置設定
    079
    080        private ExcelModel excel                = null;                         // 6.0.2.0 (2014/08/29) 新規作成
    081
    082        /**
    083         * DBTableModel から 各形式のデータを作成して,PrintWriter に書き出します。
    084         * このメソッドは、EXCEL 書き出し時に使用します。
    085         *
    086         * 雛形シートを使う場合は、雛形シートの後ろに追加していきます。
    087         * 最後には、雛形シートとして存在しな部分は、すべて削除します。
    088         * 雛形シートを使わない場合は、新規シートに追加していくことになります。
    089         * appendモードの場合は、オリジナルが雛形ファイルになります。
    090         * 雛形ファイルの指定は、無効になります。
    091         *
    092         * @og.rev 4.0.0.0 (2006/09/31) 新規追加
    093         * @og.rev 5.1.4.0 (2010/03/01) columns 対応 、useNumber属性対応
    094         * @og.rev 6.0.1.2 (2014/08/08) ロジックの完全書き換え(保証もできない位･･･)
    095         *
    096         * @see #isExcel()
    097         */
    098        @Override
    099        public void writeDBTable() {
    100//              if( ! createDBColumn() ) { return ; }           // 親クラスで実行
    101
    102                useNumber = isUseNumber();
    103
    104                // 3.5.6.0 (2004/06/18) 移動
    105                if( filename == null ) {
    106                        String errMsg = "ファイルが指定されていません。";
    107                        throw new HybsSystemException(errMsg );
    108                }
    109
    110                // appendモードの場合は、オリジナルが雛形ファイルになります。
    111                // 雛形ファイルの指定は、無効になります。
    112                if( isAppend() ) {
    113                        // 互換性のため、雛形ファイルが出力ファイルと同じでない場合はエラーとします。
    114                        if( refFilename != null && !filename.equalsIgnoreCase( refFilename ) ) {
    115                                String errMsg = "追加(appendモード)の時、雛形ファイルの指定は無効です。" + HybsSystem.CR
    116                                                                + " filename=[" + filename + "] , refFilename=[" + refFilename + "]"  + HybsSystem.CR ;
    117                                throw new HybsSystemException( errMsg );
    118                        }
    119
    120                        refFilename = filename ;
    121                }
    122
    123                // 雛形があれば、雛形ファイルを読み込みます。なければ、オリジナルのファイルを読み込みます。
    124                String  nameUse = filename;
    125                boolean isRefFile = refFilename != null && refFilename.length() > 0;
    126                if( isRefFile ) {
    127                        nameUse = refFilename ;
    128                }
    129
    130                // 既存の場合は、WorkbookFactoryで作成。新規の場合は、拡張子(.xlsx/.xls)に応じて、作成する。
    131//              Workbook wb = createWorkbook( nameUse , isRefFile );
    132                excel = new ExcelModel( nameUse , isRefFile );
    133
    134                // 雛形ファイルのシート数。最後にこの分は削除します。
    135//              int refCnt = isRefFile ? wb.getNumberOfSheets() : 0 ;
    136                int refCnt = isRefFile ? excel.getNumberOfSheets() : 0 ;
    137
    138                // appendモードの場合は、オリジナルが雛形ファイルになるため、雛形シートの削除は行いません。
    139                if( isAppend() ) { refCnt = 0; }
    140
    141                // 雛形シートを使う場合
    142                if( isRefFile ) {
    143                        excel.setFont( fontName,fontPoint );
    144                }
    145                excel.createSheet( refSheetName,isRefFile );
    146
    147                // 雛形シートを使う場合
    148//              if( isRefFile ) {
    149//                      int refSheetIdx = 0;            // 雛形シート名の指定がない場合は、最初のシート
    150//                      if( refSheetName != null ) { refSheetIdx = wb.getSheetIndex(refSheetName); }
    151//
    152//                      if( refSheetIdx < 0 ) {         // 雛形シート名が存在しなかった。
    153//                              String errMsg = "指定の雛形シート名は、雛型ファイルに存在しませんでした。" + HybsSystem.CR
    154//                                                              + " refFilename=[" + refFilename + "] , refSheetName=[" + refSheetName + "]"  + HybsSystem.CR ;
    155//                              throw new HybsSystemException( errMsg );
    156//                      }
    157//
    158//                      sheet = wb.cloneSheet( refSheetIdx );
    159//              }
    160//              else {
    161//                      // 3.8.6.0 (2006/08/07) フォント名やフォントサイズの指定
    162//                      // 雛形ファイルを使用しない場合のみ、設定可能です。
    163//                      Font font = wb.getFontAt((short)0);
    164//                      if( fontName != null ) {
    165//                              font.setFontName( fontName );   // "ＭＳ Ｐゴシック" など
    166//                      }
    167//                      if( fontPoint > 0 ) {
    168//                              font.setFontHeightInPoints( fontPoint );
    169//                      }
    170//
    171//                      sheet = wb.createSheet();
    172//              }
    173
    174                // シート名のセット。重複チェックと新しいシート名の作成処理を行う。
    175//              wb.setSheetName(wb.getNumberOfSheets() -1, getNewSheetNameByName(wb, sheetName) );
    176                excel.setLastSheetName( sheetName );
    177
    178                // poi.xssf対応(2009/04/08)
    179//              createHelper = wb.getCreationHelper();
    180
    181                nRowIndex = skipRowCount;               // 6.0.1.2 (2014/08/08) 開始行の指定
    182
    183                super.writeDBTable( null );
    184
    185                // 指定以降の余計な行を削除
    186//              removeSheetRow( sheet, nRowIndex );
    187                excel.removeRow( nRowIndex );
    188
    189                // 雛型ファイルを使っていた場合、その雛形シートを削除する
    190                if( isRefFile ) {
    191                        excel.removeSheet( 0,refCnt-1);                 // 削除するシート番号は、From-To形式で自身を含みます。
    192
    193//                      for( int cnt=0; cnt<refCnt; cnt++ ) {
    194//                              wb.removeSheetAt( 0 );
    195//                      }
    196                }
    197
    198                // メモリ中のデータをファイルに書き込む
    199                excel.saveFile( filename );
    200
    201                // 3.5.6.0 (2004/06/18) close を finally で処理するように変更。
    202//              FileOutputStream fileOut = null ;
    203//              try {
    204//                      fileOut = new FileOutputStream(filename);
    205//                      wb.write(fileOut);
    206//              }
    207//              catch( IOException ex ) {
    208//                      String errMsg = "ファイルへ書込み中にエラーが発生しました。" + HybsSystem.CR
    209//                                              + ex.getMessage() + HybsSystem.CR
    210//                                              + "  File=" + filename;                         // 5.1.8.0 (2010/07/01) errMsg 修正
    211//                      throw new HybsSystemException( errMsg,ex );             // 3.5.5.4 (2004/04/15) 引数の並び順変更
    212//              }
    213//              finally {
    214//                      Closer.ioClose( fileOut );              // 4.0.0 (2006/01/31) close 処理時の IOException を無視
    215//                      if( null != sheet ) { sheet = null; }
    216//                      if( null != wb    ) { wb    = null; }
    217//              }
    218        }
    219
    220        /**
    221         * DBTableModel から データを作成して,PrintWriter に書き出します。
    222         *
    223         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
    224         * @og.rev 3.5.4.3 (2004/01/05) 引数に PrintWriter を受け取るように変更します。
    225         * @og.rev 3.8.5.3 (2006/08/07) フォント名やフォントサイズの指定
    226         * @og.rev 4.0.0.0 (2006/09/31) UnsupportedOperationException を発行します。
    227         * @og.rev 6.0.1.2 (2014/08/08) 親クラスで同様の処理は定義済みのため、削除。
    228         *
    229         * @param       writer PrintWriterオブジェクト
    230         */
    231//      @Override
    232//      public void writeDBTable( final PrintWriter writer )  {
    233//              String errMsg = "このクラスでは実装されていません。";
    234//              throw new UnsupportedOperationException( errMsg );
    235//      }
    236
    237        /**
    238         * PrintWriter に DBTableModelのラベル情報を書き込みます。
    239         * 第一カラム目は、ラベル情報を示す "#Label" を書き込みます。
    240         * この行は、出力形式に無関係に、TableWriter.TAB_SEPARATOR で区切られます。
    241         *
    242         * @og.rev 5.1.4.0 (2010/03/01) useNumber属性対応
    243         * @og.rev 6.0.1.2 (2014/08/08) カラム飛ばしできる機能を追加
    244         *
    245         * @param       table  DBTableModelオブジェクト
    246         * @param       writer PrintWriterオブジェクト
    247         */
    248        @Override
    249        protected void writeLabel( final DBTableModel table,final PrintWriter writer ) {
    250                short nColIndex = 0;
    251//              Row   oRow = setFirstCellValue( nRowIndex++, nColIndex++, "#Label" );
    252                excel.createRow( nRowIndex++ );
    253                if( useNumber ) { headerCellValue( "Label",nColIndex++ ); }
    254
    255                for( int i=0; i<numberOfColumns; i++ ) {
    256                        int clm = clmNo[i];
    257                        if( clm < 0 ) {                 // 6.0.1.2 (2014/08/08) カラム飛ばし
    258//                              setRowCellValue( oRow, nColIndex++, "", Cell.CELL_TYPE_STRING );
    259                                headerCellValue( "",nColIndex++ );
    260                                continue;
    261                        }
    262
    263                        String val = dbColumn[clm].getLabel();
    264                        // 5.1.4.0 (2010/03/01) useNumber=false の場合は、nColIndex を一つ戻して、値に # を付ける。
    265//                      if( i==0 && !useNumber ) {
    266//                              nColIndex-- ;
    267//                              val = "#" + val;
    268//                      }
    269//                      setRowCellValue( oRow, nColIndex++, val,Cell.CELL_TYPE_STRING );
    270                        headerCellValue( val,nColIndex++ );
    271                }
    272
    273                // 余計なセルを削除
    274//              removeRowCell( oRow, nColIndex );
    275                excel.removeCell( nColIndex );
    276        }
    277
    278        /**
    279         * PrintWriter に DBTableModelの項目名情報を書き込みます。
    280         * 第一カラム目は、項目名情報を示す "#Name" を書き込みます。
    281         * この行は、出力形式に無関係に、TableWriter.TAB_SEPARATOR で区切られます。
    282         *
    283         * @og.rev 3.1.1.0 (2003/03/28) 同期メソッド(synchronized付き)を非同期に変更する。
    284         * @og.rev 5.1.4.0 (2010/03/01) useNumber属性対応
    285         * @og.rev 6.0.1.2 (2014/08/08) カラム飛ばしできる機能を追加
    286         *
    287         * @param       table  DBTableModelオブジェクト
    288         * @param       writer PrintWriterオブジェクト
    289         */
    290        @Override
    291        protected void writeName( final DBTableModel table,final PrintWriter writer ) {
    292                short nColIndex = 0;
    293//              Row   oRow = setFirstCellValue( nRowIndex++, nColIndex++, "#Name" );
    294                excel.createRow( nRowIndex++ );
    295                if( useNumber ) { headerCellValue( "Name",nColIndex++ ); }
    296
    297                for( int i=0; i<numberOfColumns; i++ ) {
    298                        int clm = clmNo[i];
    299                        if( clm < 0 ) {                 // 6.0.1.2 (2014/08/08) カラム飛ばし
    300//                              setRowCellValue( oRow, nColIndex++, "",Cell.CELL_TYPE_STRING );
    301                                headerCellValue( "",nColIndex++ );
    302                                continue;
    303                        }
    304
    305                        String val = table.getColumnName(clm);
    306                        // 5.1.4.0 (2010/03/01) useNumber=false の場合は、nColIndex を一つ戻して、値に # を付ける。
    307//                      if( i==0 && !useNumber ) {
    308//                              nColIndex-- ;
    309//                              val = "#" + val;
    310//                      }
    311//                      setRowCellValue( oRow, nColIndex++, val,Cell.CELL_TYPE_STRING );
    312                        headerCellValue( val,nColIndex++ );
    313                }
    314
    315                // 余計なセルを削除
    316//              removeRowCell( oRow, nColIndex );
    317                excel.removeCell( nColIndex );
    318        }
    319
    320        /**
    321         * PrintWriter に DBTableModelのサイズ情報を書き込みます。
    322         * 第一カラム目は、サイズ情報を示す "#Size" を書き込みます。
    323         * この行は、出力形式に無関係に、TableWriter.TAB_SEPARATOR で区切られます。
    324         *
    325         * @og.rev 3.5.5.5 (2004/04/23) DBColumn の size と maxlength の 意味を変更
    326         * @og.rev 5.1.4.0 (2010/03/01) useNumber属性対応
    327         * @og.rev 6.0.1.2 (2014/08/08) カラム飛ばしできる機能を追加
    328         *
    329         * @param       table  DBTableModelオブジェクト
    330         * @param       writer PrintWriterオブジェクト
    331         */
    332        @Override
    333        protected void writeSize( final DBTableModel table,final PrintWriter writer ) {
    334                short nColIndex = 0;
    335//              Row   oRow = setFirstCellValue( nRowIndex++, nColIndex++, "#Size" );
    336                excel.createRow( nRowIndex++ );
    337                if( useNumber ) { headerCellValue( "Size",nColIndex++ ); }
    338
    339                for( int i=0; i<numberOfColumns; i++ ) {
    340                        int clm = clmNo[i];
    341                        if( clm < 0 ) {                 // 6.0.1.2 (2014/08/08) カラム飛ばし
    342//                              setRowCellValue( oRow, nColIndex++, "",Cell.CELL_TYPE_STRING );
    343                                headerCellValue( "",nColIndex++ );
    344                                continue;
    345                        }
    346
    347                        // 4.0.0 (2005/01/31) メソッド名変更
    348                        String val = String.valueOf(dbColumn[clm].getTotalSize());
    349                        // 5.1.4.0 (2010/03/01) useNumber=false の場合は、nColIndex を一つ戻して、値に # を付ける。
    350//                      if( i==0 && !useNumber ) {
    351//                              nColIndex-- ;
    352//                              val = "#" + val;
    353//                      }
    354//                      setRowCellValue( oRow, nColIndex++, val, Cell.CELL_TYPE_NUMERIC );
    355                        headerCellValue( val,nColIndex++ );
    356                }
    357
    358                // 余計なセルを削除
    359//              removeRowCell( oRow, nColIndex );
    360                excel.removeCell( nColIndex );
    361        }
    362
    363        /**
    364         * PrintWriter に DBTableModelのクラス名情報を書き込みます。
    365         * 第一カラム目は、サイズ情報を示す "#Class" を書き込みます。
    366         * この行は、出力形式に無関係に、TableWriter.TAB_SEPARATOR で区切られます。
    367         *
    368         * @og.rev 5.1.4.0 (2010/03/01) useNumber属性対応
    369         * @og.rev 6.0.1.2 (2014/08/08) カラム飛ばしできる機能を追加
    370         *
    371         * @param       table  DBTableModelオブジェクト
    372         * @param       writer PrintWriterオブジェクト
    373         */
    374        @Override
    375        protected void writeClass( final DBTableModel table,final PrintWriter writer ) {
    376                short nColIndex = 0;
    377//              Row   oRow = setFirstCellValue( nRowIndex++, nColIndex++, "#Class" );
    378                excel.createRow( nRowIndex++ );
    379                if( useNumber ) { headerCellValue( "Class",nColIndex++ ); }
    380
    381                for( int i=0; i<numberOfColumns; i++ ) {
    382                        int clm = clmNo[i];
    383                        if( clm < 0 ) {                 // 6.0.1.2 (2014/08/08) カラム飛ばし
    384//                              setRowCellValue( oRow, nColIndex++, "",Cell.CELL_TYPE_STRING );
    385                                headerCellValue( "",nColIndex++ );
    386                                continue;
    387                        }
    388
    389                        String val = dbColumn[clm].getClassName();
    390                        // 5.1.4.0 (2010/03/01) useNumber=false の場合は、nColIndex を一つ戻して、値に # を付ける。
    391//                      if( i==0 && !useNumber ) {
    392//                              nColIndex-- ;
    393//                              val = "#" + val;
    394//                      }
    395//                      setRowCellValue( oRow, nColIndex++, val,Cell.CELL_TYPE_STRING );
    396                        headerCellValue( val,nColIndex++ );
    397                }
    398
    399                // 余計なセルを削除
    400//              removeRowCell( oRow, nColIndex );
    401                excel.removeCell( nColIndex );
    402        }
    403
    404        /**
    405         * PrintWriter に セパレーターを書き込みます。
    406         * 第一カラム目は、サイズ情報を示す "#----" を書き込みます。
    407         * この行は、出力形式に無関係に、TableWriter.TAB_SEPARATOR で区切られます。
    408         *
    409         * @og.rev 5.1.4.0 (2010/03/01) useNumber属性対応
    410         *
    411         * @param       table  DBTableModelオブジェクト
    412         * @param       writer PrintWriterオブジェクト
    413         */
    414        @Override
    415        protected void writeSeparator( final DBTableModel table,final PrintWriter writer ) {
    416                final String SEP = "----" ;
    417
    418                short nColIndex = 0;
    419//              Row   oRow = setFirstCellValue( nRowIndex++, nColIndex++, "#----" );
    420                excel.createRow( nRowIndex++ );
    421                if( useNumber ) { headerCellValue( SEP,nColIndex++ ); }
    422
    423                for( int i=0; i<numberOfColumns; i++ ) {
    424                        // 5.1.4.0 (2010/03/01) useNumber=false の場合は、単になにもしないだけ
    425//                      if( i==0 && !useNumber ) {
    426//                              continue;
    427//                      }
    428//                      setRowCellValue( oRow, nColIndex++, sep,Cell.CELL_TYPE_STRING );
    429                        headerCellValue( SEP,nColIndex++ );
    430                }
    431
    432                // 余計なセルを削除
    433//              removeRowCell( oRow, nColIndex );
    434                excel.removeCell( nColIndex );
    435        }
    436
    437
    438        /**
    439         * ExcelModel#setCellValue(String.int) の第一カラムの場合に、コメントの # を追加する簡易メソッドです。
    440         *
    441         * colNo == 0 の場合だけ、引数の val に、"#" を追加します。
    442         * これは、openGion特有のコメント行を意味するため、ヘッダーレコードにのみ適用します。
    443         *
    444         * @og.rev 6.0.1.2 (2014/08/08) カラム飛ばしできる機能を追加
    445         *
    446         * @param       val   設定文字列
    447         * @param       colNo 行番号
    448         */
    449        private void headerCellValue( final String val,final int colNo ) {
    450                if( colNo == 0 ) {
    451                        excel.setCellValue( "#" + val,colNo );
    452                }
    453                else {
    454                        excel.setCellValue( val,colNo );
    455                }
    456        }
    457
    458        /**
    459         * PrintWriter に DBTableModelのテーブル情報を書き込みます。
    460         * このクラスでは，データを ダブルコーテーション(")で囲みます。
    461         * PrintWriter に DBTableModelのテーブル情報を書き込みます。
    462         *
    463         * @og.rev 3.8.0.1 (2005/06/17) DBTypeが NVAR の場合は、元のUnicodeに戻します。
    464         * @og.rev 3.8.5.3 (2006/08/07) DBType の nativeType に対応した、CELL_TYPE をセットします。
    465         * @og.rev 4.1.1.2 (2008/02/28) NativeタイプをEnum型(fukurou.model.NativeType)に変更
    466         * @og.rev 5.1.4.0 (2010/03/01) columns 対応
    467         * @og.rev 5.1.4.0 (2010/03/01) useNumber属性対応
    468         * @og.rev 5.2.1.0 (2010/10/01) useRenderer 対応
    469         * @og.rev 5.7.6.3 (2014/05/23) stringOutput対応
    470         * @og.rev 6.0.1.2 (2014/08/08) カラム飛ばしできる機能を追加
    471         *
    472         * @param       table  DBTableModelオブジェクト
    473         * @param       writer PrintWriterオブジェクト
    474         */
    475        @Override
    476        protected void writeData( final DBTableModel table,final PrintWriter writer ) {
    477                int numberOfRows =      table.getRowCount();
    478
    479                // 5.1.4.0 columns 対応。forループは、引数i で廻す。
    480                boolean[] nvar  = new boolean[numberOfColumns];
    481//              int[] cellType  = new int[numberOfColumns];
    482                boolean[] isNums = new boolean[numberOfColumns];        // 6.0.2.0 (2014/08/29) NUMBER型かどうか
    483                boolean useRenderer = isUseRenderer();                          // 5.2.1.0 (2010/10/01)
    484
    485                for( int i=0; i<numberOfColumns; i++ ) {
    486                        int clm = clmNo[i];
    487                        if( clm < 0 ) { continue; }                     // 6.0.1.2 (2014/08/08) カラム飛ばし
    488
    489                        // 5.7.6.3 (2014/05/23) ここでレンデラ時の文字タイプ判定を行う
    490                        if( useRenderer && dbColumn[clm].isStringOutput() ){
    491//                              cellType[i] = Cell.CELL_TYPE_STRING ;
    492                                isNums[i]   = false;
    493                        }
    494                        else {
    495                                NativeType nativeType = dbColumn[clm].getNativeType();
    496                                switch( nativeType ) {
    497                                        case INT    :
    498                                        case LONG   :
    499                                        case DOUBLE :
    500//                                              cellType[i] = Cell.CELL_TYPE_NUMERIC ;
    501                                                isNums[i]   = true;
    502                                                        break;
    503                                        case STRING :
    504                                        case CALENDAR :
    505                                        default :
    506//                                                      cellType[i] = Cell.CELL_TYPE_STRING ;
    507                                                        isNums[i]   = false;
    508                                                        break;
    509                                }
    510                        }
    511                        nvar[i] = "NVAR".equals( dbColumn[clm].getDbType()) ;
    512                }
    513//              boolean useRenderer = isUseRenderer();  // 5.2.1.0 (2010/10/01) , 5.7.6.3 (2014/05/23) 上へ移動
    514
    515                short nColIndex;
    516//              Row   oRow;
    517                for( int row=0; row<numberOfRows; row++ ) {
    518                        nColIndex = 0;
    519//                      oRow = setFirstCellValue( nRowIndex++, nColIndex++, String.valueOf( row+1 ) );
    520                        excel.createRow( nRowIndex++ );
    521                        if( useNumber ) { excel.setCellValue( String.valueOf( row+1 ),nColIndex++ ); }
    522
    523                        // 5.1.4.0 (2010/03/01) useNumber=false の場合は、nColIndex を一つ戻す。
    524//                      if( !useNumber ) {
    525//                              nColIndex-- ;
    526//                      }
    527
    528                        for( int i=0; i<numberOfColumns; i++ ) {
    529                                int clm = clmNo[i];
    530                                if( clm < 0 ) {                 // 6.0.1.2 (2014/08/08) カラム飛ばし
    531//                                      setRowCellValue( oRow, nColIndex++, "",Cell.CELL_TYPE_STRING );
    532                                        excel.setCellValue( "",nColIndex++ );
    533                                        continue;
    534                                }
    535
    536                                String val = table.getValue(row,clm);
    537                                if( nvar[i] ) {
    538                                        val = StringUtil.getReplaceEscape( val );
    539                                }
    540                                // 5.2.1.0 (2010/10/01) useRenderer 対応
    541                                else if( useRenderer ) {
    542                                        val = StringUtil.spanCut( dbColumn[clm].getRendererValue( val ) );
    543                                }
    544
    545//                              setRowCellValue( oRow, nColIndex++, val,cellType[i] );
    546                                excel.setCellValue( val,nColIndex++,isNums[i] );
    547                        }
    548
    549                        // 余計なセルを削除
    550//                      removeRowCell( oRow, nColIndex );
    551                        excel.removeCell( nColIndex );
    552                }
    553        }
    554
    555        /**
    556         * Excelの指定行の一番目セルにデータを設定する。
    557         *
    558         * @og.rev 4.3.4.0 (2008/12/01) POI3.2対応
    559         * @og.rev 4.3.4.3 (2008/12/22) protected化
    560         * @og.rev 6.0.1.2 (2014/08/08) private化
    561         *
    562         * @param        indexOfRow 行の番号
    563         * @param        indexOfCell セルの番号
    564         * @param        dataVal    String文字列
    565         *
    566         * @return       Rowのobject型
    567         */
    568////    protected Row setFirstCellValue( final int indexOfRow, final int indexOfCell, final String dataVal ) {
    569//      private Row setFirstCellValue( final int indexOfRow, final int indexOfCell, final String dataVal ) {
    570//              Row oRow = sheet.getRow( indexOfRow );
    571//              if( oRow == null ) { oRow = sheet.createRow( indexOfRow ); }
    572//
    573//              Cell oCell = oRow.getCell( indexOfCell );
    574//              if( null == oCell ) { oCell = oRow.createCell( indexOfCell ); }
    575//
    576//              RichTextString richText = createHelper.createRichTextString( dataVal );
    577//              oCell.setCellValue( richText );
    578//
    579//              return oRow;
    580//      }
    581
    582        /**
    583         * Excelの指定セルにデータを設定する。
    584         *
    585         * @og.rev 4.3.4.0 (2008/12/01) POI3.2対応
    586         * @og.rev 4.3.4.3 (2008/12/22) protected化
    587         * @og.rev 5.7.4.1 (2014/03/15) useRenderer対応
    588         * @og.rev 5.7.6.3 (2014/05/23) stringOutput対応
    589         * @og.rev 6.0.1.2 (2014/08/08) private化
    590         *
    591         * @param        oRow   Row型のオブジェクト
    592         * @param        indexOfCell セルの番号
    593         * @param        dataVal    String文字列
    594         * @param        cellType   [Cell.CELL_TYPE_STRING/Cell.CELL_TYPE_NUMERIC]
    595         */
    596////    protected void setRowCellValue( final Row oRow, final int indexOfCell, final String dataVal,final int cellType ) {
    597//      private void setRowCellValue( final Row oRow, final int indexOfCell, final String dataVal,final int cellType ) {
    598//              Cell oCell = oRow.getCell( indexOfCell );
    599//              if( null == oCell ) { oCell = oRow.createCell( indexOfCell ); }
    600//
    601//              // 5.7.4.1 (2014/03/15) useRendererがtrueの場合はdouble変換をかけない
    602////            if( !isUseRenderer() && cellType == Cell.CELL_TYPE_NUMERIC ) {
    603//              if( cellType == Cell.CELL_TYPE_NUMERIC ) {
    604//                      oCell.setCellValue( StringUtil.parseDouble( dataVal ) );
    605//              }
    606//              else {
    607//                      RichTextString richText = createHelper.createRichTextString( dataVal );
    608//                      oCell.setCellValue( richText );
    609//              }
    610//      }
    611
    612        /**
    613         * Excelの指定セルをシートから削除する。
    614         *
    615         * @og.rev 4.3.4.0 (2008/12/01) POI3.2対応
    616         * @og.rev 4.3.4.3 (2008/12/22) protected化
    617         * @og.rev 6.0.1.2 (2014/08/08) private化
    618         *
    619         * @param        oRow   Row型のオブジェクト
    620         * @param        nBegin     セルの開始番号
    621         */
    622////    protected void removeRowCell( final Row oRow, final int nBegin ) {
    623//      private void removeRowCell( final Row oRow, final int nBegin ) {
    624//              int nEnd = oRow.getLastCellNum();
    625////            for( int nIndex = nBegin; nIndex <= nEnd; nIndex++) {
    626//              for( int nIndex = nEnd; nIndex >= nBegin; nIndex--) {
    627//                      Cell oCell = oRow.getCell( nIndex );
    628//                      if( null != oCell ) { oRow.removeCell(oCell); }
    629//              }
    630//      }
    631
    632        /**
    633         * Excelの指定行をシートから削除する。
    634         * nBegin は、すでに＋１されているので、＝ になるまで削除します。
    635         *
    636         * @param        oThisSheet Sheet型のオブジェクト
    637         * @param        nBegin     行の開始番号
    638         */
    639//      private void removeSheetRow( final Sheet oThisSheet, final int nBegin ) {
    640//              int nEnd = oThisSheet.getLastRowNum();
    641////            for( int nIndex = nBegin; nIndex <= nEnd; nIndex++) {
    642//              for( int nIndex = nEnd; nIndex >= nBegin; nIndex--) {
    643//                      Row oRow = oThisSheet.getRow( nIndex );
    644//                      if( null != oRow ) { oThisSheet.removeRow(oRow); }
    645//              }
    646//      }
    647
    648        /**
    649         * DBTableModelのデータとして書き込むときのシート名をセットします。
    650         * 初期値は、"Sheet1" です。同じ名称のシートが存在する場合、そのシート
    651         * 名の後に(2)、(3)のような文字列をくっ付けます。
    652         *
    653         * ※ 改造前は、シートの名前は30桁文字(31個文字)なので、そのチェックと
    654         *    substring による桁数調整が入っていましたが、やめます。
    655         *
    656         * @og.rev 6.0.1.2 (2014/08/08) シート名の桁数チェックを廃止(簡略化と希望的観測)
    657         *
    658         * @param        workbook   Workbookオブジェクト
    659         * @param        nameSet    String文字列,指定のシート名
    660         * @return      シート名
    661         */
    662////    protected String getNewSheetNameByName( final Workbook workbook, final String nameSet) {
    663//      private String getNewSheetNameByName( final Workbook workbook, final String nameSet) {
    664//              String nameSheet = nameSet;
    665//              int nCount  = 1;
    666//
    667//              while( workbook.getSheetIndex(nameSheet) >= 0 ) {       // シート名が存在している場合
    668//                      nameSheet = nameSet + "(" + nCount + ")";
    669//                      nCount++;
    670//              }
    671//
    672//              return nameSheet;
    673//      }
    674
    675        /**
    676         * 出力先ファイル名をセットします。(DIR + Filename)
    677         * これは、EXCEL追加機能として実装されています。
    678         *
    679         * @og.rev 3.5.4.3 (2004/01/05) 新規作成
    680         *
    681         * @param   fname EXCEL雛型参考ファイル名
    682         */
    683        @Override
    684        public void setFilename( final String fname ) {
    685                filename = fname;
    686        }
    687
    688        /**
    689         * DBTableModelのデータとして読み込むときのシート名を設定します。
    690         * 初期値は、"Sheet1" です。
    691         * これは、EXCEL追加機能として実装されています。
    692         *
    693         * @og.rev 3.5.4.2 (2003/12/15) 新規追加
    694         *
    695         * @param   shtName シート名
    696         */
    697        @Override
    698        public void setSheetName( final String shtName ) {
    699                if( shtName != null ) { this.sheetName = shtName; }
    700        }
    701
    702        /**
    703         * このクラスが、EXCEL対応機能を持っているかどうかを返します。
    704         *
    705         * EXCEL対応機能とは、シート名のセット、雛型参照ファイル名のセット、
    706         * 書き込み元ファイルのFileオブジェクト取得などの、特殊機能です。
    707         * 本来は、インターフェースを分けるべきと考えますが、taglib クラス等の
    708         * 関係があり、問い合わせによる条件分岐で対応します。
    709         *
    710         * @og.rev 3.5.4.3 (2004/01/05) 新規追加
    711         *
    712         * @return      EXCEL対応機能を持っているかどうか(常に true)
    713         */
    714        @Override
    715        public boolean isExcel() {
    716                return true;
    717        }
    718
    719        /**
    720         * EXCEL雛型参考ファイル名をセットします。(DIR + Filename)
    721         * これは、EXCEL追加機能として実装されています。
    722         *
    723         * @og.rev 3.5.4.3 (2004/01/05) 新規作成
    724         *
    725         * @param   rfname EXCEL雛型参考ファイル名
    726         */
    727        @Override
    728        public void setRefFilename( final String rfname ) {
    729                refFilename = rfname;
    730        }
    731
    732        /**
    733         * EXCEL雛型参考ファイルのシート名を設定します。
    734         * これは、EXCEL追加機能として実装されています。
    735         *
    736         * EXCELファイルを書き出す時に、雛型として参照するシート名を指定します。
    737         * これにより、複数の形式の異なるデータを順次書き出したり(appendモードを併用)する
    738         * ことや、シートを指定して新規にEXCELを作成する場合にフォームを設定する事が可能になります。
    739         * 初期値は、null(第一シート) です。
    740         *
    741         * @og.rev 3.5.4.3 (2004/01/05) 新規追加
    742         *
    743         * @param   rshtName シート名
    744         */
    745        @Override
    746        public void setRefSheetName( final String rshtName )  {
    747                if( rshtName != null ) { refSheetName = rshtName; }
    748        }
    749
    750        /**
    751         * データの書き込み開始位置を設定します(初期値:0)。
    752         *
    753         * TAB区切りテキストやEXCEL等のデータの書き込みの開始位置を指定します。
    754         * 属性名は、行を飛ばす処理ということで、readTable タグと同じ名称です。
    755         * ファイルの先頭行が、０行としてカウントしますので、設定値は、読み飛ばす
    756         * 件数になります。(１と指定すると、１件読み飛ばし、２行目から読み込みます。)
    757         * 行の読み飛ばしと、カラムの読み飛ばし(columns)、refFileURL、refFilename、
    758         * refSheetName とともに使用すれば、ある程度のレイアウト設定が可能です。
    759         * なお、この機能は、TableWriter_Excel のみに実装します。
    760         *
    761         * @og.rev 6.0.1.2 (2014/08/08) 新規作成
    762         *
    763         * @param       skipCount 書き込み開始位置
    764         */
    765        @Override
    766        public void setSkipRowCount( final int skipCount ) {
    767                skipRowCount = skipCount ;
    768        }
    769
    770        /**
    771         * EXCEL出力時のデフォルトフォント名を設定します。
    772         * これは、EXCEL追加機能として実装されています。
    773         *
    774         * EXCELファイルを書き出す時に、デフォルトフォント名を指定します。
    775         * フォント名は、EXCELのフォント名をそのまま使用してください。
    776         * 内部的に、POI の org.apache.poi.hssf.usermodel.HSSFFont#setFontName( String )
    777         * に設定されます。
    778         * 雛形ファイルを使用しない場合のみ、設定可能です。
    779         *
    780         * @og.rev 3.8.5.3 (2006/08/07) 新規追加
    781         *
    782         * @param   font デフォルトフォント名
    783         */
    784        @Override
    785        public void setFontName( final String font ) {
    786                fontName = font ;
    787        }
    788
    789        /**
    790         * EXCEL出力時のデフォルトフォントポイント数を設定します。
    791         * これは、EXCEL追加機能として実装されています。
    792         *
    793         * EXCELファイルを書き出す時に、デフォルトポイント数を指定します。
    794         * 内部的に、POI の org.apache.poi.hssf.usermodel.HSSFFont#setFontHeightInPoints( short )
    795         * に設定されます。
    796         * 雛形ファイルを使用しない場合のみ、設定可能です。
    797         *
    798         * @og.rev 3.8.5.3 (2006/08/07) 新規追加
    799         *
    800         * @param   point デフォルトフォントポイント数
    801         */
    802        @Override
    803        public void setFontPoint( final short point ) {
    804                fontPoint = point;
    805        }
    806
    807        /**
    808         * EXCELファイルのWookbookというStream(MicrosoftのOLE用語)を作ります
    809         * 条件によって、新規かとファイルから読み込み書き込みかが分かれます。
    810         *
    811         * @og.rev 6.0.1.2 (2014/08/08) メソッド統合
    812         *
    813         * @param   fname  EXCEL参考ファイル名
    814         * @param   isOpen true:ファイルオープン/false:新規作成
    815         *
    816         * @return  EXCELファイルのWorkbook
    817         */
    818////    protected Workbook createWorkbook( final String fname ) {
    819//      private Workbook createWorkbook( final String fname , final boolean isOpen ) {
    820//              final Workbook rtnWb ;
    821//
    822//              if( isOpen ) {
    823//                      // File オブジェクトでcreate すると、ファイルがオープンされたままになってしまう。
    824//                      FileInputStream fileIn  = null;
    825//                      try {
    826//                              fileIn = new FileInputStream(fname);
    827//                              rtnWb = WorkbookFactory.create(fileIn);
    828//                      }
    829//                      catch ( Exception ex ) {
    830//                              String errMsg = "ファイル読込みエラー[" + fname + "]"  ;
    831//                              throw new HybsSystemException( errMsg,ex );             // 3.5.5.4 (2004/04/15) 引数の並び順変更
    832//                      }
    833//                      finally {
    834//                              Closer.ioClose( fileIn );               // 4.0.0 (2006/01/31) close 処理時の IOException を無視
    835//                      }
    836//              }
    837//              else {
    838//                      // 新規の場合、ファイル名に.xlsxで終了した場合⇒.xlsx形式ファイル作成、その他⇒.xls形式ファイル作成
    839//                      if( fname.toLowerCase(Locale.JAPAN).endsWith( ".xlsx" ) ) {
    840//                              rtnWb = new org.apache.poi.xssf.usermodel.XSSFWorkbook();
    841//                      }
    842//                      else {
    843//                              rtnWb = new org.apache.poi.hssf.usermodel.HSSFWorkbook();
    844//                      }
    845//              }
    846//              return rtnWb;
    847//      }
    848}