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    }