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.hayabusa.report;
017    
018    import org.opengion.hayabusa.common.HybsSystemException;
019    import org.opengion.fukurou.util.StringUtil;
020    import org.opengion.fukurou.util.HybsDateUtil ;
021    import org.opengion.fukurou.util.Closer ;
022    
023    import org.apache.poi.poifs.filesystem.POIFSFileSystem;
024    import org.apache.poi.hssf.record.RecordFormatException;
025    
026    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
027    import org.apache.poi.hssf.usermodel.HSSFSheet;
028    import org.apache.poi.hssf.usermodel.HSSFRow;
029    import org.apache.poi.hssf.usermodel.HSSFCell;
030    import org.apache.poi.hssf.usermodel.HSSFDateUtil;
031    import org.apache.poi.hssf.usermodel.HSSFRichTextString;
032    
033    import java.io.File;
034    import java.io.InputStream;
035    import java.io.FileInputStream;
036    import java.io.IOException;
037    
038    // import java.text.DateFormat;
039    // import java.text.SimpleDateFormat;
040    // import java.util.Locale ;
041    import java.text.NumberFormat ;
042    import java.text.DecimalFormat ;
043    import java.util.Iterator ;
044    
045    /**
046     * 【EXCEL取込】雛形EXCELシート?解析??行う為の、HSSFListener 拡張クラスです?
047     * こ?オブジェクト?、HSSFRequest クラスの addListenerForAllRecords メソ?に渡?
048     * HSSFListener インターフェースを実?て?す?また?雛形EXCEL を???ExcelLayout
049     * 管?ラスを取得することが?来ます?
050     *
051     *   ※ ?のPOIでは、org.apache.poi.ss.usermodel を使?で?003形式?2007形式に対応させます?
052     *      report パッケージは保守対象外なので、あえて修正しません?
053     *
054     * @og.rev 3.8.0.0 (2005/06/07) 新規追?
055     * @og.group 帳票シス?
056     *
057     * @version  4.0
058     * @author   Kazuhiko Hasegawa
059     * @since    JDK5.0,
060     */
061    public class ExcelDataPickup {
062    
063            private final ExcelLayout       layout  ;
064    //      private final File                      filename;
065    
066            private final InputStream       in;
067            private final HSSFWorkbook      wb;
068    //      private DateFormat   dateFormat = null;                 // 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正
069            private NumberFormat numFormat  = null;
070    
071            private final boolean    debug;
072    
073            /**
074             * 雛形EXCELを??みのExcelLayoutオブジェクトと?
075             * ??タEXCELファイル名よりオブジェクトを構築します?
076             *
077             * ?で、HSSFWorkbook を構築します?
078             *
079             * @param       layout  雛形EXCELを??みのExcelLayoutオブジェク?
080             * @param       filename        ??タEXCELファイル?
081             * @param debug ??フラグ
082             */
083    //      public ExcelDataPickup( final ExcelLayout layout,final File fname, final boolean debug ) {
084            public ExcelDataPickup( final ExcelLayout layout,final File filename, final boolean debug ) {
085                    this.layout     = layout;
086    //              filename        = fname;
087                    this.debug      = debug;
088    
089                    try {
090                            in = new FileInputStream( filename );
091    
092                            POIFSFileSystem fs = new POIFSFileSystem( in );
093                            wb = new HSSFWorkbook( fs );
094                    }
095                    catch (IOException ex) {
096                            String errMsg = "ファイル読込みエラー[" + filename.getName() + "]"  ;
097                            throw new HybsSystemException( errMsg,ex );
098                    }
099                    catch (RecordFormatException ex) {
100                            String errMsg = "無効の形???タが使用されて?す?[" + filename.getName() + "]"
101                                            + "現バ?ジョンのPOIでは読み取ることが?来ません?
102                                            + "例えば、?動フィルタの設定されたシートが含まれる場合などです?" ;
103                            throw new HybsSystemException( errMsg,ex );
104                    }
105            }
106    
107            /**
108             * ??タEXCELファイル名?シート数を返します?
109             *
110             * ?で、HSSFWorkbook を構築します?
111             *
112             * @return      シート数
113             */
114            public int getSheetSize() {
115                    return wb.getNumberOfSheets();
116            }
117    
118            /**
119             * ??タEXCELファイル名???タをピ?ア??します?
120             *
121             * こ?処?行うと、ExcelLayout オブジェクトに??タEXCEL解析結果?
122             * 保存します?で、???でそ?結果を取り?して使用します?
123             *
124             * @og.rev 3.8.1.1 (2005/11/21) ??用コメント修正
125             *
126             * @param       modelSheetNo    雛形シート番号
127             * @param       sheetNo ??タシート番号
128             * @param       loopClm 繰返??カラ?なければ通常の?対???
129             */
130            public void execute( final int modelSheetNo, final int sheetNo, final String loopClm ) {
131    
132                    HSSFSheet sheet = wb.getSheetAt( sheetNo );
133                    layout.dataClear();
134    
135                    if( debug ) { System.out.println( sheetNo + ":" + wb.getSheetName( sheetNo ) ); }
136    
137                    Iterator<ExcelLayoutData> ite = layout.getLayoutDataIterator( modelSheetNo,loopClm ) ;
138                    while( ite.hasNext() ) {
139    //                      ExcelLayoutData data = (ExcelLayoutData)ite.next();
140                            ExcelLayoutData data = ite.next();
141                            String clm  = data.getClm();
142                            int    edbn = data.getEdbn();
143                            int    row  = data.getRowNo();
144                            short  col  = data.getColNo();
145    
146            //              if( clm.indexOf( debugClm ) >= 0 ) { debug = true; }
147            //              else { debug = false; }
148    
149                            String val = getValue( sheet,row,col );
150                            layout.addData( clm,edbn,val );
151                            if( debug ) { System.out.println( data.toString() + "=[" + val + "]" ); }
152                    }
153            }
154    
155            /**
156             * シートオブジェク?HSSFSheet)から行?番号を指定して値を取り?します?
157             * 行オブジェク?HSSFRow)??オブジェク?HSSFCell)が存在しな??合?、nullを返します?
158             * それ以外?、各セルタイプに応じて、??行います?
159             * 関数タイ?HSSFCell.CELL_TYPE_FORMULA)の場合?、まず???として取り出し?ゼロ??の
160             * 場合?、数字タイプとして取り出します?
161             *
162             * @og.rev 3.8.0.9 (2005/10/17) 結果?rtrim(右スペ?ス削除)します?
163             * @og.rev 3.8.1.1 (2005/11/21) ??用コメント修正
164             * @og.rev 3.9.0.5 (2008/11/27) POI3.2対?引数の型変更(short->int)
165             *
166             * @param       sheet   EXCELのシートオブジェク?
167             * @param       row             行番号
168             * @param       col             列番号
169             *
170             * @return      セルの値
171             */
172    //      private String getValue( final HSSFSheet sheet,final int row, final short col ) {
173            private String getValue( final HSSFSheet sheet,final int row, final int col ) {
174    
175                    HSSFRow  oRow  = sheet.getRow(row);
176                    if( oRow == null ) { return null; }
177                    HSSFCell oCell = oRow.getCell(col);
178                    if( oCell == null ) { return null; }
179    
180                    String strText = "";
181                    HSSFRichTextString richText ;
182                    int nCellType = oCell.getCellType();
183                    switch( nCellType ) {
184                            case HSSFCell.CELL_TYPE_NUMERIC:
185                                            strText = getNumericTypeString( oCell );
186                                            break;
187                            case HSSFCell.CELL_TYPE_STRING:
188            // POI3.0               strText = oCell.getStringCellValue();
189                                            richText = oCell.getRichStringCellValue();
190                                            strText =  richText.getString();
191                                            if( debug ) { System.out.print( "String :" ); }
192                                            break;
193                            case HSSFCell.CELL_TYPE_FORMULA:
194            //                              strText = oCell.getCellFormula();
195            // POI3.0               strText = oCell.getStringCellValue();
196                                            richText = oCell.getRichStringCellValue();
197                                            strText =  richText.getString();
198                                            if( strText == null || strText.length() == 0 ) {
199                                                    strText = getNumericTypeString( oCell );
200                                            }
201                                            else {
202                                                    if( debug ) { System.out.print( "Formula:" ); }
203                                            }
204                                            break;
205                            case HSSFCell.CELL_TYPE_BOOLEAN:
206                                            strText = String.valueOf(oCell.getBooleanCellValue());
207                                            if( debug ) { System.out.print( "Boolean:" ); }
208                                            break;
209                            case HSSFCell.CELL_TYPE_BLANK :
210                                            if( debug ) { System.out.print( "Blank  :" ); }
211                                            break;
212                            case HSSFCell.CELL_TYPE_ERROR :
213                                            if( debug ) { System.out.print( "Error  :" ); }
214                                            break;
215                            default :
216                                            if( debug ) { System.out.print( "Other " + nCellType + ":" ); }
217                                    break;
218                    }
219    
220                    return StringUtil.rTrim( strText );             // 3.8.0.9 (2005/10/17)
221            }
222    
223            /**
224             * セル値が数字?場合に、数字か日付かを判断して、対応する文字?を返します?
225             *
226             * @og.rev 3.8.1.1 (2005/11/21) ??用コメント修正
227             * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正します?
228             *   ※ ?のPOIでは、org.apache.poi.ss.usermodel を使?で?003形式?2007形式に対応させます?
229             *      report パッケージは保守対象外なので、あえて修正しません?
230             *
231             * @param oCell Cellオブジェク?
232             *
233             * @return      数字?場合?、文字?に変換した結果を?日付?場合??yyyyMMddHHmmss" 形式で返します?
234             */
235            private String getNumericTypeString( final HSSFCell oCell ) {
236                    final String strText ;
237    
238                    double dval = oCell.getNumericCellValue() ;
239                    if( HSSFDateUtil.isCellDateFormatted( oCell ) ) {
240                            strText = HybsDateUtil.getDate( HSSFDateUtil.getJavaDate( dval ).getTime() , "yyyyMMddHHmmss" );
241    
242    //                      if( dateFormat == null ) {
243    //                              dateFormat = new SimpleDateFormat( "yyyyMMddHHmmss",Locale.JAPAN );
244    //                      }
245    //                      strText = dateFormat.format( HSSFDateUtil.getJavaDate( dval ) );
246                            if( debug ) { System.out.print( "Date   :" ); }
247                    }
248                    else {
249                            // 3.8.0.9 (2005/10/17) 数字につ?、NumberFormat を行います?
250                            if( numFormat == null ) {
251                                    numFormat = NumberFormat.getInstance();
252                                    if( numFormat instanceof DecimalFormat ) {
253                                            ((DecimalFormat)numFormat).applyPattern( "#.####" );
254                                    }
255                            }
256                            strText = numFormat.format( dval );
257                            if( debug ) { System.out.print( "Numeric:" ); }
258                    }
259                    return strText ;
260            }
261    
262            /**
263             * EXCEL をオープンした InputStream を閉じます?
264             */
265            public void close() {
266                    Closer.ioClose( in );           // 4.0.0 (2006/01/31) close 処?の IOException を無?
267            }
268    }