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 }