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