Groovyでテーブルのデータを取得したい(6)
取るに足らないことなんですが、同じようなことで未来も躓きそうなので。
SafeArrayを作成して、for文でぐるぐる回すところなのですが、
for(r in rows){ if(1==rowNumber){ r.each{ safeArray.putAt([rowNumber,colNumber++],it.key) } rowNumber++ } colNumber = 1 r.each{ if( it.value instanceof oracle.sql.TIMESTAMP ) it.value = sdf.format(it.value.dateValue()) safeArray.putAt([rowNumber,colNumber++],it.value) } rowNumber++ }
の、
if( it.value instanceof oracle.sql.TIMESTAMP ) it.value = sdf.format(it.value.dateValue())
がどうしても綺麗にしたくて。。。
かと言ってOracleのTimeStamp型をやめるわけにもいかず。。。
でmetaClassにメソッドを動的に追加して、for文の中では追加したメソッドを実行すれば良いのではという
発想で書き直したのが以下のコードです。
import java.text.SimpleDateFormat import org.codehaus.groovy.scriptom.ActiveXObject import org.codehaus.groovy.scriptom.SafeArray def sql = groovy.sql.Sql.newInstance('jdbc:oracle:thin:@localhost:1521:ORCL','userid','password','oracle.jdbc.driver.OracleDriver') def xlApp = new ActiveXObject('Excel.Application') def username = "INIT" def workbook = xlApp.workbooks.Add SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss") oracle.sql.TIMESTAMP.metaClass.toString = {sdf.format(delegate.dateValue())} sql.eachRow("SELECT table_name FROM user_tables WHERE table_name LIKE 'BIZ_AB_%'"){ rs-> def rows = sql.rows("SELECT * FROM " + rs.table_name +" WHERE create_user_cd ='" + username + "'") if( rows.size() > 0 ){ def worksheet = workbook.worksheets.Add worksheet.name = rs.table_name def (long rowNumber, long colNumber) = [1,1] SafeArray safeArray = new SafeArray(org.codehaus.groovy.scriptom.SafeArray.VARIANT,1..rows.size()+1,1..rows[0].size()) for(r in rows){ if(1==rowNumber){ r.each{ safeArray.putAt([rowNumber,colNumber++],it.key) } rowNumber++ } colNumber = 1 r.each{ safeArray.putAt([rowNumber,colNumber++],it.value.toString())} rowNumber++ } worksheet.Range(worksheet.cells(1,1),worksheet.cells(rows.size()+1,rows[0].size())).Value = safeArray } } xlApp.visible = true
思ったとおり、速度的には早くなってませんが「綺麗」にはなっています^^;
Groovyで実装したクラスだけでなく、ライブラリのクラス(ここではoracle.sql.TIMESTAMP)に
対しても拡張できるところがすごいですね。(バージョン1.6以降らしいですけど)