OSDN Git Service

1.00.00-beta
[jaxcel/jaxcel.git] / Jaxcel / src / org / hanei / jaxcel / report / ReportMaker.java
1 /**\r
2  * Copyright 2014 Hanei Management Co.,Ltd. \r
3  * \r
4  * This file is part of Jaxcel\r
5  * \r
6  *  Jaxcel is free software: you can redistribute it and/or modify\r
7  *  it under the terms of the GNU Lesser General Public License as published by\r
8  *  the Free Software Foundation, either version 3 of the License, or\r
9  *  (at your option) any later version.\r
10  *\r
11  *  Jaxcel is distributed in the hope that it will be useful,\r
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14  *  GNU Lesser General Public License for more details.\r
15  *\r
16  *  You should have received a copy of the GNU Lesser General Public License\r
17  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
18  */\r
19 package org.hanei.jaxcel.report;\r
20 \r
21 import java.io.File;\r
22 import java.io.FileOutputStream;\r
23 import java.io.IOException;\r
24 import java.io.InputStream;\r
25 import java.io.OutputStream;\r
26 import java.util.Map;\r
27 \r
28 \r
29 import org.apache.poi.hssf.usermodel.HSSFSheet;\r
30 import org.apache.poi.hssf.usermodel.HSSFWorkbook;\r
31 import org.apache.poi.openxml4j.opc.OPCPackage;\r
32 import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;\r
33 import org.apache.poi.poifs.filesystem.OfficeXmlFileException;\r
34 import org.apache.poi.ss.usermodel.Cell;\r
35 import org.apache.poi.ss.usermodel.Row;\r
36 import org.apache.poi.ss.usermodel.Sheet;\r
37 import org.apache.poi.ss.usermodel.Workbook;\r
38 import org.apache.poi.ss.usermodel.WorkbookFactory;\r
39 import org.apache.poi.ss.util.CellReference;\r
40 import org.apache.poi.xssf.usermodel.XSSFChartSheet;\r
41 import org.apache.poi.xssf.usermodel.XSSFDialogsheet;\r
42 import org.apache.poi.xssf.usermodel.XSSFWorkbook;\r
43 import org.hanei.jaxcel.exception.JaxcelInputException;\r
44 import org.hanei.jaxcel.exception.JaxcelOutputException;\r
45 import org.slf4j.LoggerFactory;\r
46 import org.slf4j.Logger;\r
47 \r
48 /**\r
49  * Excel帳票生成クラス<br>\r
50  * テンプレートのExcelファイルにデータを挿入することでExcel帳票を生成する。\r
51  * \r
52  * <h4>テンプレートの書式について</h4>\r
53  * <h5>${expression}</h5>\r
54  * <p>値出力。expressionを解析し値を出力する。</p>\r
55  * \r
56  * <h5>#foreach(${object in aryObject}[ rows:"number"][ cols:"number"][ direction:"row|col"][ style:"copy|^copy"][ shift:"true|false"][ block:"true|false"][ start:"number"][ end:"number"])</h5>\r
57  * <p>foreach句。配列やListオブジェクト、Mapオブジェクトの繰返し出力を行う。<br>\r
58  * プロパティにより、繰返し出力方向の指定や、繰返し回数、出力範囲以降のセルのシフト方法等を指定可能。</p>\r
59  * <table border="1" cellspacing="1">\r
60  * <tr><th>属性</th><th>説明</th></tr>\r
61  * <tr>\r
62  *              <td>${object in aryObject}</td>\r
63  *              <td>"${" 要素オブジェクト in 配列オブジェクト "}" のフォーマットで指定する。配列オブジェクトには配列、List、Mapが使用可能。<br>\r
64  *              rows・colsオプションで指定した範囲内で、要素オブジェクトで指定した名称で各インデックスの要素が出力可能。</td>\r
65  * </tr>\r
66  * <tr>\r
67  *              <td>rows</td>\r
68  *              <td>繰返し元の行数を正の整数で指定する。"1"指定で#foreach指示子が記述された行のみとなる。省略すると規定値である "1"となる。</td>\r
69  * </tr>\r
70  * <tr>\r
71  *              <td>cols</td>\r
72  *              <td>繰返し元の列数を正の整数で指定する。"1"指定で#foreach指示子が記述された列のみとなる。省略すると規定値である "1"となる。</td>\r
73  * </tr>\r
74  * <tr>\r
75  *              <td>direction</td>\r
76  *              <td>繰返し処理の方向を指定する。省略すると規定値である"row"となる。<br>\r
77  *              <table>\r
78  *              <tr><td>row</td><td>行方向に繰返す。</td></tr>\r
79  *              <tr><td>col</td><td>列方向に繰返す。</td></tr>\r
80  *              </table></td>\r
81  * </tr>\r
82  * <tr>\r
83  *              <td>style</td>\r
84  *              <td>繰返し元範囲(rows・colsオプションで指定する範囲)のセルスタイルのコピーについて指定する。省略すると規定値である"copy"となる。<br>\r
85  *              <table>\r
86  *              <tr><td>copy</td><td>セルスタイルをコピーする。</td></tr>\r
87  *              <tr><td>copy以外</td><td>セルスタイルをコピーしない。</td></tr>\r
88  *              </table></td>\r
89  * </tr>\r
90  * <tr>\r
91  *              <td>shift</td>\r
92  *              <td>繰返し範囲より後方の範囲のシフト方法について指定する。省略すると規定値である"true"となる。<br>\r
93  *              <table>\r
94  *              <tr><td>true</td><td>繰返し範囲より後方の範囲をdirectionオプションで指定した方向にシフトする。</td></tr>\r
95  *              <tr><td>false</td><td>シフトしない。</td></tr>\r
96  *              </table></td>\r
97  * </tr>\r
98  * <tr>\r
99  *              <td>block</td>\r
100  *              <td>矩形範囲での繰返し処理を行うかについて指定する。省略すると規定値である"true"となる。<br>\r
101  *              <table>\r
102  *              <tr><td>true</td><td>繰返し範囲を矩形範囲(rows・colsオプションで指定する範囲)とする。</td></tr>\r
103  *              <tr><td>false</td><td>繰返し範囲を繰返し元範囲に含まれる行・列全体とする。<br>\r
104  *              directionオプションが"row"の場合、繰返し元範囲に含まれる行全体が繰返し範囲となる。<br>\r
105  *              directionオプションが"col"の場合、繰返し元範囲に含まれる列全体が繰返し範囲となる。</td></tr>\r
106  *              </table></td>\r
107  * </tr>\r
108  * <tr>\r
109  *              <td>start</td>\r
110  *              <td>配列オブジェクトの出力開始インデックス(1起点)を正の整数、もしくは、正の整数を返却する関数で指定する。省略すると規定値である"1"となる。</td>\r
111  * </tr>\r
112  * <tr>\r
113  *              <td>end</td>\r
114  *              <td>配列オブジェクトの出力終了インデックス(1起点)を正の整数、もしくは、正の整数を返却する関数で指定する。省略すると配列オブジェクトの要素数となる。</td>\r
115  * </tr>\r
116  * <tr>\r
117  *              <td colspan="2">startオプションよりendオプションの指定値が小さい場合、配列オブジェクトを降順で出力する。<br>\r
118  *              配列オブジェクトの要素数は"size(配列オブジェクト)"関数で取得可能。</td>\r
119  * </tr>\r
120  * </table>\r
121  * \r
122  * <h5>#if(${expression}[ rows:"number"][ cols:"number"][ delete:"left|up|clear"][ block:"true|false"])</h5>\r
123  * <p>if句。expression判定式がtrue判定の場合は指定範囲の出力、false判定の場合は指定の方法で範囲を削除する。</p>\r
124  * <table border="1" cellspacing="1">\r
125  * <tr><th>属性</th><th>説明</th></tr>\r
126  * <tr>\r
127  *              <td>${expression}</td>\r
128  *              <td>判定式。"${" 式 "}" のフォーマットで指定する。Bool値を返す式を指定する。Bool値を返さない式の場合は、値がnullでなければtrueと判断する。</td>\r
129  * </tr>\r
130  * <tr>\r
131  *              <td>rows</td>\r
132  *              <td>制御範囲の行数を正の整数で指定する。"1"指定で#if指示子が記述された行のみとなる。省略すると規定値である "1"となる。</td>\r
133  * </tr>\r
134  * <tr>\r
135  *              <td>cols</td>\r
136  *              <td>制御範囲の列数を正の整数で指定する。"1"指定で#if指示子が記述された列のみとなる。省略すると規定値である "1"となる。</td>\r
137  * </tr>\r
138  * <tr>\r
139  *              <td>delete</td>\r
140  *              <td>判定式がflse判定の場合の制御範囲に対する操作を指定する。省略すると規定値である"left"となる。<br>\r
141  *              <table>\r
142  *              <tr><td>left</td><td>制御範囲セルを削除し、左に詰める。</td></tr>\r
143  *              <tr><td>up</td><td>制御範囲セルを削除し、上に詰める。</td></tr>\r
144  *              <tr><td>clear</td><td>制御範囲セルの値・計算式をクリアするのみで詰めない。</td></tr>\r
145  *              </table>\r
146  * </tr>\r
147  * <tr>\r
148  *              <td>block</td>\r
149  *              <td>矩形範囲での制御を行うかについて指定する。省略すると規定値である"true"となる。<br>\r
150  *              <table>\r
151  *              <tr><td>true</td><td>制御範囲を矩形範囲(rows・colsオプションで指定する範囲)とする。</td></tr>\r
152  *              <tr><td>false</td><td>制御範囲を矩形範囲に含まれる行・列全体とする。<br>\r
153  *              deleteオプションが"left"の場合、矩形範囲に含まれる列全体が制御範囲となる。<br>\r
154  *              deleteオプションが"up"の場合、矩形範囲に含まれる行全体が制御範囲となる。<br>\r
155  *              deleteオプションが"clear"の場合は無効。</td></tr>\r
156  *              </table></td>\r
157  * </tr>\r
158  * </table>\r
159  * \r
160  * @version 1.00.00\r
161  * @author Noboru Saito\r
162  */\r
163 public class ReportMaker {\r
164 \r
165         private static final Logger log = LoggerFactory.getLogger(ReportMaker.class);\r
166 \r
167         /**\r
168          * POIファイルシステム<br>\r
169          * Excel 2003 形式(.xls)\r
170          */\r
171         private NPOIFSFileSystem npoifs = null;\r
172         \r
173         /**\r
174          * POIファイルシステム<br>\r
175          * Excel 2007 形式(.xlsx, .xlsm)\r
176          */\r
177         private OPCPackage pkg = null;\r
178         \r
179         /**\r
180          *  EL式マネージャ\r
181          */\r
182         private ELManager elMgr = null;\r
183         \r
184         /**\r
185          *  コンテキスト\r
186          */\r
187         private JaxcelContext context  = null;\r
188 \r
189         /**\r
190          * コンストラクタ\r
191          */\r
192         public ReportMaker() {}\r
193 \r
194         /**\r
195          * 入力ストリームのExcelテンプレートファイルにデータを挿入することでExcel帳票を生成、Workbookオブジェクトを返却する。<br>\r
196          * 返却されたWorkbookオブジェクトはPOIを使用し、加工・出力が可能。<br>\r
197          * 入力ストリームは別途クローズが必要。\r
198          * \r
199          * @param template Excelテンプレートファイル入力ストリーム\r
200          * @param parameter テンプレートに挿入するデータ\r
201          * \r
202          * @return Workbookオブジェクト\r
203          * \r
204          * @throws JaxcelInputException 入力例外発生時\r
205          */\r
206         public Workbook makeReport(InputStream template, Map<String, Object> parameter) {\r
207                 log.trace("makeReport start");\r
208 \r
209                 // 引数チェック\r
210                 if(template == null) {\r
211                         log.error("template is null");\r
212                         throw new JaxcelInputException("template is null");\r
213                 }\r
214                 if(parameter == null) {\r
215                         log.debug("parameter is null");\r
216                 }\r
217 \r
218                 // Excelテンプレートファイルオープン\r
219                 Workbook book = openWorkbook(template);\r
220                 \r
221                 // Excel帳票生成\r
222                 makeReport(book, parameter);\r
223                 \r
224                 log.trace("makeReport end");\r
225                 return book;\r
226         }\r
227 \r
228         /**\r
229          * 入力ストリームのExcelテンプレートファイルにデータを挿入することでExcel帳票を生成、出力ストリームにExcel帳票を出力する。<br>\r
230          * 入出力ストリームは別途クローズが必要。\r
231          * \r
232          * @param template Excelテンプレートファイル入力ストリーム\r
233          * @param parameter テンプレートに挿入するデータ\r
234          * @param output Excel帳票出力ストリーム\r
235          *\r
236          * @throws JaxcelInputException 入力例外発生時\r
237          * @throws JaxcelOutputException 出力例外発生時\r
238          */\r
239         public void makeReport(InputStream template, Map<String, Object> parameter, OutputStream output) {\r
240                 log.trace("makeReport start");\r
241                 \r
242                 // Excel帳票生成\r
243                 Workbook book = makeReport(template, parameter);\r
244                 \r
245                 // 出力\r
246                 outputReport(book, output);\r
247 \r
248                 // テンプレートファイルクローズ\r
249                 close();\r
250 \r
251                 log.trace("makeReport end");\r
252         }\r
253 \r
254          /**\r
255          * 入力ストリームのExcelテンプレートファイルにデータを挿入することでExcel帳票を生成、Excel帳票ファイルを出力する。<br>\r
256          * 入力ストリームは別途クローズが必要。\r
257          * \r
258          * @param template Excelテンプレートファイル入力ストリーム\r
259          * @param parameter テンプレートに挿入するデータ\r
260          * @param output Excel帳票出力ファイル\r
261          *\r
262          * @throws JaxcelInputException 入力例外発生時\r
263          * @throws JaxcelOutputException 出力例外発生時\r
264          */\r
265         public void makeReport(InputStream template, Map<String, Object> parameter, File output) {\r
266                 log.trace("makeReport start");\r
267                 \r
268                 // Excel帳票生成\r
269                 Workbook book = makeReport(template, parameter);\r
270                 \r
271                 // 出力ストリーム\r
272                 FileOutputStream _output;\r
273                 try {\r
274                         _output = new FileOutputStream(output);\r
275                 }\r
276                 catch(Exception e) {\r
277                         log.error("output file open error: {}", e.getMessage(), e);\r
278                         throw new JaxcelOutputException("output file open error");\r
279                 }\r
280 \r
281                 // 出力\r
282                 outputReport(book, _output);\r
283                 try {\r
284                         _output.close();\r
285                 } catch (IOException e) {\r
286                         log.error("output file close error: {}", e.getMessage(), e);\r
287                         throw new JaxcelOutputException("output file close error");\r
288                 }\r
289 \r
290                 // テンプレートファイルクローズ\r
291                 close();\r
292 \r
293                 log.trace("makeReport end");\r
294         }\r
295         \r
296         /**\r
297          * Excelテンプレートファイルにデータを挿入することでExcel帳票を生成、Workbookオブジェクトを返却する。<br>\r
298          * 返却されたWorkbookオブジェクトはPOIを使用し、加工・出力が可能。<br>\r
299          * Excelテンプレートファイルは別途クローズが必要。\r
300          * \r
301          * @param template Excelテンプレートファイル\r
302          * @param parameter テンプレートに挿入するデータ\r
303          * \r
304          * @return Workbookオブジェクト\r
305          * \r
306          * @throws JaxcelInputException 入力例外発生時\r
307          */\r
308         public Workbook makeReport(File template, Map<String, Object> parameter) {\r
309                 log.trace("makeReport start");\r
310 \r
311                 // 引数チェック\r
312                 if(template == null) {\r
313                         log.error("template file is null");\r
314                         throw new JaxcelInputException("template file is null");\r
315                 }\r
316                 else if(!template.exists()) {\r
317                         log.error("template file does not exist: {}", template.getAbsolutePath());\r
318                         throw new JaxcelInputException("template file does not exist");\r
319                 }\r
320                 else if(!template.canRead()) {\r
321                         log.error("template file can not read: {}", template.getAbsolutePath());\r
322                         throw new JaxcelInputException("template file can not read");\r
323                 }\r
324                 if(parameter == null) {\r
325                         log.debug("parameter is null");\r
326                 }\r
327 \r
328                 // Excelテンプレートファイルオープン\r
329                 Workbook book = openWorkbook(template);\r
330                 \r
331                 // Excel帳票生成\r
332                 makeReport(book, parameter);\r
333                 \r
334                 log.trace("makeReport end");\r
335                 return book;\r
336         }\r
337 \r
338         /**\r
339          * Excelテンプレートファイルにデータを挿入することでExcel帳票を生成、出力ストリームにExcel帳票を出力する。<br>\r
340          * 出力ストリームは別途クローズが必要。\r
341          * \r
342          * @param template Excelテンプレートファイル\r
343          * @param parameter テンプレートに挿入するデータ\r
344          * @param output Excel帳票出力ストリーム\r
345          * \r
346          * @throws JaxcelInputException 入力例外発生時\r
347          * @throws JaxcelOutputException 出力例外発生時\r
348          */\r
349         public void makeReport(File template, Map<String, Object> parameter, OutputStream output) {\r
350                 log.trace("makeReport start");\r
351 \r
352                 // Workbook生成\r
353                 Workbook book = makeReport(template, parameter);\r
354 \r
355                 // 出力\r
356                 outputReport(book, output);\r
357         \r
358                 // テンプレートファイルクローズ\r
359                 close();\r
360 \r
361                 log.trace("makeReport end");\r
362         }\r
363 \r
364         /**\r
365          * Excelテンプレートファイルにデータを挿入することでExcel帳票を生成、Excel帳票ファイルを出力する。<br>\r
366          * \r
367          * @param template Excelテンプレートファイル\r
368          * @param parameter テンプレートに挿入するデータ\r
369          * @param output Excel帳票出力ファイル\r
370          * \r
371          * @throws JaxcelInputException 入力例外発生時\r
372          * @throws JaxcelOutputException 出力例外発生時\r
373          */\r
374         public void makeReport(File template, Map<String, Object> parameter, File output) {\r
375                 log.trace("makeReport start");\r
376 \r
377                 // Workbook生成\r
378                 Workbook book = makeReport(template, parameter);\r
379 \r
380                 // 出力ストリーム\r
381                 FileOutputStream _output;\r
382                 try {\r
383                         _output = new FileOutputStream(output);\r
384                 }\r
385                 catch(Exception e) {\r
386                         log.error("output file open error: {}", e.getMessage(), e);\r
387                         throw new JaxcelOutputException("output file open error");\r
388                 }\r
389 \r
390                 // 出力\r
391                 outputReport(book, _output);\r
392                 try {\r
393                         _output.close();\r
394                 } catch (IOException e) {\r
395                         log.error("output file close error: {}", e.getMessage(), e);\r
396                         throw new JaxcelOutputException("output file close error");\r
397                 }\r
398                 \r
399                 // テンプレートファイルクローズ\r
400                 close();\r
401 \r
402                 log.trace("makeReport end");\r
403         }\r
404         \r
405         /**\r
406          * ExcelテンプレートのWorkbookオブジェクトにデータを挿入することでExcel帳票を生成する。<br>\r
407          * Excelテンプレートファイルは別途クローズが必要。\r
408          * \r
409          * @param book Workbookオブジェクト\r
410          * @param parameter テンプレートに挿入するデータ\r
411          * \r
412          * @throws JaxcelInputException 入力例外発生時\r
413          */\r
414         public void makeReport(Workbook book, Map<String, Object> parameter) {\r
415                 log.trace("makeReport start");\r
416 \r
417                 // 引数チェック\r
418                 if(book == null) {\r
419                         log.error("workbook is null");\r
420                         throw new JaxcelInputException("Workbook is null");\r
421                 }\r
422                 else if(!(book instanceof HSSFWorkbook) && !(book instanceof XSSFWorkbook)) {\r
423                         log.error("Workbook is unsupport type: {}", book.getClass().getName());\r
424                         throw new JaxcelInputException("Workbook is unsupported type");\r
425                 }\r
426                 if(parameter == null) {\r
427                         log.debug("parameter is null");\r
428                 }\r
429 \r
430                 // Jaxlsコンテキスト生成\r
431                 context = new JaxcelContext();\r
432 \r
433                 // EL式マネージャ生成。パラメータ設定\r
434                 elMgr = new ELManager();\r
435                 elMgr.setParameter(parameter);\r
436                 \r
437                 // JaxlsコンテキストにEL式マネージャ設定\r
438                 context.setElManager(elMgr);\r
439 \r
440                 // Book生成\r
441                 makeBook(book);\r
442                 \r
443                 log.trace("makeReport end");\r
444         }\r
445 \r
446         /**\r
447          * ワークブックのオープン\r
448          * \r
449          * @param template Excelテンプレートファイル 入力ストリーム or ファイル\r
450          * \r
451          * @throws JaxcelInputException Excelテンプレートファイルオープン失敗時\r
452          */\r
453         private Workbook openWorkbook(Object template) {\r
454                 log.trace("openWorkbook start");\r
455 \r
456                 // Workbookオブジェクト \r
457                 Workbook book = null;\r
458         \r
459                 // Excelテンプレートファイルオープン\r
460                 \r
461                 try {\r
462                         // Excel2003以前\r
463                         if(template instanceof File) {\r
464                                 npoifs = new NPOIFSFileSystem((File) template);\r
465                         }\r
466                         else {\r
467                                 npoifs = new NPOIFSFileSystem((InputStream) template);\r
468                         }\r
469                         book = WorkbookFactory.create(npoifs);\r
470                 } catch(OfficeXmlFileException | IOException e1) {\r
471         \r
472                         // Excel2007以降\r
473                         try {\r
474                                 if(template instanceof File) {\r
475                                         pkg = OPCPackage.open((File) template);\r
476                                 }\r
477                                 else {\r
478                                         pkg = OPCPackage.open((InputStream) template);\r
479                                 }\r
480                                 book = WorkbookFactory.create(pkg);\r
481                         } catch (Exception e2) {\r
482                                 log.error("template file open error: {}. {}", e1.getMessage(), e2.getMessage());\r
483                         }\r
484                 }\r
485 \r
486                 // チェック\r
487                 if(book == null) {\r
488                         throw new JaxcelInputException("template file open error");\r
489                 }\r
490         \r
491                 log.trace("openWorkbook end");\r
492                 return book;\r
493         }\r
494 \r
495         \r
496         /**\r
497          * 出力ストリームにワークブックを出力する\r
498          * \r
499          * @version 1.00.00\r
500          * @param book  Workbookオブジェクト\r
501          * @param output        出力ストリーム\r
502          *\r
503          * @throws JaxcelOutputException 出力例外発生時\r
504          */\r
505         private void outputReport(Workbook book, OutputStream output) {\r
506                 log.trace("outputReport start");\r
507 \r
508                 try {\r
509                         book.write(output);\r
510                 } catch (Exception e) {\r
511                         log.error("workbook output error: {}", e.getMessage(), e);\r
512                         throw new JaxcelOutputException("workbook output error");\r
513                 }\r
514                 \r
515                 log.trace("outputReport end");\r
516         }\r
517 \r
518         /**\r
519          * Excelテンプレートファイルのクローズ<br>\r
520          * テンプレートファイルの変更は保存しません。\r
521          * \r
522          * @throws JaxcelOutputException 出力例外発生時\r
523          */\r
524         public void close() {\r
525                 log.trace("close start");\r
526 \r
527                 try {\r
528                         if (npoifs != null) {\r
529                                 npoifs.close();\r
530                                 log.debug("template file close.");\r
531                                 npoifs = null;\r
532                         }\r
533                         if (pkg != null) {\r
534                                 pkg.revert();\r
535                                 log.debug("template file close.");\r
536                                 pkg = null;\r
537                         }\r
538                 } catch (IOException e) {\r
539                         log.error("template file close error: {}", e.getMessage(), e);\r
540                         throw new JaxcelOutputException("template file close error");\r
541                 }\r
542 \r
543                 log.trace("close end");\r
544         }\r
545 \r
546         /**\r
547          * Workbook生成\r
548          * @param book Workbookオブジェクト\r
549          */\r
550         private void makeBook(Workbook book) {\r
551                 log.trace("makeBook start");\r
552                 \r
553                 // シートでループ\r
554                 log.debug("sheet count: {}", book.getNumberOfSheets());\r
555                 for(int i = 0; i < book.getNumberOfSheets(); i++) {\r
556                         // カレントシート取得\r
557                         Sheet sheet = book.getSheetAt(i);\r
558                         if(sheet == null) {\r
559                                 log.warn("sheet[{}] is null. skip", i);\r
560                                 continue;\r
561                         }\r
562                         else if((sheet instanceof HSSFSheet && ((HSSFSheet)sheet).getDialog()) || (sheet instanceof XSSFDialogsheet)) {\r
563                                 log.debug("sheet[{}] is dialog sheet. skip", i);\r
564                                 continue;\r
565                         }\r
566                         else if(sheet instanceof XSSFChartSheet) {\r
567                                 log.debug("sheet[{}] is chart sheet. skip", i);\r
568                                 continue;\r
569                         }\r
570                         \r
571                         log.debug("sheet[{}] name: {}", i, sheet.getSheetName());\r
572 \r
573                         // シート生成\r
574                         makeSheet(sheet);\r
575                 }\r
576                 \r
577                 // 再計算\r
578                 book.setForceFormulaRecalculation(true);\r
579                 \r
580                 log.trace("makeBook end");\r
581         }\r
582         \r
583         /**\r
584          * ワークシート生成\r
585          * @param sheet ワークシートオブジェクト\r
586      */\r
587         private void makeSheet(Sheet sheet) {\r
588                 log.trace("makeSheet start");\r
589                 \r
590                 Row row;                                                // 行オブジェクト\r
591                 Cell cell;                                              // セルブジェクト\r
592                 TLParser tlParser;                              // パーサ\r
593 \r
594                 // カレントシート設定、パーサ生成\r
595                 context.setCurrentSheet(sheet);\r
596                 tlParser = new TLParser(context);\r
597 \r
598                 //最大行数\r
599                 int lastRowNum = sheet.getLastRowNum();\r
600                 log.debug("lastRowNum: {}", lastRowNum);\r
601                 \r
602                 //最大セル数\r
603                 int maxColNum = 0;\r
604                 \r
605                 // 行方向にループ\r
606                 for(int rowIdx = 0; rowIdx <= lastRowNum; rowIdx++) {\r
607                         // 行取得\r
608                         row = sheet.getRow(rowIdx);\r
609 \r
610                         // チェック\r
611                         if(row == null) {\r
612                                 log.debug("row[{}] is null", (rowIdx + 1));\r
613                                 continue;\r
614                         }\r
615 \r
616                         // 列最終取得・最大列数更新\r
617                         if(row.getLastCellNum() > maxColNum) {\r
618                                 maxColNum = row.getLastCellNum();\r
619                                 log.debug("maxColNum: {}", maxColNum);\r
620                         }\r
621 \r
622                         // 列方向にループ\r
623                         for(int cellIdx = 0; cellIdx <= maxColNum; cellIdx++) {\r
624                                 // セル取得\r
625                                 cell = row.getCell(cellIdx);\r
626 \r
627                                 // チェック\r
628                                 if(cell == null) {\r
629                                         log.debug("cell[{}] is null", (new CellReference(rowIdx, cellIdx)).formatAsString());\r
630                                         continue;\r
631                                 }\r
632                                 \r
633                                 // セルタイプにより分岐\r
634                                 switch (cell.getCellType()) {\r
635                                 // 文字列セル、計算式セル\r
636                                 case Cell.CELL_TYPE_STRING:\r
637                                 case Cell.CELL_TYPE_FORMULA:\r
638                                         // パース\r
639                                         tlParser.parse(cell);\r
640                                         // 再パースフラグONなら\r
641                                         if(tlParser.isReParseCell()) {\r
642                                                 // もう一度そのセルからループする\r
643                                                 cellIdx--;\r
644                                         }\r
645                                         break;\r
646                                 // 文字列セル、計算式セル以外\r
647                                 default:\r
648                                         log.debug("cell type is not string or formula");\r
649                                         continue;\r
650                                 }\r
651 \r
652                                 // 列最終取得・最大列数更新\r
653                                 if(row.getLastCellNum() > maxColNum) {\r
654                                         maxColNum = row.getLastCellNum();\r
655                                         log.debug("maxColNum update: {}", maxColNum);\r
656                                 }\r
657                         }\r
658                         //最大行数更新\r
659                         if(lastRowNum < sheet.getLastRowNum()) {\r
660                                 lastRowNum = sheet.getLastRowNum();\r
661                                 log.debug("lastRowNum update: {}", lastRowNum);\r
662                         }\r
663                 }\r
664                 log.trace("transformSheet end");\r
665         }\r
666 }\r