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.report2; 017 018 import java.io.File; 019 import java.util.Map; 020 import java.util.HashMap; 021 import java.util.Locale; 022 023 import org.opengion.fukurou.util.FileUtil; 024 import org.opengion.fukurou.util.StringUtil; 025 import org.opengion.hayabusa.common.HybsSystem; 026 import org.opengion.hayabusa.common.HybsSystemException; 027 028 import com.sun.star.beans.PropertyValue; 029 import com.sun.star.frame.XComponentLoader; 030 import com.sun.star.frame.XController; 031 import com.sun.star.frame.XDispatchHelper; 032 import com.sun.star.frame.XDispatchProvider; 033 import com.sun.star.frame.XModel; 034 import com.sun.star.frame.XStorable; 035 import com.sun.star.io.IOException; 036 import com.sun.star.lang.EventObject; 037 import com.sun.star.lang.IllegalArgumentException; 038 import com.sun.star.lang.XComponent; 039 import com.sun.star.uno.Exception; 040 import com.sun.star.uno.UnoRuntime; 041 import com.sun.star.util.CloseVetoException; 042 import com.sun.star.util.XCloseable; 043 import com.sun.star.view.PrintJobEvent; 044 import com.sun.star.view.PrintableState; 045 import com.sun.star.view.XPrintJobBroadcaster; 046 import com.sun.star.view.XPrintJobListener; 047 import com.sun.star.view.XPrintable; 048 049 /** 050 * OpenOfficeを利用して様?な形式?ファイルを読み込み、?力?印刷を行うための変換クラスです? 051 * 052 * 変換を行うことのできる入出力?フォーマット以下?通りです? 053 * 054 * [対応フォーマッ? 055 * 入力[Calc(ODS) ,Excel(XLS) ] ?出力[Calc(ODS) ,Excel(XLS) ,PDF] 056 * 入力[Writer(ODT) ,Word(DOC) ] ?出力[Writer(ODT) ,Word(DOC) ,PDF] 057 * 入力[Impress(ODP),PowerPoint(PPT)] ?出力[Impress(ODP),PowerPoint(PPT),PDF] 058 * 入力[ * 上記?全て ] ?印刷 059 * 060 * 変換を行うには、以下?2通りの方法があります? 061 * (1)簡易的な変換メソ?を利用する場? 062 * {@link #convert(String, String)}を利用して、変換を行います? 063 * こ?場合?出力形式?、?力ファイルの拡張子に従って自動的に決定されます? 064 * こ?ため、印刷処?どを行う場合??2)の方法で出力して下さ?? 065 * (2)段階的に書くメソ?を呼び出して変換する場? 066 * オブジェクトを生?した後?{@link #open()}?(?変換メソ?)、{@link #clone()}? 067 * ?に呼び出して変換を行います? 068 * こ?場合?出力形式?、それに対応するメソ?を呼び出ることで決定されます? 069 * 070 * また?変換を行うための、各種メソ?は、例外としてThrowableを投げるように定義されて?す? 071 * こ?クラスを利用する場合?、このThrowableをcatchし?catch句で、?{@link #close( boolean )}に? 072 * "true"(エラー発生時のクローズ処?を指定して、終???行って下さ?? 073 * (これを行わな??合?OpenOfficeの不要なプロセスが残ってしま?能性がありま? 074 * 075 * また?出力ファイルが既に存在する場合?出力ファイルは?削除された後?処?れます? 076 * なお?入力ファイルと出力ファイルが同じ?合?何も処?れません?例外も発行されません) 077 * 078 * 入力ファイルを?カンマ区?で??した?合??の入力ファイルを?ージして出力します? 079 * ※1 現状は、ファイルのマ?ジは、?力ファイルがExcelまた?Calcの場合?み対応して?す? 080 * 081 * @og.group 帳票シス? 082 * 083 * @version 4.0 084 * @author Hiroki.Nakamura 085 * @since JDK1.6 086 */ 087 public class DocConverter_OOO { 088 089 final private boolean isOnline; // オンライン処?ど?(オンライン処??場合?プロセスはファクトリクラス経由で生?されま? 090 final private String[] mergeFile; 091 092 private String inputName; 093 private String origName; 094 095 // private XComponent doc; 096 private XComponent xComp; // 5.1.8.0 (2010/07/01) メソ?と重なる変数名?変更 097 private SOfficeProcess soffice; 098 099 // 入力?出力?拡張子とこれに対応するフィルター? 100 // static final private HashMap<String,String> filterMap = new HashMap<String,String>(); 101 static final private Map<String,String> filterMap = new HashMap<String,String>(); 102 static { 103 filterMap.put( "ods_ods", "calc8" ); 104 filterMap.put( "xls_ods", "calc8" ); 105 filterMap.put( "ods_xls", "MS Excel 97" ); 106 filterMap.put( "xls_xls", "MS Excel 97" ); 107 filterMap.put( "ods_pdf", "calc_pdf_Export" ); 108 filterMap.put( "xls_pdf", "calc_pdf_Export" ); 109 filterMap.put( "odt_odt", "writer8" ); 110 filterMap.put( "doc_odt", "writer8" ); 111 filterMap.put( "odt_doc", "MS Word 97" ); 112 filterMap.put( "doc_doc", "MS Word 97" ); 113 filterMap.put( "odt_pdf", "writer_pdf_Export" ); 114 filterMap.put( "doc_pdf", "writer_pdf_Export" ); 115 filterMap.put( "odp_odp", "impress8" ); 116 filterMap.put( "ppt_odp", "impress8" ); 117 filterMap.put( "odp_ppt", "MS PowerPoint 97" ); 118 filterMap.put( "ppt_ppt", "MS PowerPoint 97" ); 119 filterMap.put( "odp_pdf", "impress_pdf_Export" ); 120 filterMap.put( "ppt_pdf", "impress_pdf_Export" ); 121 }; 122 123 /** 124 * コンストラクタです? 125 * 126 * #DocConverter(input, true)と同じです? 127 * 128 * @param input ファイル?(カンマ区?) 129 * @see #DocConverter_OOO(String[]) 130 */ 131 public DocConverter_OOO( final String input ) { 132 this( StringUtil.csv2Array( input ), true ); 133 } 134 135 /** 136 * コンストラクタです? 137 * 138 * #DocConverter(input, true)と同じです? 139 * 140 * @param input ファイル?(配?) 141 * @see #DocConverter_OOO(String[], boolean) 142 */ 143 public DocConverter_OOO( final String input[] ) { 144 this( input, true ); 145 } 146 147 /** 148 * コンストラクタです? 149 * 150 * isOnline(isOl)がtrueに?された場合?soffice.binのプロセスをファクトリークラス経由で生?し? 151 * キャ?ュします? 152 * ?、シス?リソースが読み込まれな??、バ?ファイルから起動した?合?、この方法? 153 * 利用できな?め?isOnlineをfalseに?する?があります? 154 * 155 * @param input ファイル?(配?) 156 * @param isOl オンライン(Web環?の使用)かど? 157 */ 158 public DocConverter_OOO( final String input[], final boolean isOl ) { 159 if( input == null || input.length == 0 || input[0].length() == 0 ) { 160 throw new HybsSystemException( "入力ファイルが指定されて?せん? ); 161 } 162 File inFile = new File( input[0] ); 163 if( !inFile.exists() ) { 164 throw new HybsSystemException( "入力ファイルが存在しません?file=" + input[0] + "]" ); 165 } 166 isOnline = isOl; 167 inputName = input[0]; 168 origName = input[0]; 169 170 if( input.length == 1 ) { 171 mergeFile = null; 172 } 173 else { 174 if( !"xls".equals( getSuffix( input[0] ) ) && !"ods".equals( getSuffix( input[0] ) ) ) { 175 throw new HybsSystemException( "ファイルのマ?ジを行う場合?入力ファイルは、Excelまた?Cacl形式である?があります?" ); 176 } 177 178 mergeFile = new String[input.length-1]; 179 for( int i=0; i<mergeFile.length; i++ ) { 180 if( input[i+1].length() == 0 || !( new File( input[i+1] ) ).exists() ) { 181 throw new HybsSystemException( "マ?ジファイルが指定されて??、また?存在しません?file=" + input[i+1] + "]" ); 182 } 183 if( inputName.equals( input[i] + 1 ) ) { 184 throw new HybsSystemException( "マ?ジファイルに入力ファイルと同じファイルが指定されてます?[file=" + input[i+1] + "]" ); 185 } 186 if( !"xls".equals( getSuffix( input[i+1] ) ) && !"ods".equals( getSuffix( input[i+1] ) ) ) { 187 throw new HybsSystemException( "ファイルのマ?ジを行う場合?マ?ジファイルは、Excelまた?Cacl形式である?があります?" ); 188 } 189 mergeFile[i] = input[i+1]; 190 } 191 } 192 } 193 194 /** 195 * SOficeのコンポ?ネントを起動します? 196 * 197 * 正常に処?終?た?合??close()を発行し、終???行って下さ?? 198 * また?例外が発生した?合??close(true)を発行し、終???行って下さ?? 199 * 200 * @og.rev 5.1.7.0 (2010/06/01) マ?ジ処?? 201 * 202 * @throws Throwable 何らか?エラーが発生した?合? 203 * @see #close() 204 * @see #close(boolean) 205 */ 206 public void open() throws Throwable { 207 // プロセスの取? 208 if( soffice == null ) { 209 if( isOnline ) { 210 soffice = ProcessFactory.newInstance(); 211 } 212 else { 213 soffice = new SOfficeProcess( "docconverter.class" ); 214 soffice.bootstrap(); 215 } 216 217 // マ?ジする場合?、?ージ対象のファイルをテンポラリにコピ?する(readOnly回避のため) 218 // ?プレー?無?として上げると、シートコピ?先として特定できなくなるた? 219 if( mergeFile != null ) { 220 File origFile = new File( origName ); 221 inputName = soffice.getTempPath() + System.currentTimeMillis() + "_" + origFile.getName(); 222 FileUtil.copy( origFile, new File( inputName ) ); 223 } 224 } 225 226 // PropertyValue[] calcProps = new PropertyValue[1]; 227 // calcProps[0] = new PropertyValue(); 228 // calcProps[0].Name = "Hidden"; 229 // calcProps[0].Value = true; 230 // 231 // String url = "file:///" + inputName.replace( '\\', '/' ); 232 // 233 // @SuppressWarnings("cast") // OpenOffice 3.2 での冗長なキャスト警告?抑止。キャストをはずすと、旧3.1 では、エラーになる? 234 // XComponentLoader cloader = (XComponentLoader) UnoRuntime.queryInterface( XComponentLoader.class, soffice.getDesktop() ); 235 // try { 236 // doc = cloader.loadComponentFromURL( url, "_default", 0, calcProps ); 237 // } 238 // catch( IOException ex ) { 239 // throw new HybsSystemException( "OpenOfficeの立ち上げ時にエラーが発生しました(入出力エラー)?, ex ); 240 // } 241 // catch( IllegalArgumentException ex ) { 242 // throw new HybsSystemException( "OpenOfficeの立ち上げ時にエラーが発生しました(パラメーター不正)?, ex ); 243 // } 244 245 // 5.1.7.0 (2010/06/01) マ?ジ処?? 246 xComp = getComponent( inputName, ( mergeFile == null ? true : false ), false ); 247 248 if( mergeFile != null ) { 249 for( int i=0; i<mergeFile.length; i++ ) { 250 merge( mergeFile[i] ); 251 } 252 } 253 } 254 255 /** 256 * ドキュメントコンポ?ネントを取得します? 257 * 258 * @param input ファイル? 259 * @param isHidden ?属?[true/false] 260 * @param isAsTemplate OpenOffice上?Template属?[true/false] 261 * 262 * @return ドキュメントコンポ?ネン? 263 */ 264 @SuppressWarnings("cast") // OpenOffice 3.2 での冗長なキャスト警告?抑止。キャストをはずすと、旧3.1 では、エラーになる? 265 private XComponent getComponent( final String input, final boolean isHidden, final boolean isAsTemplate ) { 266 PropertyValue[] calcProps = new PropertyValue[2]; 267 calcProps[0] = new PropertyValue(); 268 calcProps[0].Name = "Hidden"; 269 calcProps[0].Value = isHidden; 270 calcProps[1] = new PropertyValue(); 271 calcProps[1].Name = "AsTemplate"; 272 calcProps[1].Value = isAsTemplate; 273 274 String url = "file:///" + input.replace( '\\', '/' ); 275 276 XComponent rtnDoc; 277 XComponentLoader cloader = (XComponentLoader) UnoRuntime.queryInterface( XComponentLoader.class, soffice.getDesktop() ); 278 try { 279 rtnDoc = cloader.loadComponentFromURL( url, "_blank", 0, calcProps ); 280 } 281 catch( IOException ex ) { 282 throw new HybsSystemException( "OpenOfficeの立ち上げ時にエラーが発生しました(入出力エラー)?, ex ); 283 } 284 catch( IllegalArgumentException ex ) { 285 throw new HybsSystemException( "OpenOfficeの立ち上げ時にエラーが発生しました(パラメーター不正)?, ex ); 286 } 287 return rtnDoc; 288 } 289 290 /** 291 * ドキュメン?xls,ods)のマ?ジを行います? 292 * 293 * @param mergeInputName マ?ジ対象のファイル? 294 */ 295 @SuppressWarnings("cast") // OpenOffice 3.2 での冗長なキャスト警告?抑止。キャストをはずすと、旧3.1 では、エラーになる? 296 private void merge( final String mergeInputName ) { 297 // マ?ジする副ファイルは、テンプレー?無?として上げ?readOnly回避のため) 298 XComponent subDoc = getComponent( mergeInputName, false, true ); 299 300 XDispatchProvider dispatchProvider 301 = (XDispatchProvider)UnoRuntime.queryInterface( XDispatchProvider.class 302 ,((XController)UnoRuntime.queryInterface( XController.class 303 ,((XModel)UnoRuntime.queryInterface( XModel.class 304 ,subDoc 305 )).getCurrentController() 306 )).getFrame() 307 ); 308 309 XDispatchHelper xDispatchHelper = soffice.getDispatcher(); 310 xDispatchHelper.executeDispatch(dispatchProvider, ".uno:TableSelectAll", "", 0, new PropertyValue[0]); 311 312 String title = ( new File( inputName ).getName() ); 313 title = ( title ).substring( 0, title.indexOf( '.' ) ); 314 315 PropertyValue[] moveProps = new PropertyValue[3]; 316 moveProps[0] = new PropertyValue(); 317 moveProps[0].Name = "DocName"; 318 moveProps[0].Value = title; 319 moveProps[1] = new PropertyValue(); 320 moveProps[1].Name = "Index"; 321 moveProps[1].Value = 32767; 322 moveProps[2] = new PropertyValue(); 323 moveProps[2].Name = "Copy"; 324 moveProps[2].Value = true; 325 xDispatchHelper.executeDispatch(dispatchProvider, ".uno:Move", "", 0, moveProps); 326 327 // シートリンク方式?場合?、CalcをHiddenの状態で実行できるが?画像などのオブジェクトがリンクされな?め? 328 // 採用見?り?? 329 // XSpreadsheets mainSp = ( (XSpreadsheetDocument)UnoRuntime.queryInterface( XSpreadsheetDocument.class, xComp ) ).getSheets(); 330 // String[] mainSheetNames = mainSp.getElementNames(); 331 // 332 // XSpreadsheets subSp = ( (XSpreadsheetDocument)UnoRuntime.queryInterface( XSpreadsheetDocument.class, subDoc ) ).getSheets(); 333 // String[] subSheetNames = subSp.getElementNames(); 334 // for( int i=0; i<1; i++ ) { 335 // XSpreadsheet newSp = insertSheet( mainSp, subSheetNames[i], 0, (short)(mainSheetNames.length + i) ); 336 // XSheetLinkable mainLink = (XSheetLinkable) UnoRuntime.queryInterface( XSheetLinkable.class, newSp ); 337 // mainLink.link( "file:///" + mergeInputName.replace( '\\', '/' ), subSheetNames[i], "", "", com.sun.star.sheet.SheetLinkMode.NORMAL ); 338 // mainLink.setLinkMode( com.sun.star.sheet.SheetLinkMode.NONE ); 339 // } 340 341 closeComponent( subDoc ); 342 } 343 344 // /** 345 // * スプレ?シートオブジェクトに対して、シートを新規に追?ます? 346 // * 追?るシート名が既に存在する場合?シート名のサフィ?スとして1,2...の連番を付加します? 347 // * 348 // * @param sheets 349 // * @param sheetName 350 // * @param suffix 351 // * @param index 352 // * @return 追?ート?シートオブジェク? 353 // */ 354 // private XSpreadsheet insertSheet( final XSpreadsheets sheets, final String sheetName, final int suffix, final short index ) { 355 // String sn = sheetName + ( suffix == 0 ? "" : String.valueOf( suffix ) ); 356 // try { 357 // sheets.insertNewByName( sn, index ); 358 // } 359 // catch ( com.sun.star.uno.RuntimeException ex ) { 360 // if( suffix < 256 ) { 361 // return insertSheet( sheets, sheetName, suffix+1, index ); 362 // } 363 // else { 364 // throw new HybsSystemException( "シート?追?失敗しました", ex ); 365 // } 366 // } 367 // 368 // XSpreadsheet insSheet = null; 369 // try { 370 // insSheet = (XSpreadsheet)UnoRuntime.queryInterface( XSpreadsheet.class, sheets.getByName( sn ) ); 371 // } 372 // catch( NoSuchElementException ex ) { 373 // throw new HybsSystemException( "追?たシートにアクセスできません?, ex ); 374 // } 375 // catch( WrappedTargetException ex ) { 376 // throw new HybsSystemException( "追?たシートにアクセスできません?, ex ); 377 // } 378 // return insSheet; 379 // } 380 381 /** 382 * Calcコンポ?ネントをクローズします? 383 * 384 * こ?クローズ処??、??正常終?た?合に呼び出しする?があります? 385 * 例外が発生した?合??close(true)を発行し、終???行って下さ?? 386 * 387 * こ?メソ?は#close(false)と同じです? 388 * 389 * @throws Throwable 何らか?エラーが発生した?合? 390 * @see #close(boolean) 391 */ 392 public void close() throws Throwable { 393 close( false ); 394 } 395 396 /** 397 * Calcコンポ?ネントをクローズします? 398 * 399 * 引数のisErrがtrueの場合?こ?変換オブジェクトで生?された?ロセスは強制?破?れます? 400 * falseの場合?、?ロセスは、ファクトリクラスを経由して、キャ?ュに戻されます? 401 * (バッチ???場合?、いずれの場合も、?ロセスは強制?破?れま? 402 * 403 * 起動から変換、クローズまでの書く??例外が発生した?合??close(true)を発行し、終???行って下さ?? 404 * 405 * #close(false)は#close()と同じであるため??常利用することはありません? 406 * 407 * @og.rev 4.2.4.1 (2008/07/07 ) 終???60回で終わるよ?修正 408 * @og.rev 4.3.0.0 (2008/07/15 ) ↑?6秒しか?て?かった?で?0秒?ように修正 409 * 410 * @param isErr trueの場合?こ?変換オブジェクトで生?された?ロセスは強制?破?れます? 411 */ 412 @SuppressWarnings("cast") // OpenOffice 3.2 での冗長なキャスト警告?抑止。キャストをはずすと、旧3.1 では、エラーになる? 413 public void close( final boolean isErr ) { 414 if( xComp != null ) { 415 closeComponent( xComp ); 416 } 417 418 if( soffice != null ) { 419 if( isOnline ) { 420 if( isErr ) { 421 ProcessFactory.remove( soffice ); 422 } 423 else { 424 ProcessFactory.release( soffice ); 425 } 426 } 427 else { 428 soffice.close(); 429 } 430 } 431 432 // マ?ジした場合?、テンポラリにコピ?したファイルを削除 433 if( mergeFile != null ) { 434 if( ! ( new File( inputName ) ).delete() ) { 435 System.err.println( "?ポラリにコピ?したファイルを削除できませんでした?" + inputName + "]" ); 436 } 437 } 438 } 439 440 /** 441 * ドキュメントコンポ?ネントをクローズします? 442 * 443 * @param comp ドキュメントコンポ?ネン? 444 */ 445 @SuppressWarnings("cast") // OpenOffice 3.2 での冗長なキャスト警告?抑止。キャストをはずすと、旧3.1 では、エラーになる? 446 private void closeComponent( final XComponent comp ) { 447 XCloseable closeable = null; 448 for( int i = 0;; ++i ) { 449 try { 450 closeable = (XCloseable) UnoRuntime.queryInterface( XCloseable.class, comp ); 451 closeable.close( true ); 452 break; 453 } 454 catch( CloseVetoException ex ) { 455 // 4.2.4.1 (2008/07/07 ) 456 // 4.3.4.4 (2009/01/01) 457 if( i == 600 ) { throw new HybsSystemException( "sofficeプロセスに接続できません?, ex ); } 458 try { 459 Thread.sleep( 100 ); 460 } 461 catch( InterruptedException ex2 ) { 462 // throw new HybsSystemException( ex2 ); 463 } 464 } 465 } 466 } 467 468 /** 469 * 印刷を行います? 470 * 471 * 正常に処?終?た?合??close()を発行し、終???行って下さ?? 472 * また?例外が発生した?合??close(true)を発行し、終???行って下さ?? 473 * 474 * @og.rev 4.3.0.0 (2008/07/16) スプ?ルが終わるまでwaitし?さらにプリンタ発行?状況を監視し、正常終?ど?を判断 475 * @og.rev 4.3.7.3 (2009/06/22) 存在しな??リンターを指定した?合?エラーハンドリングを追? 476 * @og.rev 5.1.2.0 (2010/01/01) CentOS等?、OS_INFOがLinux UNKNOWNとなるため?判定条件を変更 477 * 478 * @param printer プリンター? 479 * @throws Throwable 何らか?エラーが発生した?合? 480 */ 481 public void print( final String printer ) throws Throwable { 482 if( xComp == null ) { throw new HybsSystemException( "初めに?open()を実行して下さ? ); } 483 484 if( printer == null || printer.length() == 0 ) { 485 throw new HybsSystemException( "プリンターが指定されて?せん? ); 486 } 487 488 @SuppressWarnings("cast") // OpenOffice 3.2 での冗長なキャスト警告?抑止。キャストをはずすと、旧3.1 では、エラーになる? 489 XPrintable xprintable = (XPrintable) UnoRuntime.queryInterface( XPrintable.class, xComp ); 490 @SuppressWarnings("cast") // OpenOffice 3.2 での冗長なキャスト警告?抑止。キャストをはずすと、旧3.1 では、エラーになる? 491 XPrintJobBroadcaster selection = (XPrintJobBroadcaster) UnoRuntime.queryInterface(XPrintJobBroadcaster.class, xprintable); 492 MyPrintJobListener listener = new MyPrintJobListener (); 493 selection.addPrintJobListener( listener ); 494 495 PropertyValue[] tmpProps = new PropertyValue[1]; 496 tmpProps[0] = new PropertyValue(); 497 tmpProps[0].Name = "Name"; 498 // 5.1.2.0 (2010/01/01) CentOS等?、OS_INFOがLinux UNKNOWNとなるため?判定条件を変更 499 // OSがLinuxの場合?、?リンタ名称の前後に"<",">"を付加 500 // tmpProps[0].Value = "Linux".equals( HybsSystem.sys( "OS_INFO" ) ) ? "<" + printer + ">" : printer; 501 tmpProps[0].Value = "LINUX".indexOf( HybsSystem.sys( "OS_INFO" ).toUpperCase( Locale.JAPAN ) ) >= 0 ? "<" + printer + ">" : printer; 502 503 // 4.3.4.4 (2009/01/01) 504 try { 505 xprintable.setPrinter( tmpProps ); 506 } 507 catch ( IllegalArgumentException ex ) { 508 throw new HybsSystemException( "印刷時にエラーが発生しました?, ex ); 509 } 510 511 // 4.3.7.3 (2009/06/22) 存在しな??リンタを指定した?合?、PropertyValueに 512 // ?ォルト?リンターが?るため?引数の値と合?して?かで正しく設定されたかを確? 513 String curPrinter = null; 514 PropertyValue[] chkProps = xprintable.getPrinter(); 515 for( int i=0; i<chkProps.length; i++ ) { 516 if( "Name".equals( chkProps[i].Name) ) { 517 curPrinter = (String)chkProps[i].Value; 518 break; 519 } 520 } 521 if( !(printer.equalsIgnoreCase( curPrinter ) ) ) { 522 String errMsg = "プリンター[" + printer + "]を発行?に?できませんでした? + HybsSystem.CR 523 + "存在しな??リンタ名が?されて?可能性があります?"; 524 throw new HybsSystemException( errMsg ); 525 } 526 527 // 4.3.0.0 (2008/07/16) 528 PropertyValue[] printProps = new PropertyValue[1]; 529 printProps[0] = new PropertyValue(); 530 printProps[0].Name = "Wait"; 531 printProps[0].Value = true; 532 533 // 4.3.4.4 (2009/01/01) 534 try { 535 xprintable.print( printProps ); 536 } 537 catch ( IllegalArgumentException ex ) { 538 throw new HybsSystemException( "印刷時にエラーが発生しました?, ex ); 539 } 540 541 // 4.3.0.0 (2008/07/16) 542 if( listener.getStatus() == null 543 || ( listener.getStatus() != PrintableState.JOB_COMPLETED && listener.getStatus() != PrintableState.JOB_SPOOLED ) ){ 544 throw new HybsSystemException ( "Error Occured while spooling print job. Check Spooler-Service!!!"); 545 } 546 } 547 548 /** 549 * プリンタジョブ?状況を監視するリスナ?です? 550 * 551 * @author Hiroki.Nakamura 552 */ 553 private static class MyPrintJobListener implements XPrintJobListener { 554 private PrintableState status = null; 555 556 @Override 557 public void printJobEvent( final PrintJobEvent event ) { 558 status = event.State; 559 } 560 561 @Override 562 public void disposing( final EventObject event ) { 563 // 何もありません?PMD エラー回避) 564 } 565 566 public PrintableState getStatus() { 567 return status; 568 } 569 } 570 571 /** 572 * PDF出力を行います? 573 * 574 * 入力形式で未対応?場?形式?入力ファイルの拡張子で判別)、例外が発行されます? 575 * 576 * 正常に処?終?た?合??close()を発行し、終???行って下さ?? 577 * また?例外が発生した?合??close(true)を発行し、終???行って下さ?? 578 * 579 * @param outputName 出力ファイル? 580 * @param pdfPasswd PDFパスワー? 581 * @throws Throwable 何らか?エラーが発生した?合? 582 */ 583 public void pdf( final String outputName, final String pdfPasswd ) throws Throwable { 584 savePdf( outputName, getFilterName( getSuffix( inputName ), "pdf" ), pdfPasswd ); 585 } 586 587 /** 588 * Calc(ods)出力を行います? 589 * 590 * 入力形式で未対応?場?形式?入力ファイルの拡張子で判別)、例外が発行されます? 591 * 592 * 正常に処?終?た?合??close()を発行し、終???行って下さ?? 593 * また?例外が発生した?合??close(true)を発行し、終???行って下さ?? 594 * 595 * @param outputName 出力ファイル? 596 * @throws Throwable 何らか?エラーが発生した?合? 597 */ 598 public void ods( final String outputName ) throws Throwable { 599 saveDoc( outputName, getFilterName( getSuffix( inputName ), "ods" ) ); 600 } 601 602 /** 603 * Excel(xls)出力を行います? 604 * 605 * 入力形式で未対応?場?形式?入力ファイルの拡張子で判別)、例外が発行されます? 606 * 607 * 正常に処?終?た?合??close()を発行し、終???行って下さ?? 608 * また?例外が発生した?合??close(true)を発行し、終???行って下さ?? 609 * 610 * @param outputName 出力ファイル? 611 * @throws Throwable 何らか?エラーが発生した?合? 612 */ 613 public void xls( final String outputName ) throws Throwable { 614 saveDoc( outputName, getFilterName( getSuffix( inputName ), "xls" ) ); 615 } 616 617 /** 618 * Writer(ods)出力を行います? 619 * 620 * 入力形式で未対応?場?形式?入力ファイルの拡張子で判別)、例外が発行されます? 621 * 622 * 正常に処?終?た?合??close()を発行し、終???行って下さ?? 623 * また?例外が発生した?合??close(true)を発行し、終???行って下さ?? 624 * 625 * @param outputName 出力ファイル? 626 * @throws Throwable 何らか?エラーが発生した?合? 627 */ 628 public void odt( final String outputName ) throws Throwable { 629 saveDoc( outputName, getFilterName( getSuffix( inputName ), "odt" ) ); 630 } 631 632 /** 633 * Word(doc)出力を行います? 634 * 635 * 入力形式で未対応?場?形式?入力ファイルの拡張子で判別)、例外が発行されます? 636 * 637 * 正常に処?終?た?合??close()を発行し、終???行って下さ?? 638 * また?例外が発生した?合??close(true)を発行し、終???行って下さ?? 639 * 640 * @param outputName 出力ファイル? 641 * @throws Throwable 何らか?エラーが発生した?合? 642 */ 643 public void doc( final String outputName ) throws Throwable { 644 saveDoc( outputName, getFilterName( getSuffix( inputName ), "doc" ) ); 645 } 646 647 /** 648 * Impress(odp)出力を行います? 649 * 650 * 入力形式で未対応?場?形式?入力ファイルの拡張子で判別)、例外が発行されます? 651 * 652 * 正常に処?終?た?合??close()を発行し、終???行って下さ?? 653 * また?例外が発生した?合??close(true)を発行し、終???行って下さ?? 654 * 655 * @param outputName 出力ファイル? 656 * @throws Throwable 何らか?エラーが発生した?合? 657 */ 658 public void odp( final String outputName ) throws Throwable { 659 saveDoc( outputName, getFilterName( getSuffix( inputName ), "odp" ) ); 660 } 661 662 /** 663 * PowerPoint(ppt)出力を行います? 664 * 665 * 入力形式で未対応?場?形式?入力ファイルの拡張子で判別)、例外が発行されます? 666 * 667 * 正常に処?終?た?合??close()を発行し、終???行って下さ?? 668 * また?例外が発生した?合??close(true)を発行し、終???行って下さ?? 669 * 670 * @param outputName 出力ファイル? 671 * @throws Throwable 何らか?エラーが発生した?合? 672 */ 673 public void ppt( final String outputName ) throws Throwable { 674 saveDoc( outputName, getFilterName( getSuffix( inputName ), "ppt" ) ); 675 } 676 677 /** 678 * 出力ファイルから出力形式を自動判別し?変換を行います? 679 * 680 * 入出力形式で未対応?場?形式?入出力ファイルの拡張子で判別)、例外が発行されます? 681 * 682 * 正常に処?終?た?合??close()を発行し、終???行って下さ?? 683 * また?例外が発生した?合??close(true)を発行し、終???行って下さ?? 684 * 685 * @param outputName 出力ファイル? 686 * @throws Throwable 何らか?エラーが発生した?合? 687 */ 688 public void auto( final String outputName ) throws Throwable { 689 String outSuffix = getSuffix( outputName ); 690 if( "pdf".equalsIgnoreCase( outSuffix ) ) { 691 savePdf( outputName, getFilterName( getSuffix( inputName ), outSuffix ), null ); 692 } 693 else { 694 saveDoc( outputName, getFilterName( getSuffix( inputName ), outSuffix ) ); 695 } 696 } 697 698 /** 699 * フィルター名を?して、各種ファイル形式に出力を行います? 700 * 701 * @param outputName 出力ファイル? 702 * @param filter フィルター? 703 */ 704 private void saveDoc( final String outputName, final String filter ) { 705 if( xComp == null ) { throw new HybsSystemException( "初めに?open()を実行して下さ? ); } 706 if( !checkOutput( outputName ) ){ return; } 707 708 PropertyValue[] storeProps = new PropertyValue[1]; 709 storeProps[0] = new PropertyValue(); 710 storeProps[0].Name = "FilterName"; 711 storeProps[0].Value = filter; 712 713 String url = "file:///" + outputName.replace( '\\', '/' ); 714 @SuppressWarnings("cast") // OpenOffice 3.2 での冗長なキャスト警告?抑止。キャストをはずすと、旧3.1 では、エラーになる? 715 XStorable xstorable = (XStorable) UnoRuntime.queryInterface( XStorable.class, xComp ); 716 try { 717 xstorable.storeAsURL( url, storeProps ); 718 } 719 catch ( Throwable th ) { 720 throw new HybsSystemException( "ファイルへの変換時にエラーが発生しました?filter=" + filter + "]", th ); 721 } 722 } 723 724 /** 725 * フィルターを指定してPDF出力を行います? 726 * 727 * @param outputName 出力ファイル? 728 * @param filter フィルター? 729 * @param pdfPasswd PDFパスワー? 730 */ 731 private void savePdf( final String outputName, final String filter, final String pdfPasswd ) { 732 if( xComp == null ) { throw new HybsSystemException( "初めに?open()を実行して下さ? ); } 733 if( !checkOutput( outputName ) ){ return; } 734 735 PropertyValue[] storeProps; 736 if( pdfPasswd == null || pdfPasswd.length() == 0 ) { 737 storeProps = new PropertyValue[1]; 738 storeProps[0] = new PropertyValue(); 739 storeProps[0].Name = "FilterName"; 740 storeProps[0].Value = filter; 741 } 742 // 帳票要求テーブルでPDFパスワードが設定されて?場? 743 else { 744 PropertyValue[] filterProps = new PropertyValue[2]; 745 filterProps[0] = new PropertyValue(); 746 filterProps[0].Name = "EncryptFile"; 747 filterProps[0].Value = true; 748 filterProps[1] = new PropertyValue(); 749 filterProps[1].Name = "DocumentOpenPassword"; 750 filterProps[1].Value = pdfPasswd; 751 752 storeProps = new PropertyValue[2]; 753 storeProps[0] = new PropertyValue(); 754 storeProps[0].Name = "FilterName"; 755 storeProps[0].Value = "calc_pdf_Export"; 756 storeProps[1] = new PropertyValue(); 757 storeProps[1].Name = "FilterData"; 758 storeProps[1].Value = filterProps; 759 } 760 761 String url = "file:///" + outputName.replace( '\\', '/' ); 762 @SuppressWarnings("cast") // OpenOffice 3.2 での冗長なキャスト警告?抑止。キャストをはずすと、旧3.1 では、エラーになる? 763 XStorable xstorable = (XStorable) UnoRuntime.queryInterface( XStorable.class, xComp ); 764 try { 765 xstorable.storeToURL( url, storeProps ); 766 } 767 catch ( Throwable th ) { 768 throw new HybsSystemException( "PDFファイルへの変換時にエラーが発生しました?filter=" + filter + "]", th ); 769 } 770 } 771 772 /** 773 * 出力ファイルのチェ?を行います? 774 * 775 * @param outputName 出力ファイル? 776 * 777 * @return 処?象かど?(入力ファイルと出力ファイルが同じ?合?、falseが返りま? 778 */ 779 private boolean checkOutput( final String outputName ) { 780 if( outputName == null || outputName.length() == 0 ) { 781 throw new HybsSystemException( "出力ファイルが指定されて?せん? ); 782 } 783 784 File inFile = new File( inputName ); 785 File outFile = new File( outputName ); 786 787 if( outFile.exists() ) { 788 if( inFile.getAbsoluteFile().equals( outFile.getAbsoluteFile() ) ) { 789 // 入力と出力が同じファイルの場合な何もしな? 790 return false; 791 } 792 else if( !outFile.delete() ) { 793 throw new HybsSystemException( "出力?の既存ファイルが削除できません?file=" + outputName + "]" ); 794 } 795 } 796 return true; 797 } 798 799 /** 800 * 入出力?形?拡張?からフィルター名を取得します? 801 * 802 * @param inSuffix 入力拡張? 803 * @param outSuffix 出力拡張? 804 * 805 * @return フィルター? 806 */ 807 private static String getFilterName( final String inSuffix, final String outSuffix ) { 808 String filterName = filterMap.get( inSuffix + "_" + outSuffix ); 809 if( filterName == null ) { 810 String errMsg = "入力形式?出力形式?、以下?対応表に基づき?設定して下さ??" + HybsSystem.CR 811 + "入力[Calc(ods) ,Excel(xls) ] ?出力[Calc(ods) ,Excel(xls) ,PDF]" + HybsSystem.CR 812 + "入力[Writer(odt) ,Word(doc) ] ?出力[Writer(odt) ,Word(doc) ,PDF]" + HybsSystem.CR 813 + "入力[Impress(odp),PowerPoint(ppt)] ?出力[Impress(odp),PowerPoint(ppt),PDF]" + HybsSystem.CR; 814 throw new HybsSystemException( errMsg ); 815 } 816 return filterName; 817 } 818 819 /** 820 * ファイル名から拡張?小文?を求めます? 821 * 822 * @param fileName ファイル? 823 * 824 * @return 拡張?小文? 825 */ 826 private static String getSuffix( final String fileName ) { 827 String suffix = null; 828 if( fileName != null ) { 829 // int sufIdx = fileName.lastIndexOf( "." ); 830 int sufIdx = fileName.lastIndexOf( '.' ); 831 if( sufIdx >= 0 ) { 832 suffix = fileName.substring( sufIdx + 1 ).toLowerCase( Locale.JAPAN ); 833 } 834 } 835 return suffix; 836 } 837 838 /** 839 * ドキュメント?変換を行うための簡易メソ?です? 840 * 841 * 変換方法?、?力ファイルの拡張子により自動的に決定されます? 842 * 843 * @param inputFile 入力ファイル? 844 * @param outputFile 出力ファイル? 845 * @see #convert(String[], String, boolean) 846 */ 847 public static final void convert( final String inputFile, final String outputFile ) { 848 convert( StringUtil.csv2Array( inputFile ), outputFile ); 849 } 850 851 /** 852 * ドキュメント?変換を行うための簡易メソ?です? 853 * 854 * 変換方法?、?力ファイルの拡張子により自動的に決定されます? 855 * 856 * @param inputFile 入力ファイル名?? 857 * @param outputFile 出力ファイル? 858 * @see #convert(String[], String, boolean) 859 */ 860 public static final void convert( final String[] inputFile, final String outputFile ) { 861 convert( inputFile, outputFile, true ); 862 } 863 864 /** 865 * ドキュメント?変換を行うための簡易メソ?です? 866 * 867 * 変換方法?、?力ファイルの拡張子により自動的に決定されます? 868 * 869 * isOnlineがtrueに?された場合?soffice.binのプロセスをファクトリークラス経由で生?し? 870 * キャ?ュします? 871 * ?、シス?リソースが読み込まれな??、バ?ファイルから起動した?合?、この方法? 872 * 利用できな?め?isOnlineをfalseに?する?があります? 873 * 874 * @param inputFile 入力ファイル名?? 875 * @param outputFile 出力ファイル? 876 * @param isOnline オンライン(Web環?の使用)かど? 877 */ 878 public static final void convert( final String inputFile[], final String outputFile, final boolean isOnline ) { 879 DocConverter_OOO dc = new DocConverter_OOO( inputFile, isOnline ); 880 try { 881 dc.open(); 882 dc.auto( outputFile ); 883 dc.close(); 884 } 885 catch ( Throwable th ) { 886 dc.close( true ); 887 throw new HybsSystemException( th ); 888 } 889 } 890 891 /** 892 * ドキュメント?変換を行います? 893 * 894 * 変換方法?、?力ファイルの拡張子により自動的に決定されます? 895 * 896 * @og.rev 4.3.1.1 (2008/08/23) mkdirs の戻り?判? 897 * 898 * @param args コマンド引数配? 899 * @throws Exception 何らか?エラーが発生したとき? 900 */ 901 public static void main( final String[] args ) throws Exception { 902 if( args.length < 2 ) { 903 System.out.println( "usage : OdsConverter [inputFile or inputDir] [outputDir]" ); 904 return; 905 } 906 907 File input = new File( args[0] ); 908 File output = new File( args[1] ); 909 910 // 4.3.1.1 (2008/08/23) mkdirs の戻り?判? 911 if( output.mkdirs() ) { 912 System.err.println( args[1] + " の ?レクトリ作?に失敗しました? ); 913 } 914 915 if( input.isDirectory() ) { 916 File[] inputFiles = input.listFiles(); 917 for( int i = 0; i<inputFiles.length; i++ ) { 918 String inputFile = inputFiles[i].getAbsolutePath(); 919 String outputFile = output.getAbsolutePath() + File.separator + inputFiles[i].getName().replace( ".xls", ".ods" ); 920 convert( StringUtil.csv2Array( inputFile ), outputFile, false ); 921 } 922 } 923 else { 924 String inputFile = input.getAbsolutePath(); 925 String outputFile = output.getAbsolutePath() + File.separator + input.getName().replace( ".xls", ".ods" ); 926 convert( StringUtil.csv2Array( inputFile ), outputFile, false ); 927 } 928 } 929 }