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