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.fukurou.util.Closer ;
019    import org.opengion.fukurou.util.LogWriter;
020    
021    import org.apache.poi.poifs.filesystem.POIFSFileSystem;
022    import org.apache.poi.hssf.eventusermodel.HSSFRequest ;
023    import org.apache.poi.hssf.eventusermodel.HSSFEventFactory;
024    import org.apache.poi.hssf.eventusermodel.HSSFListener ;
025    import org.apache.poi.hssf.record.SSTRecord ;
026    import org.apache.poi.hssf.record.Record ;
027    import org.apache.poi.hssf.record.BOFRecord  ;
028    import org.apache.poi.hssf.record.BoundSheetRecord;
029    import org.apache.poi.hssf.record.LabelSSTRecord;
030    import org.apache.poi.hssf.record.UnicodeString;
031    // import org.apache.poi.hssf.record.common.UnicodeString;              // X.X.X.X (2012/XX/XX) POI3.0ã®å ´å?
032    
033    import java.io.File;
034    import java.io.InputStream;
035    import java.io.FileInputStream;
036    import java.io.IOException;
037    
038    /**
039     * ã€EXCELå–込】雛形EXCELシートã?è§£æžå?ç?‚’行ã†ç‚ºã®ã€HSSFListener 拡張クラスã§ã™ã?
040     * ã“ã?オブジェクトã?ã€HSSFRequest クラス㮠addListenerForAllRecords メソãƒ?ƒ‰ã«æ¸¡ã?
041     * HSSFListener インターフェースを実è£?—ã¦ã?¾ã™ã?ã¾ãŸã?雛形EXCEL ã‚’å?ç?¾Œã?ExcelLayout
042     * 管ç?‚¯ãƒ©ã‚¹ã‚’å–å¾—ã™ã‚‹ã“ã¨ãŒå?æ¥ã¾ã™ã?
043     *
044     * @og.rev 3.8.0.0 (2005/06/07) æ–°è¦è¿½åŠ?
045     * @og.group 帳票シスãƒ?ƒ 
046     *
047     * @version  4.0
048     * @author   Kazuhiko Hasegawa
049     * @since    JDK5.0,
050     */
051    public class HybsHSSFListener implements HSSFListener {
052            private SSTRecord sstrec;
053            private int       sheetNo = -1;
054            private int       sheetSize = 0;
055            private boolean   trace  = false;
056    
057            private ExcelLayout laynot = null;
058    
059            /**
060             * 雛形EXCELã® {@カラãƒ? è§£æžæƒ…報を設定ã—ã¾ã™ã?
061             *
062             * 雛形EXCELã¯ã€HSSFListener を使用ã—ã¦ã€ã‚¤ãƒ™ãƒ³ãƒˆé§?‹•ã§å–å¾—ã—ã¾ã™ã?ãã?å ´åˆã?
063             * {@カラãƒ?ã‚’å«ã‚?‚»ãƒ«ã‚’見ã¤ã‘る都度ã€ã“ã®ãƒ¡ã‚½ãƒ?ƒ‰ã‚’呼ã³å‡ºã—ã¦ã€{@カラãƒ?ã®
064             * ä½ç½®(行å?番å·)を設定ã—ã¾ã™ã?
065             * ãƒ??ã‚¿EXCELã‹ã‚‰ãƒ??タを読ã¿å‡ºã™å?åˆã?ã€ã“ã“ã§ç™»éŒ²ã—ãŸã‚«ãƒ©ãƒ??行å?よりã€èª­ã¿è¾¼ã¿ã¾ã™ã?
066             * 具体的ã«ã¯ã€HSSFListener#processRecord( Record )ã§ã€SSTRecord.sid ã® æƒ??をキープã—ã¦ãŠãã€?
067             * LabelSSTRecord.sid 毎ã«ã€{@カラãƒ?ã‚’å«ã‚?‹ãƒã‚§ãƒ?‚¯ã—ã?å«ã‚??åˆã«ã€ã“ã®ãƒ¡ã‚½ãƒ?ƒ‰ã«
068             * è§£æžæƒ…報を設定ã—ã¾ã™ã?
069             *
070             * @og.rev 4.3.4.0 (2008/12/01) POI3.2対å¿?引数ã®åž‹å¤‰æ›´(SSTRecord ã® toString() åŒ?
071             *
072             * @param record Recordオブジェク�
073             */
074            public void processRecord( final Record record ) {
075                    switch ( record.getSid() ) {
076                            // Workbook ã§ã® シート毎ã«å‘¼ã°ã‚Œã¾ã™ã?先行ã™ã‚‹ãŸã‚ã?ã“ã?回数をシート数ã¨ã—ã¦æ•°ãˆã¾ã™ã?
077                            case BoundSheetRecord.sid:
078                                    // 4.0.0.0 (2007/11/29) 入れå­if ã®çµ±å?
079                                    if( trace && record instanceof BoundSheetRecord ) {
080                                            BoundSheetRecord bsr = (BoundSheetRecord) record;
081                                            System.out.println("Sheet named: " + bsr.getSheetname() );
082                                    }
083                                    sheetSize ++ ;
084                                    break;
085                            // TYPE_WORKSHEET ã®å ´åˆã?シート開始毎ã«å‘¼ã°ã‚Œã¾ã™ã?
086                            case BOFRecord.sid:
087                                    if( record instanceof BOFRecord ) {
088                                            BOFRecord bof = (BOFRecord) record;
089                                            if(bof.getType() == BOFRecord.TYPE_WORKBOOK) {
090                                                    if( trace ) { System.out.println("Encountered workbook"); }
091                                            }
092                                            else if(bof.getType() == BOFRecord.TYPE_WORKSHEET) {
093                                                    // シート開始毎ã«å‘¼ã°ã‚Œã‚‹ãŸã‚ã€ç¾åœ¨ã®ã‚·ãƒ¼ãƒˆç•ªå·ã‚’å¾—ã‚‹ã®ã«ä½¿ç”¨ã—ã¾ã™ã?
094                                                    sheetNo++ ;
095                                                    if( trace ) { System.out.println("Encountered sheet [" + sheetNo + "]" ); }
096                                            }
097                                    }
098                                    break;
099                            // ã™ã¹ã¦ã®ãƒ¬ã‚³ãƒ¼ãƒ‰ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ãŸã‚ã«ã€ä¸?º¦ã?‘呼ã°ã‚Œã¾ã™ã?ã“ã“ã§åˆæœŸåŒ–ã—ã¦ãŠãã¾ã™ã?
100                            case SSTRecord.sid:
101                                    if( record instanceof SSTRecord ) {
102                                            sstrec = (SSTRecord) record;
103                                            laynot = new ExcelLayout( sheetSize );
104                                            if( trace ) { System.out.println( "SSTRecord:[" + sstrec.getNumUniqueStrings() + "]" ); }
105                            //              for( int k=0; k<sstrec.getNumUniqueStrings(); k++ )  {
106                            //                      String val = sstrec.getString(k);
107                            //                      System.out.println("SSTRecord id=[" + k + "]=[" + val + "]" );
108                            //              }
109                                    }
110                                    break;
111                            // æ–?­—åž‹ã®ãƒ¬ã‚³ãƒ¼ãƒ‰ã§ã™ã?
112                            case LabelSSTRecord.sid:
113                                    if( record instanceof LabelSSTRecord ) {
114                                            LabelSSTRecord lrec = (LabelSSTRecord) record;
115    
116                                            int   row  = lrec.getRow();
117                                            short col  = lrec.getColumn();
118    // POI3.0ã®å ´å? String val = sstrec.getString( lrec.getSSTIndex() ) ;
119                                            UnicodeString ustr = sstrec.getString( lrec.getSSTIndex() ) ;
120                                            String val = ustr.getString();
121    
122                                            // カラãƒ?«ã€{@ã‚’å«ã‚??åˆã?ã€laynot ã«é››å½¢æƒ??を追åŠ?—ã¾ã™ã?
123                                            // æ•´åˆæ?ãƒã‚§ãƒ?‚¯ã¯ã€ExcelLayoutData クラスã§è¡Œã„ã¾ã™ã?
124                                            if( val != null && val.indexOf( "{@" ) >= 0 ) {
125                                                    if( trace ) { System.out.println("String cell id,sheet,row,col=[" + lrec.getSSTIndex() + "," + sheetNo + "," + row + "," + col + "] => " + val ); }
126                                                    laynot.addModel( sheetNo,val,row,col );
127                                            }
128                                    }
129                                    break;
130                            default :
131                                    LogWriter.log( "想定外ã?イベントをå—ã‘å–りã¾ã—ãŸã€?[" + record.getSid() + "]" );
132                                    break;
133                    }
134            }
135    
136            /**
137             * 雛形EXCELシートã? {&#064;カラãƒ? è§£æžãƒ‡ãƒ¼ã‚¿ç®¡ç?‚¯ãƒ©ã‚¹ã‚’è¿”ã—ã¾ã™ã?
138             *
139             * 雛形EXCELã‚’è§£æžã—終ã‚ã£ãŸå¾Œã§ã€è§£æžãƒ‡ãƒ¼ã‚¿ç®¡ç?‚¯ãƒ©ã‚¹ã‚’å–りå?ã—ã¾ã™ã?
140             * 雛形EXCELã¨ã€ãƒ‡ãƒ¼ã‚¿EXCELãŒï¼‘対?‘ã§ã¯ãªã?Ÿã‚ã?リアルタイãƒ??ç?Œå‡ºæ¥ã¾ã›ã‚“ã€?
141             * ä¸?—¦ã€ã™ã¹ã¦ã®é››å½¢EXCELã‚’è§£æžã—終ã‚ã£ãŸå¾Œã§ã€ãƒ‡ãƒ¼ã‚¿EXCEL処ç?‚’行ã†å¿?¦ãŒã‚りã¾ã™ã?
142             *
143             * @return      雛形EXCELシー�
144             */
145            public ExcelLayout getLayout() { return laynot; }
146    
147            /**
148             * 雛形EXCEL ã®ã‚·ãƒ¼ãƒˆæ•°ã‚’è¿”ã—ã¾ã™ã?
149             *
150             * @return      雛形シート数
151             */
152            public int getSheetSize() { return sheetSize; }
153    
154            /**
155             * 処ç?µŒéŽæƒ??を表示ã™ã‚‹ã‹ã©ã?‹[true/false]を指定ã—ã¾ã?åˆæœŸå€¤:false)
156             *
157             * イベント毎ã?状æ³ã‚’ã€æ¨™æº–å?力ã«å‡ºåŠ›ã™ã‚‹ã‹ã©ã?‹ã®ãƒ•ラグã§ã™ã?
158             * åˆæœŸå€¤ã¯ã€false ã§ã™ã?
159             *
160             * @param       flag    処ç?µŒéŽæƒ??を表示ã™ã‚‹ã‹ã©ã?‹[true/false]
161             */
162            public void setTrace( final boolean flag ) { trace = flag; }
163    
164            /**
165             * EXCELレイアウト情報をå–å¾—ã—ã¾ã™ã?
166             *
167             * POIã®ã‚¤ãƒ™ãƒ³ãƒˆå?ç?HSSFListener)ã§ã€å„イベントã”ã¨ã«å‡¦ç?‚’行ã„ã¾ã™ã?
168             * イベントã?ã€BOFRecordã€BoundSheetRecordã€SSTRecordã€LabelSSTRecord ã«ã¤ã?¦
169             * 発生ã™ã‚‹ã‚ˆã?«è¨­å®šã—ã¦ã?¾ã™ã?
170             *
171             * @param       file    処�るEXCELファイル
172             * @param       trace   標準å?力ã«ãƒˆãƒ¬ãƒ¼ã‚¹æƒ??ã‚’å?力ã™ã‚‹ã‹ã©ã?‹ã‚’指定ã—ã¾ã™ã?
173             *
174             * @return      EXCELレイアウト情報
175             * @throws IOException 入出力エラーãŒç™ºç”Ÿã—ãŸå?å?
176             */
177            public static ExcelLayout makeExcelLayout( final File file ,final boolean trace ) throws IOException {
178    
179                    FileInputStream fin = null;
180                    InputStream din = null;
181                    final HybsHSSFListener event ;
182                    try {
183                            fin = new FileInputStream( file );
184                            POIFSFileSystem poifs = new POIFSFileSystem( fin );
185                            din = poifs.createDocumentInputStream( "Workbook" );
186                            HSSFRequest req = new HSSFRequest();
187    
188                            event = new HybsHSSFListener();
189                            event.setTrace( trace );                // 標準å?力ã«ãƒˆãƒ¬ãƒ¼ã‚¹æƒ??ã‚’å?力ã—ã¾ã™ã?
190    
191                    //      req.addListenerForAllRecords( event );  // 全イベントを処ç?
192                            req.addListener( event,BOFRecord.sid );
193                            req.addListener( event,BoundSheetRecord.sid );
194                            req.addListener( event,SSTRecord.sid );
195                            req.addListener( event,LabelSSTRecord.sid );
196    
197                            HSSFEventFactory factory = new HSSFEventFactory();
198                            factory.processEvents( req,din );
199                    }
200                    finally {
201                            Closer.ioClose( fin );          // 4.0.0 (2006/01/31) close 処ç?™‚ã® IOException ã‚’ç„¡è¦?
202                            Closer.ioClose( din );          // 4.0.0 (2006/01/31) close 処ç?™‚ã® IOException ã‚’ç„¡è¦?
203            //              fin.close();
204            //              din.close();
205                    }
206    
207                    return event.getLayout();
208            }
209    }