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 java.io.PrintWriter;
019import java.util.List;
020import java.util.Map ;
021import java.util.LinkedHashMap ;
022
023import org.odftoolkit.odfdom.OdfFileDom;
024import org.odftoolkit.odfdom.doc.office.OdfOfficeAutomaticStyles;
025import org.odftoolkit.odfdom.doc.office.OdfOfficeMasterStyles;
026import org.odftoolkit.odfdom.doc.style.OdfStyle;
027import org.odftoolkit.odfdom.doc.style.OdfStyleFooter;
028import org.odftoolkit.odfdom.doc.style.OdfStyleFooterLeft;
029import org.odftoolkit.odfdom.doc.style.OdfStyleHeader;
030import org.odftoolkit.odfdom.doc.style.OdfStyleHeaderLeft;
031import org.odftoolkit.odfdom.doc.style.OdfStyleMasterPage;
032import org.odftoolkit.odfdom.doc.style.OdfStylePageLayout;
033import org.odftoolkit.odfdom.doc.style.OdfStyleParagraphProperties;
034import org.odftoolkit.odfdom.doc.style.OdfStyleTableCellProperties;
035import org.odftoolkit.odfdom.doc.table.OdfTableCell;
036import org.odftoolkit.odfdom.doc.table.OdfTableRow;
037import org.odftoolkit.odfdom.dom.element.style.StylePageLayoutPropertiesElement;
038import org.odftoolkit.odfdom.dom.style.OdfStyleFamily;
039import org.w3c.dom.Node;
040
041import org.opengion.fukurou.model.NativeType;
042import org.opengion.fukurou.util.HybsEntry;
043import org.opengion.hayabusa.common.HybsSystemException;
044import org.opengion.hayabusa.db.DBColumn;
045import org.opengion.hayabusa.db.DBTableModel;
046
047/**
048 * Calcファイルの書き出しクラスです。
049 *
050 * このクラスでは、通常の出力クラスと異なり、データ部分には、データではなく、
051 * {@カラム名_行番号}が出力されます。
052 *
053 * この出力結果は、通常、Calc帳票システムの雛形を作成するための、元情報として
054 * 利用することを想定しています。
055 *
056 * writeTableParam タグで key="Size" を指定できます。これは、作成するレコードのデータ件数です。
057 * 初期値は、25件です。
058 *
059 * @og.group ファイル出力
060 *
061 * @version  5.0
062 * @author       Hiroki Nakamura
063 * @since    JDK6.0,
064 */
065public class TableWriter_CalcDef extends TableWriter_Calc {
066        //* このプログラムのVERSION文字列を設定します。   {@value} */
067        private static final String VERSION = "6.0.1.2 (2014/08/08)" ;
068
069        // 5.6.6.1 (2013/07/12) keys の整合性チェックを行います。
070        private static final Map<String,String> keysMap = new LinkedHashMap<String,String>();
071
072        private static final int INIT_DATA_SIZE = 25;
073
074        private int dataSize    = INIT_DATA_SIZE;
075
076        static {
077                keysMap.put( "SIZE"             , "レコードのデータ件数(初期値:25)"          );
078        }
079
080        /**
081         * PrintWriter に DBTableModelのテーブル情報を書き込みます。
082         * このクラスでは,データを ダブルコーテーション(")で囲みます。
083         * PrintWriter に DBTableModelのテーブル情報を書き込みます。
084         *
085         * @og.rev 5.1.8.0 (2010/07/01) コメント出力(CalcDefAno)追加による対応
086         * @og.rev 6.0.1.2 (2014/08/08) カラム飛ばしできる機能を追加
087         *
088         * @param       table  DBTableModelオブジェクト
089         * @param       writer PrintWriterオブジェクト
090         */
091        @Override
092        protected void writeData( final DBTableModel table,final PrintWriter writer ) {
093                for( int r=0; r<dataSize; r++ ) {
094                        OdfTableRow row = new OdfTableRow( contentDom );
095
096                        if( useNumber ) {
097                                String val = "ROWNO_" + r ;
098                                row.appendCell( createTextCell( contentDom, val, null, true, true ) );
099                        }
100
101                        boolean[] cellType = new boolean[numberOfColumns];
102                        for( int i=0; i<numberOfColumns; i++ ) {
103                                int clm = clmNo[i];
104                                if( clm < 0 ) { continue; }                     // 6.0.1.2 (2014/08/08) カラム飛ばし
105
106                                NativeType nativeType = dbColumn[clm].getNativeType();
107                                switch( nativeType ) {
108                                        case INT    :
109                                        case LONG   :
110                                        case DOUBLE :
111                                                cellType[i] = true ;
112                                                break;
113                                        case STRING :
114                                        case CALENDAR :
115                                        default :
116                                                cellType[i] = false ;
117                                                break;
118                                }
119                        }
120
121                        for( int i=0; i<numberOfColumns; i++ ) {
122                                int clm = clmNo[i];
123                                if( clm < 0 ) { continue; }                     // 6.0.1.2 (2014/08/08) カラム飛ばし
124
125                                String val = table.getColumnName( clm ) + "_" + r ;
126                                row.appendCell( createTextCell( contentDom, val, table.getDBColumn( clm ), cellType[i], false ) );
127                                row.setStyleName( "ro1" );
128                        }
129
130                        sheet.appendRow( row );
131                }
132        }
133
134        /**
135         * テキストコンテンツ用のセルを生成する
136         *
137         * @og.rev 5.1.8.0 (2010/07/01) コメント出力(CalcDefAno)追加による対応
138         *
139         * @param       contentDom      OdfFileDomオブジェクト
140         * @param       content         コンテンツ
141         * @param       col                     DBColumnオブジェクト
142         * @param       isCellTypeNumber        [true:数字型/false:文字型]
143         * @param       isNumberList            [true:数字リスト=999/false:通常]
144         *
145         * @return      テキストコンテンツ用のセル
146         */
147        protected OdfTableCell createTextCell( final OdfFileDom contentDom, final String content, final DBColumn col, final Boolean isCellTypeNumber, final Boolean isNumberList ) {
148                OdfTableCell cell = super.createTextCell( contentDom, "{@" + content + "}", false, isNumberList );
149                if( isNumberList ) {
150                        OdfStyle style = contentAutoStyles.newStyle( OdfStyleFamily.TableCell );
151                        style.setProperty( OdfStyleTableCellProperties.TextAlignSource, "fix" );
152                        style.setProperty( OdfStyleTableCellProperties.RepeatContent, "false" );
153                        style.setProperty( OdfStyleParagraphProperties.TextAlign, "end" );
154                        style.setProperty( OdfStyleParagraphProperties.MarginRight, "0cm" );
155                        String cellStyleName = style.getStyleNameAttribute();
156                        cell.setStyleName( cellStyleName );
157                }
158
159                return cell;
160        }
161
162        /**
163         * デフォルトで用意されているStylesを調整します。
164         *
165         * ヘッダー表示しない
166         * フッターを数字のみにして、右端に出す
167         * ページレイアウトを横にする
168         * ページの設定を、拡大縮小モードを「印刷範囲をページ数に合わせる」に設定(1ページ)
169         */
170        @Override
171        protected void resetAutoStylesAndMasterStyles() {
172                try {
173                        // AutomaticStyles調整
174                        OdfOfficeAutomaticStyles oas = wb.getStylesDom().getAutomaticStyles();
175                        OdfStylePageLayout spl = oas.getPageLayout( "pm1" );
176                        spl.setProperty( StylePageLayoutPropertiesElement.PageHeight, "21.00cm" );
177                        spl.setProperty( StylePageLayoutPropertiesElement.PageWidth, "29.70cm" );
178                        spl.setProperty( StylePageLayoutPropertiesElement.PrintOrientation, "landscape" );
179                        spl.setProperty( StylePageLayoutPropertiesElement.ScaleToPages, "1" );
180
181                        // MasterStyles調整
182                        OdfOfficeMasterStyles oms = wb.getOfficeMasterStyles();
183                        OdfStyleMasterPage smp = oms.getMasterPage( "Default" );
184
185                        // MasterPageのデフォルトで用意されているノードを削除
186                        Node fcd = smp.getFirstChild();
187                        while( fcd != null ) {
188                                smp.removeChild( fcd );
189                                fcd = smp.getFirstChild();
190                        }
191
192                        // MasterPageのノードを定義と追加
193                        OdfStyleHeader sh = new OdfStyleHeader( wb.getStylesDom() );
194                        OdfStyleHeaderLeft shl = new OdfStyleHeaderLeft( wb.getStylesDom() );
195                        sh.setStyleDisplayAttribute( false );
196                        shl.setStyleDisplayAttribute( false );
197                        smp.appendChild( sh );
198                        smp.appendChild( shl );
199                        OdfStyleFooter sf = new OdfStyleFooter( wb.getStylesDom() );
200                        OdfStyleFooterLeft sfl = new OdfStyleFooterLeft( wb.getStylesDom() );
201                        sf.newStyleRegionRightElement().newTextPElement().newTextPageNumberElement();
202                        sfl.setStyleDisplayAttribute( false );
203                        smp.appendChild( sf );
204                        smp.appendChild( sfl );
205                }
206                catch( Exception ex ) {
207                        String errMsg = "AutomaticStylesとMasterStyles調整できません";
208                        throw new HybsSystemException( errMsg, ex );
209                }
210        }
211
212        /**
213         * パラメーターリストをセットします。
214         * 内部は、HybsEntry クラスを持っています。
215         * 引数が、null の場合は、何もしません。
216         *
217         * @og.rev 5.6.6.1 (2013/07/12) keys の整合性チェックを行います。
218         *
219         * @param       listParam       HybsEntryリスト
220         */
221        @Override
222        public void setParam( final List<HybsEntry> listParam ) {
223                if( listParam != null && !listParam.isEmpty() ) {
224                        for( HybsEntry entry : listParam ) {
225
226                                String key = entry.getKey() ;           // 5.6.6.1 (2013/07/12) keys の整合性チェック
227                                checkParam( key , keysMap );
228
229                                String val = entry.getValue() ;         // 5.6.6.1 (2013/07/12) val を先に取得
230                                // 6.0.0.1 (2014/04/25) These nested if statements could be combined
231                                if( val != null && val.length() > 0 && "Size".equalsIgnoreCase( key ) ) {
232                                        dataSize = Integer.parseInt( val );
233                                }
234                        }
235                }
236        }
237}