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.report;
017
018 import org.opengion.hayabusa.common.HybsSystem;
019 import org.opengion.hayabusa.common.HybsSystemException;
020 import org.opengion.fukurou.util.LogWriter;
021
022 import org.opengion.fukurou.util.QrcodeImage;
023 import org.opengion.fukurou.util.ReplaceString;
024
025 import java.io.IOException;
026 import java.util.Map ;
027 import java.util.HashMap ;
028 import java.util.regex.Pattern;
029 import java.util.regex.Matcher ;
030
031 /**
032 * DBTableReport インターフェース を実è£?�—たHTMLをパースするクラスですã?
033 * AbstractDBTableReport を継承してã�?�¾すã?で?ŒwriteReport() のみオーバã?ライドして??
034 * 固定長æ–?—ファイルの出力機è?を実現してã�?�¾すã?
035 *
036 * @og.group 帳票シスãƒ?ƒ
037 *
038 * @version 4.0
039 * @author Kazuhiko Hasegawa
040 * @since JDK5.0,
041 */
042 public class DBTableReport_HTML extends AbstractDBTableReport {
043 private static final String TR_IN = "<tr" ;
044 private static final String TR_OUT = "</tr>" ;
045 private static final String TD_OUT = "</td>" ; // 3.5.5.9 (2004/06/07)
046 private static final String PAGE_BREAK = "page-break" ;
047 private static final String PAGE_END_CUT = "PAGE_END_CUT" ; // 3.6.0.0 (2004/09/17)
048 private static final String END_TAG = "</table></body></html>";
049 private static final String CUT_TAG1 = "<span";
050 private static final String CUT_TAG2 = "</span>";
051 private static final String SPACE_ST = "<span style=\"mso-spacerun: yes\">"; // 3.6.0.0 (2004/09/17)
052 private static final String SPACE = " "; // 3.6.0.0 (2004/09/17)
053 private static final String SPACE_ED = " </span>"; // 3.6.0.0 (2004/09/17)
054 private static final String FRAMESET = "Excel Workbook Frameset" ;
055
056 private static final String CR = System.getProperty("line.separator");
057
058 // <td xxx="yyy">zzzz</td> 形式とマッチしã€?zzzz< 部åˆ?‚’前方参ç?しますã?
059 private static final Pattern PTN1 = Pattern.compile("<td[^>]*(>.*?<)/td>");
060 // >aaaa<span bb="cc">dddd</span>eeee< 形式に?’文字以上ã?スペã?スを含ã‚?ƒ‡ータと
061 // マッチし、aaaa,dddd,eeee を前方参ç?しますã?
062 private static final Pattern PTN2 = Pattern.compile("[^>]*>([^<]*? ++[^<]*?)<");
063 // aa bb cc 形式とマッチし、各連続スペã?ス部åˆ?‚’前方参ç?しますã?
064 private static final Pattern PTN3 = Pattern.compile("( +)");
065
066 private boolean fileEnd = false; // ファイルの読み取り制御
067
068 // 3.6.1.0 (2005/01/05) QRコーãƒ??’次å…?ƒ�ーコーãƒ?用の出力ファイル管ç�?
069 private Map<String,String> qrFileMap = null;
070 // <v:shape ?¥?¥?¥ alt="{@QRCODE.XXXX}" ?¥?¥?¥>
071 // <v:imagedata src="yyy" ?¥?¥?¥>?¥?¥?¥</v:shape>形式とマッチしã€?
072 // xxx 部åˆ?�¨、yyy 部åˆ?‚’前方参ç?しますã?
073 private static final Pattern IMGPTN1 = Pattern.compile("<v:shape [^>]*alt=\"\\{@QRCODE.([^\\}]*)\\}\"[^>]*>[^<]*<v:imagedata [^>]*src=\"([^\"]*)\"[^>]*>");
074 // <img ?¥?¥?¥ src="yyy" ?¥?¥?¥ alt="{@QRCODE.XXXX}" ?¥?¥?¥ > 形式とマッチしã€?
075 // yyy 部åˆ?�¨、xxx 部åˆ?‚’前方参ç?しますã?
076 private static final Pattern IMGPTN2 = Pattern.compile("<img [^>]*src=\"([^\"]*)\"[^>]*alt=\"\\{@QRCODE.([^\\}]*)\\}\"[^>]*>");
077
078 // 4.0.0 (2007/06/08) pageEndCut = true 時ã? LINE_COPY 機è?の実è£?
079 private static final String LINE_COPY = "LINE_COPY" ; // 4.0.0 (2007/06/08)
080 private String lineCopy = null;
081
082 /**
083 * 入力文字å? を読み取って、å?力しますã?
084 * tr タグを目印にã€?¼‘è¡?trタグé–?ずつ取り出しますã?
085 * 読み取りを終äº?�™るå?合ã?、null を返しますã?
086 * å�?‚µブクラスで実è£?�—てくださいã€?
087 *
088 * @og.rev 3.0.0.1 (2003/02/14) ä¸?º¦もValueセãƒ?ƒˆしてã�?�ªã�??に次ペã?ジ要求があったå?合ã?、フォーマットがおかしい
089 * @og.rev 3.6.0.0 (2004/09/24) フォーマットエラーの判å®?formatErr)をã?親クラスに移動しますã?
090 *
091 * @return 出力文字å?
092 */
093 @Override
094 protected String readLine() {
095 if( fileEnd ) { return null; }
096
097 // pageEndCut 時に、データがオーバã?してã�?�ªã�?–“のみ、lineCopy があれã?返すã€?
098 if( pageEndCut && !rowOver && lineCopy != null ) {
099 lineCopyCnt ++ ; // 雛形は、_0 のみが毎回返される為の、加ç®?
100 return lineCopy ;
101 }
102
103 final StringBuilder buf ;
104 try {
105 String line = reader.readLine();
106 if( line == null ) {
107 if( rowOver ) {
108 return null;
109 }
110 else {
111 initReader();
112 initWriter();
113 line = reader.readLine();
114 if( line == null ) { return null; }
115 }
116 }
117 if( line.indexOf( FRAMESET ) >= 0 ) {
118 String errMsg = "HTML ファイルエラー :" + line + HybsSystem.CR
119 + "Excelファイル形式がフレーãƒ?�«なってã�?�¾すã?(è¤?•°シートには未対å¿?" ;
120 throw new HybsSystemException( errMsg );
121 }
122 if( line.indexOf( TR_IN ) >= 0 ) {
123 buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
124 buf.append( line );
125 int trLebel = 1; // 行を表ã�?<tr> のレベル
126 while( trLebel != 0 ) {
127 line = reader.readLine();
128 // 4.0.0 (2005/08/31) null 参ç?はずし対å¿?
129 if( line != null ) {
130 if( line.indexOf( TR_IN ) >= 0 ) { trLebel++ ; }
131 if( line.indexOf( TR_OUT ) >= 0 ) { trLebel-- ; }
132 buf.append( CR ).append( line );
133 }
134 else {
135 String errMsg = "HTML ファイルエラー :" + buf.toString() + HybsSystem.CR
136 + "è¡?TR)の整合æ?が取れる前に、ファイルが終äº?�—ましたã€? ;
137 throw new HybsSystemException( errMsg );
138 }
139 }
140 }
141 else {
142 return line;
143 }
144 } catch(IOException ex) {
145 String errMsg = "HTML ファイル 読取時にエラーが発生しましたã€? + reader;
146 throw new HybsSystemException( errMsg,ex ); // 3.5.5.4 (2004/04/15) 引数の並びé ?¤‰更
147 }
148
149 String rtnLine = buf.toString() ;
150
151 // lineCopy æƒ??の取得ã?
152 if( pageEndCut && !rowOver ) {
153 // LINE_COPY は削除しますã?で、表示上見えるよã�?�«しておいてくださいã€?
154 int adrs = rtnLine.indexOf( LINE_COPY );
155 if( adrs >= 0 ) {
156 lineCopy = rtnLine.substring( 0,adrs )
157 + rtnLine.substring( adrs + LINE_COPY.length() ) ;
158 rtnLine = lineCopy ;
159 }
160 }
161
162 return rtnLine ;
163 }
164
165 /**
166 * 入力文字å? を加工して、å?力しますã?
167 * {@XXXX} をテーブルモãƒ?ƒ«より読み取り、å?をセãƒ?ƒˆしますã?
168 * å�?‚µブクラスで実è£?�—てくださいã€?
169 *
170 * @og.rev 3.0.0.1 (2003/02/14) ä¸?º¦もValueセãƒ?ƒˆしてã�?�ªã�??に次ペã?ジ要求があったå?合ã?、フォーマットがおかしい
171 * @og.rev 3.0.0.2 (2003/02/20) {@XXXX}æ–?—が、EXCELに表示しきれなã�??合に挿入されるタグの削除処ç�??変更ã€?
172 * @og.rev 3.5.0.0 (2003/09/17) {@XXXX}æ–?—ã?スペã?スをã?&nbsp;と置き換えますã?
173 * @og.rev 3.5.0.0 (2003/09/17) {@XXXX}æ–?—がアンバランス時にHybsSystemExceptionを発行するã?
174 * @og.rev 3.5.5.9 (2004/06/07) {@XXXX}の連続å?ç�??アドレス計算方法がã€?–“違ってã�?�¾したので修正しますã?
175 * @og.rev 3.6.0.0 (2004/09/17) pageEndCut ã�?true の場合ã?、PAGE_END_CUT æ–?—å?のある行を削除しますã?
176 * @og.rev 3.6.0.0 (2004/09/24) フォーマットエラーの判å®?formatErr)をã?親クラスに移動しますã?
177 * @og.rev 3.6.1.0 (2005/01/05) QRコーãƒ??’次å…?ƒ�ーコーãƒ?の機è?追åŠ?
178 * @og.rev 3.8.1.2 (2005/12/19) PAGE_END_CUTの判定にdataOver フラグを使用ã€?
179 *
180 * @param inLine 入力文字å?
181 *
182 * @return 出力文字å?
183 */
184 @Override
185 protected String changeData( final String inLine ) {
186 // rowOver で、かつ ペã?ジブレークかã?ージエンドカãƒ?ƒˆの場合ã?処ç�?µ‚äº??
187 if( rowOver && ( inLine.indexOf( PAGE_BREAK ) >= 0 ) ) {
188 fileEnd = true;
189 return END_TAG;
190 }
191
192 String chLine = changeHeaderFooterData( inLine ) ;
193
194 // 3.6.1.0 (2005/01/05) QRコーãƒ??’次å…?ƒ�ーコーãƒ?の機è?追åŠ?
195 if( chLine.indexOf( "{@QRCODE." ) >= 0 ) {
196 chLine = qrcodeReplace( chLine );
197 }
198
199 int st = chLine.indexOf( "{@" );
200 // 3.8.1.2 (2005/12/19) {@XXXX}の存在しなã�?¡Œも PAGE_END_CUTの判定を行うã€?
201
202 StringBuilder buf = new StringBuilder( chLine );
203
204 boolean spaceInFlag = false; // {@XXXX} 変数のãƒ??タにスペã?スを含ã‚?�‹どã�?�‹チェãƒ?‚¯
205 while( st >= 0 ) {
206 int end = buf.indexOf( "}",st+2 );
207
208 // EXCELに表示しきれなã�?–‡字ã?、CUT_TAG1,CUT_TAG2 が挿入されてしまã�?‚ºã€?
209 // 削除するå¿?¦�があるã€?
210 int cutSt1 = buf.indexOf( CUT_TAG1,st+2 );
211 if( cutSt1 >= 0 && cutSt1 < end ) {
212 int cutEnd1 = buf.indexOf( ">",cutSt1 );
213
214 int cutSt2 = buf.indexOf( CUT_TAG2,end );
215 if( cutSt2 >= 0 ) {
216 buf.delete( cutSt2, cutSt2 + CUT_TAG2.length() );
217 }
218 buf.delete( cutSt1, cutEnd1+1 );
219 // 途中をカãƒ?ƒˆした為、もã�?¸?º¦計算しなおしã€?
220 end = buf.indexOf( "}",st+2 ); // 3.5.5.9 (2004/06/07)
221 }
222
223 // 3.5.5.9 (2004/06/07)
224 // 関数等を使用すると、{@XXXX} æ–?—å?を直接åŠ?·¥したãƒ??タがå?力されるã€?
225 // こã?åŠ?·¥されたデータは、HTML 表示に使用されるだけã?ため、削除しますã?
226 // 削除方法ã?、{@XXX</td> を想定してã�?‚‹為ã€?{@ から </td> の間ですã?
227 int td_out = buf.indexOf( TD_OUT,st+2 );
228 if( td_out >= 0 && td_out < end ) {
229 buf.delete( st, td_out );
230 // {@XXXX} パラメータが消えたã?で、次の計算を行いますã?
231 st = buf.indexOf( "{@",st+4 ); // 3.5.5.9 (2004/06/07)
232 continue ;
233 }
234
235 // 途中をカãƒ?ƒˆした為、もã�?¸?º¦計算しなおしã€?
236 // フォーマットがおかしい場合ã?処ç�?
237 if( end < 0 ) {
238 String errMsg = "こã?ãƒ?ƒ³プレートファイルの {@XXXX} がã?フォーマットエラーですã?"
239 + HybsSystem.CR
240 + chLine.substring( st ) ;
241 throw new HybsSystemException( errMsg );
242 }
243
244 String key = buf.substring( st+2,end );
245
246 String val = getValue( key );
247 if( val.indexOf( " " ) >= 0 ) { spaceInFlag = true; }
248
249 // {@XXXX} ã‚?実際の値と置き換えるã€?
250 buf.replace( st,end+1,val );
251
252 // {@ の 存在チェãƒ?‚¯ã€?
253 st = buf.indexOf( "{@",st-1 ); // 3.5.5.9 (2004/06/07)
254 }
255
256 // 3.6.0.0 (2004/09/17) pageEndCut ã�?true の場合ã?、PAGE_END_CUT æ–?—å?のある行を削除しますã?
257 // ここで判定するã?は、PAGE_END_CUT æ–?—そのもã?がã?åŠ?·¥されてã�?‚‹可能性があるためã?
258 String rtn = buf.toString();
259 if( dataOver && pageEndCut ) { // 3.8.1.2 (2005/12/19)
260 String temp = rtn.replaceAll( CUT_TAG1 + "[^>]*>" ,"" );
261 if( temp.indexOf( PAGE_END_CUT ) >= 0 ) {
262 rtn = "" ;
263 }
264 }
265 else {
266 // 3.6.0.0 (2004/09/17) スペã?ス置き換えã?ã€?td XXX>YYY</td> の YYYのç¯?›²のみとするã€?
267 if( spaceInFlag ) {
268 rtn = spaceReplace( rtn ) ;
269 }
270 }
271 return rtn ;
272 }
273
274 /**
275 * è¶?‰¹殊å?ç�??
276 * EXCEL の ヘッãƒ??/フッター部åˆ??、\{\@XXXX\} と、エスケープ文字が付加されã‚?
277 * ので、このæ–?—å?を見つけたらã?{@XXXX} に、戻して処ç�?�™るよã�?�«するã€?
278 *
279 * @param inLine 入力文字å?
280 *
281 * @return 出力文字å?
282 */
283 private String changeHeaderFooterData( final String inLine ) {
284 int st = inLine.indexOf( "\\{\\@" );
285 if( st < 0 ) { return inLine; }
286
287 StringBuilder buf = new StringBuilder( inLine );
288
289 while( st >= 0 ) {
290 buf.deleteCharAt( st ); // 初めの '\'
291 buf.deleteCharAt( st+1 ); // ?‘文字削除してã�?‚‹為ã€?1 番目を削除
292 int end = buf.indexOf( "\\}",st+2 );
293 // フォーマットがおかしい場合ã?処ç�?
294 if( end < 0 ) {
295 String errMsg = "こã?ãƒ?ƒ³プレートã? HeaderFooter 部åˆ?? {@XXXX} がã?書式エラーですã?"
296 + HybsSystem.CR
297 + inLine ;
298 throw new HybsSystemException( errMsg );
299 }
300 buf.deleteCharAt( end ); // 初めの '\'
301 st = buf.indexOf( "\\{\\@",end + 1 );
302 }
303 return buf.toString();
304 }
305
306 /**
307 * 入力文字å? を読み取って、å?力しますã?
308 * å�?‚µブクラスで実è£?�—てくださいã€?
309 *
310 * @param line 入力文字å?
311 */
312 @Override
313 protected void println( final String line ) {
314 writer.println( line );
315 }
316
317 /**
318 * {@XXXX}æ–?—変換後ã?スペã?スをã?&nbsp;と置き換えますã?
319 *
320 * ただしã?式などを使用すると、td タグの属æ?æƒ??に{@XXXX}æ–?—が含まã‚?
321 * これに、EXCELのスペã?スであるã€?lt;span style="mso-spacerun:
322 * yes">&nbsp;&nbsp;</span>
323 * と置き換えると、属æ?リスト中のタグとã�?�†入れ子状態が発生する為ã€?
324 * これは、置き換えませんã€?
325 * <td XXX>YYY</td> の YYYのç¯?›² を置き換えることになりますã?
326 *
327 * ここではã€?�Ž去の互換性を最大限確保する為に、特殊な方法で、å?ç�?�—ますã?
328 * 前後ã?スペã?スを取り除ã�?�Ÿæ–?—å?で、かつã€?¼’つ以上ã?連続したスペã?スã�?
329 * 存在する場合ã?み、trim してã€??続スペã?スをã?&nbsp;と置き換えますã?
330 * æ–?—ã?間に連続スペã?スがなã�??合ã?、前後ã?スペã?スも削除せずにã€?
331 * å…??æ–?—å?をそのまま返しますã?
332 * 前後ã?スペã?スを変換してしまã�?�¨、数字型の場合に、EXCELでの計算式がエラーになりますã?
333 *
334 * @og.rev 3.5.0.0 (2003/09/17) 新規追åŠ?
335 * @og.rev 3.5.5.0 (2004/03/12) 連続スペã?スの処ç�?‚’EXCELの方式に合わせる
336 * @og.rev 3.6.0.0 (2004/09/17) スペã?ス置き換えã?ã€?td XXX>YYY</td> の YYYのç¯?›²のみとするã€?
337 * @og.rev 3.6.1.0 (2005/01/05) 置換ロジãƒ?‚¯修正(ReplaceString クラスを使用)
338 *
339 * @param target å…??æ–?—å?
340 *
341 * @return 置換えた文字å?
342 */
343 private String spaceReplace( final String target ) {
344 ReplaceString repData = new ReplaceString();
345
346 Matcher match1 = PTN1.matcher( target ) ;
347 while( match1.find() ) {
348 int st1 = match1.start(1);
349 String grp1 = match1.group(1);
350 Matcher match2 = PTN2.matcher( grp1 ) ;
351 while( match2.find() ) {
352 int st2 = match2.start(1);
353 String grp2 = match2.group(1);
354 Matcher match3 = PTN3.matcher( grp2 ) ;
355 while( match3.find() ) {
356
357 int st = st1 + st2 + match3.start(1);
358 int ed = st1 + st2 + match3.end(1);
359
360 repData.add( st,ed,makeSpace( ed-st ) );
361 }
362 }
363 }
364
365 String rtn = repData.replaceAll( target );
366
367 return rtn ;
368 }
369
370 /**
371 * æŒ?®šã?個数のスペã?スæ–?—を表すã?EXCEL の記号を作æ?しますã?
372 *
373 * EXCELでは、スペã?ス?’å?以上をã€?lt;span style="mso-spacerun: yes">&nbsp;&nbsp;</span>
374 * 形式に置き換えますã?これは、EXCELがHTML変換する時ã?ルールですã?
375 *
376 * ここでは、スペã?スの個数-1 の &nbsp; を持つ、上記ã?æ–?—å?を作æ?しますã?
377 * æœ?¾Œã?ä¸?�¤は、本物のスペã?ス記号を割り当てますã?
378 *
379 * @og.rev 3.6.0.0 (2004/09/17) 新規追åŠ?
380 *
381 * @param cnt スペã?スの個数
382 *
383 * @return 置換えた文字å?
384 */
385 private String makeSpace( final int cnt ) {
386 StringBuilder buf = new StringBuilder( 40 + cnt * 6 );
387 buf.append( SPACE_ST );
388 for( int i=1; i<cnt; i++ ) {
389 buf.append( SPACE );
390 }
391 buf.append( SPACE_ED );
392
393 return buf.toString();
394 }
395
396 /**
397 * {@QRCODE.XXXX} を含ã‚?æ–?—å?の alt 属æ?ã‚?src 属æ?にセãƒ?ƒˆしますã?
398 *
399 * QRコードã?画像を入れ替えるため、alt属æ?に設定してある キーæƒ??をå?にã€?
400 * ?’次å…?ƒ�ーコード画像を作æ?しã?そã?ファイル名を、src 属æ?に設定することでã€?
401 * 動的に画像ファイルのリンクを作æ?しますã?
402 * 現在のEXCELでは、バージョンによってã€?¼’種類ã?画像表示方法が存在するようでã€?
403 * ?‘画像に付きã€?¼’ç®?‰€の変更がå¿?¦�ですã?こã??’ç®?‰€は、変換方法が異なる為ã€?
404 * 全く別の処ç�?‚’行うå¿?¦�がありますã?
405 *
406 * <v:shape ?¥?¥?¥ alt="{@QRCODE.XXXX}" ?¥?¥?¥>
407 * <v:imagedata src="yyy" ?¥?¥?¥>?¥?¥?¥</v:shape>形式とマッチしã€?
408 * xxx 部åˆ?�¨、yyy 部åˆ?‚’前方参ç?しますã?
409 *
410 * <img ?¥?¥?¥ src="yyy" ?¥?¥?¥ alt="{@QRCODE.XXXX}" ?¥?¥?¥ > 形式とマッチしã€?
411 * yyy 部åˆ?�¨、xxx 部åˆ?‚’前方参ç?しますã?
412 *
413 * 画像ã?エンコードã?、alt属æ?に設定したã?{@QRCODE.XXXX} æ–?—å?の
414 * XXXX 部åˆ??カラãƒ?ƒ‡ータ(通常、{@XXXX} で取得できる値)を使用しますã?
415 * ãƒ??タが存在しなã�??合ã?、src="yyy" 部を削除することで対応しますã?
416 * なおã?後続å?ç�??関係で、alt="{@QRCODE.XXXX}" æ–?—å?は、削除しますã?
417 *
418 * @og.rev 3.6.1.0 (2005/01/05) 新規追åŠ?
419 *
420 * @param target å…??æ–?—å?
421 *
422 * @return 置換えた文字å?
423 */
424 private String qrcodeReplace( final String target ) {
425 ReplaceString repData = new ReplaceString();
426
427 Matcher match1 = IMGPTN1.matcher( target ) ;
428 while( match1.find() ) {
429 String altV = match1.group(1);
430
431 int stAlt = match1.start(1) - 9 ; // {@QRCODE. まで遡ã‚?
432 int edAlt = match1.end(1) + 1 ; // } を含める
433 repData.add( stAlt,edAlt,"" ); // {@QRCODE.XXXX} の部åˆ?‰Š除
434
435 int st = match1.start(2);
436 int ed = match1.end(2);
437
438 String msg = getValue( altV ); // QRコード変換するæ–?—å?の取å¾?
439 if( msg != null && msg.length() > 0 ) {
440 String newStr = makeQrImage( altV,msg ); // 画像ファイルのファイルå�?
441 repData.add( st,ed,newStr );
442 }
443 else {
444 repData.add( st-5,ed+1,"" ); // src="yyy" 部åˆ??み削除
445 }
446 }
447
448 Matcher match2 = IMGPTN2.matcher( target ) ;
449 while( match2.find() ) {
450 int st = match2.start(1);
451 int ed = match2.end(1);
452
453 String altV = match2.group(2);
454 int stAlt = match2.start(2) - 9 ; // {@QRCODE. まで遡ã‚?
455 int edAlt = match2.end(2) + 1 ; // } を含める
456 repData.add( stAlt,edAlt,"" ); // {@QRCODE.XXXX} の部åˆ?‰Š除
457
458 String msg = getValue( altV ); // QRコード変換するæ–?—å?の取å¾?
459 if( msg != null && msg.length() > 0 ) {
460 String newStr = makeQrImage( altV,msg ); // 画像ファイルのファイルå�?
461 repData.add( st,ed,newStr );
462 }
463 else {
464 repData.add( st-5,ed+1,"" ); // src="yyy" 部åˆ??み削除
465 }
466 }
467
468 String rtn = repData.replaceAll( target ) ;
469
470 return rtn ;
471 }
472
473 /**
474 * æŒ?®šã?カラãƒ?��と、QRコード変換するæ–?—å?より、画像を作æ?しますã?
475 *
476 * 返り値は、作æ?した画像ファイルのファイル名ですã?
477 * これは、データが存在しなã�??合に、src="" を返すå¿?¦�があるためã€?
478 * (でなã�?�¨、画像へのリンクが表示されてしまã�??)
479 * src="./帳票ID.files/image00x.png" とã�?�†画像ファイルのアドレス部åˆ?‚’
480 * {@QRCODE_カラãƒ?��} 形式に変更しておくå¿?¦�がありますã?
481 *
482 * @og.rev 3.6.1.0 (2005/01/05) 新規追åŠ?
483 *
484 * @param key カラãƒ?��
485 * @param msg QRコード変換するæ–?—å?
486 *
487 * @return 画像ファイルのファイルå�?
488 */
489 private String makeQrImage( final String key, final String msg ) {
490 if( msg == null || msg.length() == 0 ) { return "" ; }
491
492 String realClmName = null ;
493 int sp = key.lastIndexOf( '_' );
494 if( sp >= 0 ) {
495 try {
496 int row = Integer.parseInt( key.substring( sp+1 ) );
497 int realRow = getRealRow( row );
498 realClmName = key.substring( 0,sp ) + "_" + realRow ;
499 }
500 catch (NumberFormatException e) { // 4.0.0 (2005/01/31)
501 String errMsg = "警告:QRCODE名ã?ヘッãƒ??に'_'カラãƒ?��が使用";
502 LogWriter.log( errMsg );
503 }
504 }
505 else {
506 realClmName = key ;
507 }
508
509 if( qrFileMap == null ) { qrFileMap = new HashMap<String,String>(); }
510 if( qrFileMap.containsKey( realClmName ) ) { // Map にすでに存在してã�?‚‹ã€?
511 return qrFileMap.get( realClmName );
512 }
513
514 // 帳票?©?¤ をå?に、画像ファイルの保存フォルãƒ?‚’求めますã?
515 String filename = "./" + listId + ".files/" + realClmName + ".png";
516 String fullAddress = htmlDir + filename ;
517
518 QrcodeImage qrImage = new QrcodeImage();
519 qrImage.init( msg,fullAddress );
520 qrImage.saveImage();
521
522 qrFileMap.put( realClmName,filename );
523 return filename;
524 }
525 }