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 }