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     */
016    package org.opengion.plugin.io;
017    
018    import java.io.BufferedReader;
019    import java.io.FileInputStream;
020    import java.io.IOException;
021    import java.io.InputStream;
022    // import java.text.DateFormat;
023    import java.text.DecimalFormat;
024    import java.text.NumberFormat;
025    // import java.text.SimpleDateFormat;
026    // import java.util.Locale;
027    import java.util.List;
028    import java.util.ArrayList;
029    
030    import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
031    import org.apache.poi.ss.usermodel.Cell;
032    import org.apache.poi.ss.usermodel.DateUtil;
033    import org.apache.poi.ss.usermodel.RichTextString;
034    import org.apache.poi.ss.usermodel.Row;
035    import org.apache.poi.ss.usermodel.Sheet;
036    import org.apache.poi.ss.usermodel.Workbook;
037    import org.apache.poi.ss.usermodel.WorkbookFactory;
038    import org.apache.poi.ss.usermodel.CreationHelper;
039    import org.apache.poi.ss.usermodel.FormulaEvaluator;
040    import org.opengion.fukurou.util.Closer;
041    import org.opengion.fukurou.util.StringUtil;
042    import org.opengion.fukurou.util.HybsDateUtil;
043    import org.opengion.hayabusa.common.HybsSystem;
044    import org.opengion.hayabusa.common.HybsSystemException;
045    import org.opengion.hayabusa.db.DBTableModelUtil;
046    
047    /**
048     * POI による、EXCELバイナリファイルを読み取る実?ラスです?
049     *
050     * ファイル名?シート名を指定して、データを読み取ることが可能です?
051     * 第?ラ? # で始まる行?、コメント行なので、読み飛?します?
052     * カラ?の?行で、カラ??null の場合?、その列?読み飛?します?
053     *
054     * 入力形式?、openXML形式にも対応して?す?
055     * ファイルの?に応じて?xlsと.xlsxのどちらで読み取るか?、?部?
056     * 自動判定されます?
057     *
058     * @og.rev 3.5.4.8 (2004/02/23) 新規作?
059     * @og.rev 4.3.6.7 (2009/05/22) ooxml形式対?
060     * @og.group ファイル入?
061     *
062     * @version  4.0
063     * @author   Kazuhiko Hasegawa
064     * @since    JDK5.0,
065     */
066    public class TableReader_Excel extends TableReader_Default {
067            //* こ?プログラ??VERSION??を設定します?       {@value} */
068            private static final String VERSION = "5.5.8.2 (2012/11/09)" ;
069    
070            private String  filename                = null;         // 3.5.4.3 (2004/01/05)
071            private String  sheetName               = null;         // 3.5.4.2 (2003/12/15)
072            private String  sheetNos                = null;         // 5.5.7.2 (2012/10/09)
073    
074            private String  constKeys               = null;         // 5.5.8.2 (2012/11/09) 固定?となるカラ?(CSV形?
075            private String  constAdrs               = null;         // 5.5.8.2 (2012/11/09) 固定?となるアドレス(????・・・)
076            private String  nullBreakClm    = null;         // 5.5.8.2 (2012/11/09) 取込み条件/Sheet BREAK条件
077    
078            /**
079             * DBTableModel から ?式???タを作?して,BufferedReader より読み取ります?
080             * コメン?空行を除き???の行?、??名が?です?
081             * それ以降?、コメン?空行を除き???タとして読み込んで?ます?
082             * こ?メソ?は、EXCEL 読み込み時に使用します?
083             *
084             * @og.rev 4.0.0.0 (2006/09/31) 新規追?
085             * @og.rev 5.1.6.0 (2010/05/01) columns 処?追?
086             * @og.rev 5.1.6.0 (2010/05/01) skipRowCountの追?
087             * @og.rev 5.1.8.0 (2010/07/01) Exception をきちっと記述(InvalidFormatException)
088             * @og.rev 5.2.1.0 (2010/10/01) setTableColumnValues メソ?を経由して、テーブルに??タをセ?する?
089             * @og.rev 5.5.1.2 (2012/04/06) HeaderData ?try の上に?、エラーメ?ージを取得できるようにする?
090             * @og.rev 5.5.7.2 (2012/10/09) sheetNos 追?よる?シート?マ?ジ読み取りサポ??
091             * @og.rev 5.5.8.2 (2012/11/09) HeaderData に ??フラグを渡します?
092             *
093             * @see #isExcel()
094             */
095            @Override
096            public void readDBTable() {
097                    InputStream  in = null;
098                    HeaderData data = null;         // 5.5.1.2 (2012/04/06)
099                    try {
100                            boolean isDebug = isDebug();                    // 5.5.7.2 (2012/10/09) ????
101    
102                            if( isDebug ) { System.out.println( " Filename=" + filename ) ; }
103    
104                            in = new FileInputStream(filename);
105    
106    //                      POIFSFileSystem fs = new POIFSFileSystem(in);
107    //                      HSSFWorkbook wb = new HSSFWorkbook(fs);
108    //                      HSSFSheet sheet ;
109                            Workbook wb = WorkbookFactory.create(in);
110    //                      Sheet sheet ;
111                            Sheet[] sheets ;                                                                        // 5.5.7.2 (2012/10/09) 配?に変更
112    
113                            if( isDebug ) { wb = ExcelUtil.activeWorkbook( wb ); }          // ??モード時には、エクセルのアク?ブセル領域のみにシュリンクを行う
114    
115                            // 5.5.7.2 (2012/10/09) ?シート?マ?ジ読み取り?sheetNos の?が優先される?
116                            if( sheetNos != null && sheetNos.length() > 0 ) {
117                                    String[] sheetList = StringUtil.csv2ArrayExt( sheetNos , wb.getNumberOfSheets()-1 );    // ?シート番号は、シート数-1
118                                    sheets = new Sheet[sheetList.length];
119                                    for( int i=0; i<sheetList.length; i++ ) {
120                                            sheets[i] = wb.getSheetAt( Integer.parseInt( sheetList[i] ) );
121                                    }
122                            }
123                            else if( sheetName != null && sheetName.length() > 0 ) {
124                                    Sheet sheet = wb.getSheet( sheetName );
125                                    if( sheet == null ) {
126                                            String errMsg = "対応するシートが存在しません?Sheet=[" + sheetName + "]" ;
127                                            throw new HybsSystemException( errMsg );
128                                    }
129                                    sheets = new Sheet[] { sheet };
130                            }
131                            else {
132                                    Sheet sheet = wb.getSheetAt(0);
133                                    sheets = new Sheet[] { sheet };
134                            }
135    
136    //                      if( sheetName == null || sheetName.length() == 0 ) {
137    //                              sheet = wb.getSheetAt(0);
138    //                      }
139    //                      else {
140    //                              sheet = wb.getSheet( sheetName );
141    //                              if( sheet == null ) {
142    //                                      String errMsg = "対応するシートが存在しません?Sheet=[" + sheetName + "]" ;
143    //                                      throw new HybsSystemException( errMsg );
144    //                              }
145    //                      }
146    
147                            boolean  nameNoSet = true;
148                            table = DBTableModelUtil.newDBTable();
149    
150                            int numberOfRows = 0;
151    //                      HeaderData data = new HeaderData();
152                            data = new HeaderData();                                // 5.5.1.2 (2012/04/06)
153    
154                            data.setDebug( isDebug );                               // 5.5.8.2 (2012/11/09)
155    
156                            // 5.1.6.0 (2010/05/01) columns 処?
157                            data.setUseNumber( isUseNumber() );
158    
159                            // 5.5.8.2 (2012/11/09) 固定?となるカラ?(CSV形?とアドレス(????・・・)を設?
160                            data.setSheetConstData( constKeys,constAdrs );
161    
162                            int nullBreakClmAdrs = -1;                                              // 5.5.8.2 (2012/11/09) nullBreakClm の DBTableModel上?アドレス?1 は、未使用
163                            if( data.setColumns( columns ) ) {
164                                    nameNoSet = false;
165                                    table.init( data.getColumnSize() );
166                                    setTableDBColumn( data.getNames() ) ;
167                                    nullBreakClmAdrs = table.getColumnNo( nullBreakClm, false );    // 5.5.8.2 (2012/11/09) カラ?号取得?存在しなければ -1 を返す?
168                            }
169    
170                            int skip = getSkipRowCount();                                   // 5.1.6.0 (2010/05/01)
171                            // 5.5.7.2 (2012/10/09) ?シート?マ?ジ読み取り?
172                            for( int i=0; i<sheets.length; i++ ) {                       // 5.5.7.2 (2012/10/09) シート?列を処?ます?
173                                    Sheet sheet = sheets[i] ;                                       // 5.5.7.2 (2012/10/09)
174    
175                                    data.setSheetConstValues( sheet );                              // 5.5.8.2 (2012/11/09) シート単位に固定カラ??値をキャ?ュする?
176    
177                                    int nFirstRow = sheet.getFirstRowNum();
178                                    if( nFirstRow < skip ) { nFirstRow = skip; } // 5.1.6.0 (2010/05/01)
179                                    int nLastRow  = sheet.getLastRowNum();
180                                    if( isDebug ) {         // 5.5.7.2 (2012/10/09) ????
181                                            System.out.println( " Debug: 行?番=" + numberOfRows + " : Sheet= " + sheet.getSheetName() + " , 開?" + nFirstRow + " , 終?" + nLastRow );
182                                    }
183                                    for( int nIndexRow = nFirstRow; nIndexRow <= nLastRow; nIndexRow++) {
184            //                              HSSFRow oRow = sheet.getRow(nIndexRow);
185                                            Row oRow = sheet.getRow(nIndexRow);
186                                            if( data.isSkip( oRow ) ) { continue; }
187                                            if( nameNoSet ) {
188                                                    nameNoSet = false;
189                                                    table.init( data.getColumnSize() );
190                                                    setTableDBColumn( data.getNames() ) ;
191                                                    nullBreakClmAdrs = table.getColumnNo( nullBreakClm, false );    // 5.5.8.2 (2012/11/09) カラ?号取得?存在しなければ -1 を返す?
192                                            }
193    
194                                            if( numberOfRows < getMaxRowCount() ) {
195                                                    String[] tblData = data.row2Array( oRow );                      // 5.5.8.2 (2012/11/09) nullBreakClm の判定?ため、?配?に受ける?
196                                                    if( nullBreakClmAdrs >= 0 && ( tblData[nullBreakClmAdrs] == null || tblData[nullBreakClmAdrs].isEmpty() ) ) {
197                                                            break;          // nullBreakClm ?null の場合?、そのSheet処?中止する?
198                                                    }
199                                                    setTableColumnValues( tblData );                                        // 5.5.8.2 (2012/11/09)
200    //                                              setTableColumnValues( data.row2Array( oRow ) );         // 5.2.1.0 (2010/10/01)
201    //                                              table.addColumnValues( data.row2Array( oRow ) );
202                                                    numberOfRows ++ ;
203                                            }
204                                            else {
205                                                    table.setOverflow( true );
206                                            }
207                                    }
208    
209                                    // ?まで?NAME が見つから無かった??
210                                    if( nameNoSet ) {
211                                            String errMsg = "?まで?NAME が見つかりませんでした?
212                                                                            + HybsSystem.CR
213                                                                            + "ファイルが空か?もしく?損傷して?可能性があります?"
214                                                                            + HybsSystem.CR ;
215                                            throw new HybsSystemException( errMsg );
216                                    }
217                            }
218                    }
219    //              catch (Exception e) {
220                    catch ( IOException ex ) {
221                            String errMsg = "ファイル読込みエラー[" + filename + "]"  ;
222                            if( data != null ) { errMsg = errMsg + data.getLastCellMsg(); }         // 5.5.1.2 (2012/04/06)
223                            throw new HybsSystemException( errMsg,ex );             // 3.5.5.4 (2004/04/15) 引数の並び?更
224                    }
225                    // 5.1.8.0 (2010/07/01) Exception をきちっと記述
226                    catch (InvalidFormatException ex) {
227                            String errMsg = "ファイル形式エラー[" + filename + "]"  ;
228                            if( data != null ) { errMsg = errMsg + data.getLastCellMsg(); }         // 5.5.1.2 (2012/04/06)
229                            throw new HybsSystemException( errMsg,ex );
230                    }
231                    finally {
232                            Closer.ioClose( in );           // 4.0.0 (2006/01/31) close 処?の IOException を無?
233                    }
234            }
235    
236            /**
237             * DBTableModel から ?式???タを作?して,BufferedReader より読み取ります?
238             * コメン?空行を除き???の行?、??名が?です?
239             * それ以降?、コメン?空行を除き???タとして読み込んで?ます?
240             *
241             * @og.rev 3.5.4.3 (2004/01/05) 引数に、BufferedReader を受け取る要に変更します?
242             * @og.rev 4.0.0.0 (2006/09/31) UnsupportedOperationException を発行します?
243             *
244             * @param   reader ?式???タ(使用して?せん)
245             */
246            @Override
247            public void readDBTable( final BufferedReader reader ) {
248                    String errMsg = "こ?クラスでは実?れて?せん?;
249                    throw new UnsupportedOperationException( errMsg );
250            }
251    
252            /**
253             * DBTableModelの??タとしてEXCELファイルを読み込?き?シート名を設定します?
254             * これにより、?の形式?異なるデータを?次読み込?と??シートを?して
255             * 読み取ることが可能になります?
256             * sheetNos と sheetName が同時に?された場合?、sheetNos が優先されます?エラーにはならな??でご注意く???
257             * のでご注意く???
258             *
259             * @og.rev 3.5.4.2 (2003/12/15) 新規追?
260             *
261             * @param   sheetName シート名
262             */
263            @Override
264            public void setSheetName( final String sheetName ) {
265                    this.sheetName = sheetName;
266            }
267    
268            /**
269             * EXCELファイルを読み込?き?シート番号を指定しま?初期値:0)?
270             *
271             * EXCEL読み込み時に?シートをマ?ジして取り込みます?
272             * シート番号は? から始まる数字で表します?
273             * ヘッ??は、最初?シート?カラ?置に合わせます????ータイトルの自動認識?ありません。?
274             * よって、指定するシート?、すべて同?イアウトでな?取り込み時にカラ??ずれが発生します?
275             * 
276             * シート番号の??、カンマ区?で、??できます?また?N-M の様にハイフンで繋げることで?
277             * N 番から、M 番のシート?を??可能です?また?"*" による、?シート指定が可能です?
278             * これら??合わせも可能です???0,1,3,5-8,10-* ??
279             * ただし?"*" に関しては例外的に、?字だけで、すべてのシートを表すか、N-* を最後に?するかの
280             * どちらかです?途中には?*" は、現れません?
281             * シート番号は??1,1,2,2)??転(3,2,1) での?が可能です?これは、その??で、読み込まれます?
282             * sheetNos と sheetName が同時に?された場合?、sheetNos が優先されます?エラーにはならな??でご注意く???
283             * こ?メソ?は、isExcel() == true の場合?み利用されます?
284             * 
285             * 初期値は??第?ート?です?
286             *
287             * ※ こ?クラスでは実?れて?せん?
288             *
289             * @og.rev 5.5.7.2 (2012/10/09) 新規追?
290             *
291             * @param   sheetNos EXCELファイルのシート番号??から始まる?
292             * @see         #setSheetName( String ) 
293             */
294            @Override
295            public void setSheetNos( final String sheetNos ) {
296                    this.sheetNos = sheetNos;
297            }
298    
299            /**
300             * EXCELファイルを読み込?き?シート単位?固定?を設定するため?カラ?とアドレスを指定します?
301             * カラ?は、カンマ区?で?します?
302             * 対応するアドレスを?EXCEL上??列を?から始まる整数でカンマ区?で?します?
303             * これにより、シート???書かれて???を?DBTableModel のカラ?固定?として
304             * 設定することができます?
305             * 例として、DB定義書で、テーブル名をシート?全レコードに設定したい場合などに使?す?
306             * こ?メソ?は、isExcel() == true の場合?み利用されます?
307             *
308             * @og.rev 5.5.8.2 (2012/11/09) 新規追?
309             *
310             * @param   constKeys 固定?となるカラ?(CSV形?
311             * @param   constAdrs 固定?となるアドレス(????・・・)
312             */
313            @Override
314            public void setSheetConstData( final String constKeys,final String constAdrs ) {
315                    this.constKeys = constKeys;
316                    this.constAdrs = constAdrs;
317            }
318    
319            /**
320             * ここに?されたカラ??に NULL が現れた時点で読み取りを中止します?
321             *
322             * これは、指定?カラ????と?事を条件に、そのレコードだけを読み取る処?行います?
323             * ?Sheetの場合?、次のSheetを読みます?
324             * 現時点では、Excel の場合?み有効です?
325             *
326             * @og.rev 5.5.8.2 (2012/11/09) 新規追?
327             *
328             * @param   clm カラ??
329             */
330            @Override
331            public void setNullBreakClm( final String clm ) {
332                    nullBreakClm = clm;
333            }
334    
335            /**
336             * こ?クラスが?EXCEL対応機?を持って?かど?を返します?
337             *
338             * EXCEL対応機?とは、シート名のセ?、読み込み?ァイルの
339             * Fileオブジェクト取得などの、特殊機?です?
340             * 本来は、インターフェースを?けるべきと?ますが、taglib クラス等?
341             * 関係があり、問?わせによる条件?で対応します?
342             *
343             * @og.rev 3.5.4.3 (2004/01/05) 新規追?
344             *
345             * @return      EXCEL対応機?を持って?かど?(常にtrue)
346             */
347            @Override
348            public boolean isExcel() {
349                    return true;
350            }
351    
352            /**
353             * 読み取り?ァイル名をセ?します?(DIR + Filename)
354             * これは、EXCEL追??として実?れて?す?
355             *
356             * @og.rev 3.5.4.3 (2004/01/05) 新規作?
357             *
358             * @param   filename 読み取り?ァイル?
359             */
360            @Override
361            public void setFilename( final String filename ) {
362                    this.filename = filename;
363                    if( filename == null ) {
364                            String errMsg = "ファイル名が?されて?せん? ;
365                            throw new HybsSystemException( errMsg );
366                    }
367            }
368    }
369    
370    /**
371     * EXCEL ネイ?ブ???タを???ローカルクラスです?
372     * こ?クラスでは、コメント行?スキ??判定?ヘッ??部のカラ?取得?
373     * 行情報(Row)から、カラ??配?の取得などを行います?
374     *
375     * @og.rev 3.5.4.8 (2004/02/23) 新規追?
376     * @og.group ファイル入?
377     *
378     * @version  4.0
379     * @author   儲
380     * @since    JDK5.0,
381     */
382    class HeaderData {
383            private String[] names ;
384    //      private short[]  index;
385            private int[]    index; // 4.3.4.0 (2008/12/01) POI3.2対?
386            private int              columnSize = 0;
387            private boolean  nameNoSet = true;
388            private boolean  useNumber = true;
389            private boolean  isDebug   = false;             // 5.5.8.2 (2012/11/09)
390    
391            private String[] orgNames ;                     // 5.5.1.2 (2012/04/06) オリジナルのカラ?
392            private Cell     lastCell = null;       // 5.5.1.2 (2012/04/06) ?に実行して?セルを保持(エラー時に使用する?
393    
394            // 5.5.8.2 (2012/11/09) 固定?のカラ?、DBTableModelのアドレス、Sheetの?列番号
395            private int              cnstLen = 0;           // 初期値=0 の場合?、固定?を使わな??事?
396            private String[] cnstKeys ;
397            private int[]    cnstIndx ;
398            private int[]    cnstRowNo;
399            private int[]    cnstClmNo;
400            private String[] cnstVals ;                     // Sheet単位?固定?のキャ?ュ(シート???に値を取得して保持しておく)
401    
402            /**
403             * ????を?出力するかど?[true/false]を指定しま?初期値:false)?
404             *
405             * 初期値は、false(出力しな? です?
406             *
407             * @og.rev 5.5.8.2 (2012/11/09) 新規作?
408             *
409             * @param       isDebug ???? [true:出力す?false:出力しない]
410             */
411            void setDebug( final boolean isDebug ) {
412                    this.isDebug = isDebug ;
413            }
414    
415            /**
416             * 行番号??を?使用して?かど?[true/false]を指定しま?初期値:true)?
417             *
418             * 初期値は、true(使用する) です?
419             *
420             * @og.rev 5.1.6.0 (2010/05/01) 新規作?
421             *
422             * @param       useNumber       行番号?? [true:使用して?/false:して?い]
423             */
424            void setUseNumber( final boolean useNumber ) {
425                    this.useNumber = useNumber ;
426            }
427    
428            /**
429             * 固定?となるカラ?(CSV形?と、constAdrs 固定?となるアドレス(????・・・)を設定します?
430             *
431             * @param       constKeys       固定?となるカラ?(CSV形?
432             * @param       constAdrs       固定?となるアドレス(????・・・)
433             *
434             * @og.rev 5.5.8.2 (2012/11/09) 新規追?
435             */
436            public void setSheetConstData( final String constKeys,final String constAdrs ) {
437                    if( constKeys == null || constKeys.isEmpty() ) {
438                            return ;
439                    }
440    
441                    cnstKeys  = constKeys.split( "," );
442                    cnstLen   = cnstKeys.length;
443                    cnstIndx  = new int[cnstLen];
444                    cnstRowNo = new int[cnstLen];
445                    cnstClmNo = new int[cnstLen];
446    
447                    String[] row_col = constAdrs.split( "," ) ;
448                    cnstRowNo = new int[cnstLen];
449                    cnstClmNo = new int[cnstLen];
450                    for( int j=0; j<cnstLen; j++ ) {
451                            cnstKeys[j] = cnstKeys[j].trim();               // 前後?不要なスペ?スを削除
452                            String rowcol = row_col[j].trim();              // 前後?不要なスペ?スを削除
453    
454                            int sep = rowcol.indexOf( '-' );
455                            cnstRowNo[j] = Integer.parseInt( rowcol.substring( 0,sep ) );
456                            cnstClmNo[j] = Integer.parseInt( rowcol.substring( sep+1 ) );
457    
458                            if( isDebug ) {
459                                    System.out.println( " Debug: constKey=" + cnstKeys[j] + " : RowNo= " + cnstRowNo[j] + " , ClmNo=" + cnstClmNo[j] );
460                            }
461                    }
462            }
463    
464            /**
465             * カラ?を外部から?します?
466             * カラ?が?NULL でなければ?NAME より、こちらが優先されます?
467             * カラ?は??番に、指定する?があります?
468             *
469             * @og.rev 5.1.6.0 (2010/05/01) 新規作?
470             * @og.rev 5.5.8.2 (2012/11/09) 固定?取得用の cnstIndx の設定を行う?
471             *
472             * @param       columns EXCELのカラ??(CSV形?
473             *
474             * @return true:処?施/false:無処?
475             */
476            boolean setColumns( final String columns ) {
477                    if( columns != null && columns.length() > 0 ) {
478                            names = StringUtil.csv2Array( columns );
479                            columnSize = names.length ;
480                            index = new int[columnSize];
481                            int adrs = (useNumber) ? 1:0 ;  // useNumber =true の場合??件目(No)は読み飛?す?
482                            // 5.5.8.2 (2012/11/09) 固定?取得用の cnstIndx の設定を行う?
483    //                      for( int i=0; i<columnSize; i++ ) { index[i] = adrs++; }
484                            for( int i=0; i<columnSize; i++ ) {
485                                    index[i] = adrs++;
486                                    for( int j=0; j<cnstLen; j++ ) {
487                                            if( names[i].equalsIgnoreCase( cnstKeys[j] ) ) {
488                                                    cnstIndx[j] = index[i];
489                                            }
490                                    }
491                            }
492                            nameNoSet = false;
493    
494                            return true;
495                    }
496                    return false;
497            }
498    
499            /**
500             * EXCEL ネイ?ブ???タを???ローカルクラスです?
501             * こ?クラスでは、コメント行?スキ??判定?ヘッ??部のカラ?取得?
502             * 行情報(Row)から、カラ??配?の取得などを行います?
503             *
504             * @og.rev 4.3.4.0 (2008/12/01) POI3.2対?
505             *
506             * @param oRow Row EXCELの行オブジェク?
507             *
508             * @return true:コメント?false:通常?
509             */
510    //      boolean isSkip( HSSFRow oRow ) {
511            boolean isSkip( Row oRow ) {
512                    if( oRow == null ) { return true; }
513    
514    //              short nFirstCell = oRow.getFirstCellNum();
515                    int nFirstCell = oRow.getFirstCellNum();
516    //              HSSFCell oCell = oRow.getCell(nFirstCell);
517                    Cell oCell = oRow.getCell(nFirstCell);
518                    String strText =  getValue( oCell );
519                    if( strText != null && strText.length() > 0 ) {
520                            if( nameNoSet ) {
521                                    if( strText.equalsIgnoreCase( "#Name" ) ) {
522                                            makeNames( oRow );
523                                            nameNoSet = false;
524                                            return true;
525                                    }
526                                    else if( strText.charAt( 0 ) == '#' ) {
527                                            return true;
528                                    }
529                                    else {
530                                            String errMsg = "#NAME が見つかる前に??タが見つかりました?
531                                                                            + HybsSystem.CR
532                                                                            + "可能性として、ファイルが?ネイ?ブExcelでな?が?られます?"
533                                                                            + HybsSystem.CR ;
534                                            throw new HybsSystemException( errMsg );
535                                    }
536                            }
537                            else {
538                                    if( strText.charAt( 0 ) == '#' ) {
539                                            return true;
540                                    }
541                            }
542                    }
543    
544                    return nameNoSet ;
545            }
546    
547            /**
548             * EXCEL ネイ?ブ?行情報(Row)からカラ???を取得します?
549             *
550             * @og.rev 4.3.4.0 (2008/12/01) POI3.2対?
551             * @og.rev 5.1.6.0 (2010/05/01) useNumber(行番号??を?使用して?(true)/して??false)を指?
552             * @og.rev 5.1.6.0 (2010/05/01) useNumber(行番号??を?使用して?(true)/して??false)を指?
553             * @og.rev 5.5.1.2 (2012/04/06) オリジナルのカラ?を取?
554             * @og.rev 5.5.8.2 (2012/11/09) 固定?取得用の cnstIndx の設定を行う?
555             *
556             * @param oRow Row EXCELの行オブジェク?
557             */
558    //      private void makeNames( final HSSFRow oRow ) {
559            private void makeNames( final Row oRow ) {
560                    // 先?カラ???NAME 属?行であるかど?を?useNumber で判定しておく?
561                    short nFirstCell = (short)( (useNumber) ? 1:0 );
562    //              short nFirstCell = oRow.getFirstCellNum();
563                    short nLastCell  = oRow.getLastCellNum();
564    
565                    orgNames = new String[nLastCell+1];             // 5.5.1.2 (2012/04/06) オリジナルのカラ?を取?
566    
567                    int maxCnt = nLastCell - nFirstCell;
568                    String[] names2 = new String[maxCnt];
569    //              short[]  index2 = new short[maxCnt];
570                    int[]  index2 = new int[maxCnt];
571    
572                    // 先?カラ???NAME 属?行である?+ で、?進めて??
573    //              for( short nIndexCell = ++nFirstCell; nIndexCell <= nLastCell; nIndexCell++) {
574    //              for( int nIndexCell = ++nFirstCell; nIndexCell <= nLastCell; nIndexCell++) {
575                    // 先?カラ???NAME 属?行であるかど?を?useNumber で判定しておく?
576                    for( int nIndexCell = nFirstCell; nIndexCell <= nLastCell; nIndexCell++) {
577    //                      HSSFCell oCell = oRow.getCell(nIndexCell);
578                            Cell oCell = oRow.getCell(nIndexCell);
579                            String strText = getValue( oCell );
580    
581                            orgNames[nIndexCell] = strText;         // 5.5.1.2 (2012/04/06) オリジナルのカラ?を取?
582    
583                            // #NAME 行が、ゼロ??の場合?、読み飛?す?
584                            if( strText != null && strText.length() > 0 ) {
585                                    names2[columnSize] = strText;
586                                    index2[columnSize] = nIndexCell;
587                                    columnSize++;
588                            }
589                    }
590    
591                    // #NAME を使用しな??合:no?存在しな?ース
592                    if( maxCnt == columnSize ) {
593                            names = names2;
594                            index = index2;
595                    }
596                    else {
597                            names = new String[columnSize];
598    //                      index = new short[columnSize];
599                            index = new int[columnSize];
600                            System.arraycopy(names2, 0, names, 0, columnSize);
601                            System.arraycopy(index2, 0, index, 0, columnSize);
602                    }
603    
604                    // 5.5.8.2 (2012/11/09) 固定?取得用の cnstIndx の設定を行う?
605                    if( cnstLen > 0 ) {
606                            for( int i=0; i<columnSize; i++ ) {
607                                    for( int j=0; j<cnstLen; j++ ) {
608                                            if( names[i].equalsIgnoreCase( cnstKeys[j] ) ) {
609                                                    cnstIndx[j] = index[i];
610                                            }
611                                    }
612                            }
613                    }
614            }
615    
616            /**
617             * カラ???を返します?
618             * ここでは、?部配?をそのまま返します?
619             *
620             * @return String[] カラ??配???
621             */
622            String[] getNames() {
623                    return names;
624            }
625    
626            /**
627             * カラ?イズを返します?
628             *
629             * @return      カラ?イズ
630             */
631            int getColumnSize() {
632                    return columnSize;
633            }
634    
635            /**
636             * Sheet単位?固定?のキャ?ュ(シート???に値を取得して保持しておく)を設定します?
637             * これは、シートチェンジの??に?呼び出しておくことで、それ以降?列取得時に
638             * 固定?を利用することで処??度向上を目?ます?
639             *
640             * @og.rev 5.5.8.2 (2012/11/09) 新規作?
641             *
642             * @param sheet Sheet EXCELのSheetオブジェク?
643             */
644            public void setSheetConstValues( final Sheet sheet ) {
645                    cnstVals = new String[cnstLen];
646                    for( int j=0; j<cnstLen; j++ ) {
647                            Row  oRow  = sheet.getRow( cnstRowNo[j] );
648                            Cell oCell = oRow.getCell( cnstClmNo[j] );
649                            cnstVals[j] = getValue( oCell );
650    
651                            if( isDebug ) {
652                                    System.out.println( " Debug: Sheet=" + sheet.getSheetName() + " : RowNo= " + cnstRowNo[j] + " , ClmNo=" + cnstClmNo[j] + " , " + cnstKeys[j] + "=" + cnstVals[j] );
653                            }
654                    }
655            }
656    
657            /**
658             * カラ???を返します?
659             *
660             * @og.rev 5.5.8.2 (2012/11/09) 固定?の設定を行う?
661             *
662             * @param oRow Row EXCELの行オブジェク?
663             *
664             * @return String[] カラ??配???
665             */
666    //      String[] row2Array( final HSSFRow oRow ) {
667            String[] row2Array( final Row oRow ) {
668                    if( nameNoSet ) {
669                            String errMsg = "#NAME が見つかる前に??タが見つかりました?;
670                            throw new HybsSystemException( errMsg );
671                    }
672    
673                    String[] data = new String[columnSize];
674                    for( int i=0;i<columnSize; i++ ) {
675    //                      HSSFCell oCell = oRow.getCell( index[i] );
676                            Cell oCell = oRow.getCell( index[i] );
677                            data[i] = getValue( oCell );
678                    }
679    
680                    // 5.5.8.2 (2012/11/09) 固定?の設定を行う?
681                    for( int j=0; j<cnstLen; j++ ) {
682                            data[cnstIndx[j]] = cnstVals[j];
683                    }
684                    return data;
685            }
686    
687            /**
688             * セルオブジェク?Cell)から値を取り?します?
689             *
690             * @og.rev 3.8.5.3 (2006/08/07) 取り出し方法を少し修正
691             * @og.rev 5.5.1.2 (2012/04/06) フォーマットセルを実行して、その結果を?帰?処?る?
692             *
693             * @param oCell Cell EXCELのセルオブジェク?
694             *
695             * @return      セルの値
696             */
697    //      private String getValue( final Cell oCell ) {
698            private String getValue( final Cell oCell ) {
699                    lastCell = oCell;       // 5.5.1.2 (2012/04/06) 今から実行するセルを取得しておきます?
700    
701                    if( oCell == null ) { return null; }
702    
703                    String strText = "";
704    //              HSSFRichTextString richText;
705                    RichTextString richText;
706                    int nCellType = oCell.getCellType();
707                    switch(nCellType) {
708    //                      case HSSFCell.CELL_TYPE_NUMERIC:
709                            case Cell.CELL_TYPE_NUMERIC:
710                                            strText = getNumericTypeString( oCell );
711                                            break;
712    //                      case HSSFCell.CELL_TYPE_STRING:
713                            case Cell.CELL_TYPE_STRING:
714            // POI3.0               strText = oCell.getStringCellValue();
715                                            richText = oCell.getRichStringCellValue();
716                                            if( richText != null ) {
717                                                    strText = richText.getString();
718                                            }
719                                            break;
720    //                      case HSSFCell.CELL_TYPE_FORMULA:
721                            case Cell.CELL_TYPE_FORMULA:
722            // POI3.0               strText = oCell.getStringCellValue();
723                                            // 5.5.1.2 (2012/04/06) フォーマットセルを実行して、その結果を?帰?処?る?
724                                            Workbook wb = oCell.getSheet().getWorkbook();
725                                            CreationHelper crateHelper = wb.getCreationHelper();
726                                            FormulaEvaluator evaluator = crateHelper.createFormulaEvaluator();
727    
728                                            try {
729                                                    strText = getValue(evaluator.evaluateInCell(oCell));
730                                            }
731                                            catch ( Throwable th ) {
732    //                                              String errMsg = "セルフォーマットが解析できません?" + String.valueOf(oCell.getCellFormula()) + "]"
733                                                    String errMsg = "セルフォーマットが解析できません?" + oCell.getCellFormula() + "]"
734                                                                            + getLastCellMsg();
735                                                    throw new HybsSystemException( errMsg,th );
736                                            }
737                                            break;
738    
739    //                                      richText = oCell.getRichStringCellValue();
740    //                                      if( richText != null ) {
741    //                                              strText = richText.getString();
742    //                                      }
743    //                                      else {
744    //                                              strText = getNumericTypeString( oCell );
745    //                                      }
746    //                                      break;
747    //                      case HSSFCell.CELL_TYPE_BOOLEAN:
748                            case Cell.CELL_TYPE_BOOLEAN:
749                                            strText = String.valueOf(oCell.getBooleanCellValue());
750                                            break;
751    //                      case HSSFCell.CELL_TYPE_BLANK :
752    //                      case HSSFCell.CELL_TYPE_ERROR:
753                            case Cell.CELL_TYPE_BLANK :
754                            case Cell.CELL_TYPE_ERROR:
755                                            break;
756                            default :
757                                    break;
758                    }
759                    return strText.trim();
760            }
761    
762            /**
763             * セル値が数字?場合に、数字か日付かを判断して、対応する文字?を返します?
764             *
765             * @og.rev 3.8.5.3 (2006/08/07) 新規追?
766             * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正します?
767             *
768             * @param oCell Cell
769             *
770             * @return      数字?場合?、文字?に変換した結果を?日付?場合??yyyyMMddHHmmss" 形式で返します?
771             */
772    //      private String getNumericTypeString( final HSSFCell oCell ) {
773            private String getNumericTypeString( final Cell oCell ) {
774                    final String strText ;
775    
776                    double dd = oCell.getNumericCellValue() ;
777    //              if( HSSFDateUtil.isCellDateFormatted( oCell ) ) {
778                    if( DateUtil.isCellDateFormatted( oCell ) ) {
779                            strText = HybsDateUtil.getDate( DateUtil.getJavaDate( dd ).getTime() , "yyyyMMddHHmmss" );      // 5.5.7.2 (2012/10/09) HybsDateUtil を利用
780    
781    //                      DateFormat dateFormat = new SimpleDateFormat( "yyyyMMddHHmmss",Locale.JAPAN );
782    // //                   strText = dateFormat.format( HSSFDateUtil.getJavaDate( dd ) );
783    //                      strText = dateFormat.format( DateUtil.getJavaDate( dd ) );
784                    }
785                    else {
786                            NumberFormat numFormat = NumberFormat.getInstance();
787                            if( numFormat instanceof DecimalFormat ) {
788                                    ((DecimalFormat)numFormat).applyPattern( "#.####" );
789                            }
790                            strText = numFormat.format( dd );
791                    }
792                    return strText ;
793            }
794    
795            /**
796             * ?に実行して?セル??を返します?
797             *
798             * エラー発生時に、どのセルでエラーが発生したかの??を取得できるようにします?
799             *
800             * @og.rev 5.5.1.2 (2012/04/06) 新規追?
801             * @og.rev 5.5.8.2 (2012/11/09) エラー??に、シート名も追?
802             *
803             * @return      ?に実行して?セル??の??
804             */
805            String getLastCellMsg() {
806                    String lastMsg = null;
807    
808                    if( lastCell != null ) {
809                            int rowNo = lastCell.getRowIndex();
810                            int celNo = lastCell.getColumnIndex();
811                            int no = lastCell.getColumnIndex();
812                            String shtNm = lastCell.getSheet().getSheetName();
813    
814    
815                            lastMsg = "Sheet=" + shtNm + ", Row=" + rowNo + ", Cel=" + celNo ;
816                            if( orgNames != null && orgNames.length < no ) {
817                                    lastMsg = lastMsg + ", NAME=" + orgNames[no] ;
818                            }
819                    }
820                    return lastMsg;
821            }
822    }