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