OSDN Git Service

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