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.plugin.io;
017    
018    import java.io.PrintWriter;
019    
020    import org.odftoolkit.odfdom.OdfFileDom;
021    import org.odftoolkit.odfdom.doc.OdfSpreadsheetDocument;
022    import org.odftoolkit.odfdom.doc.office.OdfOfficeAutomaticStyles;
023    import org.odftoolkit.odfdom.doc.office.OdfOfficeSpreadsheet;
024    import org.odftoolkit.odfdom.doc.table.OdfTable;
025    import org.odftoolkit.odfdom.doc.table.OdfTableCell;
026    import org.odftoolkit.odfdom.doc.table.OdfTableRow;
027    import org.odftoolkit.odfdom.doc.text.OdfTextParagraph;
028    import org.odftoolkit.odfdom.dom.attribute.office.OfficeValueTypeAttribute;
029    import org.opengion.fukurou.model.NativeType;
030    import org.opengion.fukurou.util.StringUtil;
031    import org.opengion.hayabusa.common.HybsSystemException;
032    import org.opengion.hayabusa.db.DBTableModel;
033    import org.w3c.dom.Node;
034    
035    /**
036     * Calcファイルの書きå?しクラスですã?
037     *
038     * DefaultTableWriter を継承してã�?�¾すã?で?Œラベル?Œ名前,データの出力部のみ
039     * オーバã?ライドして?ŒOpenOfficeのCalcファイルの出力機è?を実現してã�?�¾すã?
040     *
041     * @og.group ファイル出åŠ?
042     *
043     * @version  5.0
044     * @author       Hiroki Nakamura
045     * @since    JDK6.0,
046     */
047    public class TableWriter_Calc extends TableWriter_Default {
048            //* こã?プログラãƒ??VERSIONæ–?­—å?を設定しますã?       {@value} */
049            private static final String VERSION = "5.5.2.6 (2012/05/25)" ;
050    
051            protected OdfSpreadsheetDocument        wb                                      = null;
052            protected OdfTable                                      sheet                           = null;
053            protected OdfFileDom                            contentDom                      = null;
054            protected OdfOfficeSpreadsheet          officeSpreadsheet       = null;
055            protected OdfOfficeAutomaticStyles      contentAutoStyles       = null;
056    
057            protected boolean                                       useNumber                       = true;
058    
059            private String                                  sheetName                       = "Sheet1";
060            private String                                  refSheetName            = null;
061            private String                                  filename                        = null;
062            private String                                  refFilename                     = null;
063    //      private String                                  fontName                        = null;                 // 現時点では未使用
064    //      private short                                   fontPoint                       = -1;                   // 現時点では未使用
065    
066            /**
067             * DBTableModel から å�?½¢式ã?ãƒ??タを作æ?して,PrintWriter に書きå?しますã?
068             * こã?メソãƒ?ƒ‰は、Calc 書きå?し時に使用しますã?
069             *
070             * @see #isExcel()
071             */
072            @Override
073            public void writeDBTable() {
074                    if( !createDBColumn() ) { return; }
075    
076                    useNumber = isUseNumber();
077    
078                    if( filename == null ) {
079                            String errMsg = "ファイルが指定されてã�?�¾せんã€?;
080                            throw new HybsSystemException( errMsg );
081                    }
082    
083                    /* 以下ã?未実è£?***********************************************/
084                    if( isAppend() ) {
085                            String errMsg = "Calcの場合ã?Append利用できませんã€?;
086                            throw new HybsSystemException( errMsg );
087                    }
088    
089                    if( ( refFilename != null && refFilename.length() > 0 ) || ( refSheetName != null && refSheetName.length() >= 0 ) ) {
090                            String errMsg = "Calcの場合ã?,refFilenamerefSheetName利用できませんã€?;
091                            throw new HybsSystemException( errMsg );
092                    }
093    
094            //      if( fontName != null && fontName.length() > 0 ) {
095            //              String errMsg = "Calcの場合ã?fontNameは、利用できませんã€?;
096            //              throw new HybsSystemException( errMsg );
097            //              System.err.println( errMsg );
098            //      }
099    
100            //      if( fontPoint >= 0 ) {
101            //              String errMsg = "Calcの場合ã?fontPointは、利用できませんã€?;
102            //              throw new HybsSystemException( errMsg );
103            //              System.err.println( errMsg );
104            //      }
105                    /* *************************************************************/
106    
107                    // 新規ã?場å�?
108                    try {
109                            wb = OdfSpreadsheetDocument.newSpreadsheetDocument();
110                            // コンãƒ?ƒ³ãƒ??ルートとDOMを取å¾?
111                            contentDom = wb.getContentDom();
112                            officeSpreadsheet = wb.getContentRoot();
113                            contentAutoStyles = contentDom.getOrCreateAutomaticStyles();
114    
115                            // ãƒ?ƒ•ォルトで用意されてã�?‚‹ノã?ドを削除
116                            Node childNode = officeSpreadsheet.getFirstChild();
117                            while( childNode != null ) {
118                                    officeSpreadsheet.removeChild( childNode );
119                                    childNode = officeSpreadsheet.getFirstChild();
120                            }
121                    }
122                    catch( Exception ex ) {
123                            String errMsg = "Calcのæ–?›¸宣è¨?�Œできませんã€?;
124                            throw new HybsSystemException( errMsg, ex );
125                    }
126    
127                    //ãƒ?ƒ•ォルトで用意されてã�?‚‹Styles調整
128                    resetAutoStylesAndMasterStyles();
129    
130                    sheet = new OdfTable( contentDom );
131                    sheet.setTableNameAttribute( sheetName );
132    
133                    super.writeDBTable( null );
134    
135                    officeSpreadsheet.appendChild( sheet );
136    
137                    try {
138                            wb.save( filename );
139                            wb.close();
140                    }
141                    catch( Exception ex ) {
142                            String errMsg = "Calcのæ–?›¸saveができませんã€?;
143                            throw new HybsSystemException( errMsg, ex );
144                    }
145                    finally {
146                            if( null != sheet )     { sheet = null; }
147                            if( null != wb )        { wb = null; }
148                    }
149            }
150    
151            /**
152             * DBTableModel から ãƒ??タを作æ?して,PrintWriter に書きå?しますã?
153             *
154             * @param       writer PrintWriterオブジェクãƒ?
155             */
156            @Override
157            public void writeDBTable( final PrintWriter writer )  {
158                    String errMsg = "こã?クラスでは実è£?�•れてã�?�¾せんã€?;
159                    throw new UnsupportedOperationException( errMsg );
160            }
161    
162            /**
163             * PrintWriter に DBTableModelのラベルæƒ??を書き込みますã?
164             * 第ä¸?‚«ラãƒ?›®は、ラベルæƒ??を示ã�?"#Label" を書き込みますã?
165             * こã?行ã?、å?力形式に無関係に、TableWriter.TAB_SEPARATOR で区åˆ?‚‰れますã?
166             *
167             * @param       table  DBTableModelオブジェクãƒ?
168             * @param       writer PrintWriterオブジェクãƒ?
169             */
170            @Override
171            protected void writeLabel( final DBTableModel table, final PrintWriter writer ) {
172                    OdfTableRow row = new OdfTableRow( contentDom );
173    
174                    if( useNumber ) {
175                            row.appendCell( createTextCell( contentDom, "#Label", false, false ) );
176                    }
177    
178                    for( int i = 0; i < numberOfColumns; i++ ) {
179                            int clm = clmNo[i];
180                            String val = dbColumn[clm].getLabel();
181                            if( i == 0 && !useNumber ) {
182                                    val = "#" + val;
183                            }
184                            row.appendCell( createTextCell( contentDom, val, false, false ) );
185                    }
186                    row.setStyleName( "ro1" );
187                    sheet.appendRow( row );
188            }
189    
190            /**
191             * PrintWriter に DBTableModelのé ?›®名情報を書き込みますã?
192             * 第ä¸?‚«ラãƒ?›®はã€??目名情報を示ã�?"#Name" を書き込みますã?
193             * こã?行ã?、å?力形式に無関係に、TableWriter.TAB_SEPARATOR で区åˆ?‚‰れますã?
194             *
195             * @param       table  DBTableModelオブジェクãƒ?
196             * @param       writer PrintWriterオブジェクãƒ?
197             */
198            @Override
199            protected void writeName( final DBTableModel table, final PrintWriter writer ) {
200                    OdfTableRow row = new OdfTableRow( contentDom );
201    
202                    if( useNumber ) {
203                            row.appendCell( createTextCell( contentDom, "#Name", false, false ) );
204                    }
205    
206                    for( int i = 0; i < numberOfColumns; i++ ) {
207                            int clm = clmNo[i];
208                            String val = table.getColumnName( clm );
209                            if( i == 0 && !useNumber ) {
210                                    val = "#" + val;
211                            }
212                            row.appendCell( createTextCell( contentDom, val, false, false ) );
213                    }
214                    row.setStyleName( "ro1" );
215                    sheet.appendRow( row );
216            }
217    
218            /**
219             * PrintWriter に DBTableModelのサイズæƒ??を書き込みますã?
220             * 第ä¸?‚«ラãƒ?›®は、サイズæƒ??を示ã�?"#Size" を書き込みますã?
221             * こã?行ã?、å?力形式に無関係に、TableWriter.TAB_SEPARATOR で区åˆ?‚‰れますã?
222             *
223             * @param       table  DBTableModelオブジェクãƒ?
224             * @param       writer PrintWriterオブジェクãƒ?
225             */
226            @Override
227            protected void writeSize( final DBTableModel table, final PrintWriter writer ) {
228                    OdfTableRow row = new OdfTableRow( contentDom );
229    
230                    if( useNumber ) {
231                            row.appendCell( createTextCell( contentDom, "#Size", false, false ) );
232                    }
233    
234                    for( int i = 0; i < numberOfColumns; i++ ) {
235                            int clm = clmNo[i];
236                            String val = String.valueOf( dbColumn[clm].getTotalSize() );
237                            if( i == 0 && !useNumber ) {
238                                    val = "#" + val;
239                            }
240                            row.appendCell( createTextCell( contentDom, val, true, false ) );
241                    }
242                    row.setStyleName( "ro1" );
243                    sheet.appendRow( row );
244            }
245    
246            /**
247             * PrintWriter に DBTableModelのクラス名情報を書き込みますã?
248             * 第ä¸?‚«ラãƒ?›®は、サイズæƒ??を示ã�?"#Class" を書き込みますã?
249             * こã?行ã?、å?力形式に無関係に、TableWriter.TAB_SEPARATOR で区åˆ?‚‰れますã?
250             *
251             * @param       table  DBTableModelオブジェクãƒ?
252             * @param       writer PrintWriterオブジェクãƒ?
253             */
254            @Override
255            protected void writeClass( final DBTableModel table, final PrintWriter writer ) {
256                    OdfTableRow row = new OdfTableRow( contentDom );
257    
258                    if( useNumber ) {
259                            row.appendCell( createTextCell( contentDom, "#Class", false, false ) );
260                    }
261    
262                    for( int i = 0; i < numberOfColumns; i++ ) {
263                            int clm = clmNo[i];
264                            String val = dbColumn[clm].getClassName();
265                            if( i == 0 && !useNumber ) {
266                                    val = "#" + val;
267                            }
268                            row.appendCell( createTextCell( contentDom, val, false, false ) );
269                    }
270                    row.setStyleName( "ro1" );
271                    sheet.appendRow( row );
272            }
273    
274            /**
275             * PrintWriter に セパレーターを書き込みますã?
276             * 第ä¸?‚«ラãƒ?›®は、サイズæƒ??を示ã�?"#----" を書き込みますã?
277             * こã?行ã?、å?力形式に無関係に、TableWriter.TAB_SEPARATOR で区åˆ?‚‰れますã?
278             *
279             * @param       table  DBTableModelオブジェクãƒ?
280             * @param       writer PrintWriterオブジェクãƒ?
281             */
282            @Override
283            protected void writeSeparator( final DBTableModel table, final PrintWriter writer ) {
284                    String sep = "----";
285    
286                    OdfTableRow row = new OdfTableRow( contentDom );
287                    row.appendCell( createTextCell( contentDom, "#----", false, false ) );
288                    for( int i = 0; i < numberOfColumns; i++ ) {
289                            if( i == 0 && !useNumber ) {
290                                    continue;
291                            }
292                            row.appendCell( createTextCell( contentDom, sep, false, false ) );
293                    }
294                    sheet.appendRow( row );
295            }
296    
297            /**
298             * PrintWriter に DBTableModelのãƒ??ブルæƒ??を書き込みますã?
299             * こã?クラスでは?Œデータã‚?ãƒ?ƒ–ルコーãƒ??ション(")で囲みますã?
300             * PrintWriter に DBTableModelのãƒ??ブルæƒ??を書き込みますã?
301             *
302             * @og.rev 5.2.1.0 (2010/10/01) useRenderer 対å¿?
303             *
304             * @param       table  DBTableModelオブジェクãƒ?
305             * @param       writer PrintWriterオブジェクãƒ?
306             */
307            @Override
308            protected void writeData( final DBTableModel table,final PrintWriter writer ) {
309                    int numberOfRows =      table.getRowCount();
310    
311                    boolean[] nvar = new boolean[numberOfColumns];
312                    boolean[] cellType = new boolean[numberOfColumns];
313                    for( int i=0; i<numberOfColumns; i++ ) {
314                            int clm = clmNo[i];
315                            NativeType nativeType = dbColumn[clm].getNativeType();
316                            switch( nativeType ) {
317                                    case INT    :
318                                    case LONG   :
319                                    case DOUBLE :
320                                            cellType[i] = true ;
321                                            break;
322                                    case STRING :
323                                    case CALENDAR :
324                                    default :
325                                            cellType[i] = false ;
326                                            break;
327                            }
328                            nvar[i] = "NVAR".equals( dbColumn[clm].getDbType() );
329                    }
330                    boolean useRenderer = isUseRenderer();  // 5.2.1.0 (2010/10/01)
331    
332                    for( int r = 0; r < numberOfRows; r++ ) {
333                            OdfTableRow row = new OdfTableRow( contentDom );
334    
335                            if( useNumber ) {
336                                    row.appendCell( createTextCell( contentDom, String.valueOf( r + 1 ), true, true ) );
337                            }
338    
339                            for( int i = 0; i < numberOfColumns; i++ ) {
340                                    int clm = clmNo[i];
341                                    String val = table.getValue( r, clm );
342                                    if( nvar[i] ) {
343                                            val = StringUtil.getReplaceEscape( val );
344                                    }
345                                    // 5.2.1.0 (2010/10/01) useRenderer 対å¿?
346                                    else if( useRenderer ) {
347                                            val = StringUtil.spanCut( dbColumn[clm].getRendererValue( val ) );
348                                    }
349                                    row.appendCell( createTextCell( contentDom, val, cellType[i], false ) );
350                            }
351                            row.setStyleName( "ro1" );
352                            sheet.appendRow( row );
353                    }
354            }
355    
356            /**
357             * ãƒ?‚­ストコンãƒ?ƒ³ãƒ?”¨のセルを生成すã‚?
358             *
359             * @param       contentDom      OdfFileDomオブジェクãƒ?
360             * @param       content         コンãƒ?ƒ³ãƒ?
361             * @param       isCellTypeNumber        [true:数字型/false:æ–?­—型]
362             * @param       isNumberList            [true:数字リスãƒ?999/false:通常]
363             *
364             * @return      OpenOfficeのセルãƒ??ブルオブジェクãƒ?
365             */
366            protected OdfTableCell createTextCell(  final OdfFileDom contentDom,
367                                                                                            final String content,
368                                                                                            final Boolean isCellTypeNumber,
369                                                                                            final Boolean isNumberList ) {
370                    OdfTableCell cell = new OdfTableCell( contentDom );
371                    if( isCellTypeNumber ) {
372                            cell.setOfficeValueAttribute( Double.parseDouble( content ) );
373                            cell.setOfficeValueTypeAttribute( OfficeValueTypeAttribute.Value.FLOAT.toString() );
374                    }
375                    else {
376                            cell.setOfficeValueTypeAttribute( OfficeValueTypeAttribute.Value.STRING.toString() );
377                    }
378                    OdfTextParagraph paragraph = new OdfTextParagraph( contentDom, null, content );
379                    cell.appendChild( paragraph );
380                    return cell;
381            }
382    
383            /**
384             * ãƒ?ƒ•ォルトで用意されてã�?‚‹Stylesを調整しますã?
385             * ※ここでは何もしませんã€?
386             *
387             */
388            protected void resetAutoStylesAndMasterStyles(){
389                    // Document empty method 対ç­?
390            }
391    
392            /**
393             * DBTableModelのãƒ??タとして読み込ã‚?�¨きã?シート名を設定しますã?
394             * 初期値はã€?Sheet1" ですã?
395             * これは、Calc追åŠ?©Ÿè?として実è£?�•れてã�?�¾すã?
396             *
397             * @param   sheetName シート名
398             */
399            @Override
400            public void setSheetName( final String sheetName ) {
401                    if( sheetName != null ) {
402                            this.sheetName = sheetName;
403                    }
404            }
405    
406            /**
407             * Calc雛型参è?ファイルのシート名を設定しますã?
408             * これは、Calc追åŠ?©Ÿè?として実è£?�•れてã�?�¾すã?
409             *
410             * Calcファイルを書きå?す時にã€?››型として参ç?するシート名を指定しますã?
411             * これにより、è¤?•°の形式ã?異なるデータをé?次書きå?したã‚?appendモードを併用)する
412             * ことã‚??シートをæŒ?®šして新規にCalcを作æ?する場合にフォーãƒ?‚’設定する事が可能になりますã?
413             * 初期値は、null(第ä¸?‚·ーãƒ? ですã?
414             *
415             * @param   sheetName シート名
416             */
417            @Override
418            public void setRefSheetName( final String sheetName ) {
419                    if( sheetName != null ) {
420                            refSheetName = sheetName;
421                    }
422            }
423    
424            /**
425             * こã?クラスがã?Calc対応機è?(=Excel対応機è?)を持ってã�?‚‹かどã�?�‹を返しますã?
426             *
427             * Calc対応機è?とは、シート名のセãƒ?ƒˆã€?››型参照ファイル名ã?セãƒ?ƒˆã€?
428             * 書き込みå…?ƒ•ァイルのFileオブジェクト取得などの、特殊機è?ですã?
429             * 本来は、インターフェースをå?けるべきとè€?�ˆますが、taglib クラス等ã?
430             * 関係があり、問ã�?�ˆわせによる条件åˆ?²�で対応しますã?
431             *
432             * @return      Calc対応機è?(=Excel対応機è?)を持ってã�?‚‹かどã�?�‹(true 固å®?
433             */
434            @Override
435            public boolean isExcel() {
436                    return true;
437            }
438    
439            /**
440             * 出力å?ファイル名をセãƒ?ƒˆしますã?(DIR + Filename)
441             * これは、Calc追åŠ?©Ÿè?として実è£?�•れてã�?�¾すã?
442             *
443             * @param   filename Calc雛型参è?ファイルå�?
444             */
445            @Override
446            public void setFilename( final String filename ) {
447                    this.filename = filename;
448            }
449    
450            /**
451             * Calc雛型参è?ファイル名をセãƒ?ƒˆしますã?(DIR + Filename)
452             * これは、Calc追åŠ?©Ÿè?として実è£?�•れてã�?�¾すã?
453             *
454             * @param   filename Calc雛型参è?ファイルå�?
455             */
456            @Override
457            public void setRefFilename( final String filename ) {
458                    refFilename = filename;
459            }
460    
461            /**
462             * Calc出力時のãƒ?ƒ•ォルトフォント名を設定しますã?
463             * Calcの場合ã?fontNameは、利用できませんã€?
464             *
465             * Calcファイルを書きå?す時に、デフォルトフォント名を指定しますã?
466             * フォント名は、Calcのフォント名をそのまま使用してくださいã€?
467             * に設定されますã?
468             * 初期値は、シスãƒ?ƒ リソース の TABLE_WRITER_DEFAULT_FONT_NAME ですã?
469             *
470             * @og.rev      5.5.2.6 (2012/05/25) findbugs対å¿?
471             *
472             * @param   fontName ãƒ?ƒ•ォルトフォント名
473             */
474            @Override
475            public void setFontName( final String fontName ) {
476    //              this.fontName = fontName ;
477                    String errMsg = "Calcの場合ã?fontNameは、利用できません。fontName=[" + fontName + "]";
478                    System.err.println( errMsg );
479            }
480    
481            /**
482             * Calc出力時のãƒ?ƒ•ォルトフォントã?イント数を設定しますã?
483             * Calcの場合ã?fontPointは、利用できませんã€?
484             *
485             * Calcファイルを書きå?す時に、デフォルトã?イント数を指定しますã?
486             * に設定されますã?
487             * 初期値は、シスãƒ?ƒ リソース の TABLE_WRITER_DEFAULT_FONT_POINTS ですã?
488             *
489             * @og.rev      5.5.2.6 (2012/05/25) findbugs対å¿?
490             *
491             * @param   point ãƒ?ƒ•ォルトフォントã?イント数
492             */
493            @Override
494            public void setFontPoint( final short point ) {
495    //              fontPoint = point;
496                    String errMsg = "Calcの場合ã?fontPointは、利用できません。fontPoint=[" + point + "]";
497                    System.err.println( errMsg );
498            }
499    }