ScriptomでExcelに画像を貼付ける -その2-
ちょっとだけ実用的にしてみた。とあるディレクトリ(c:\temp)にある、template.xlsというExcelブックをひな形にして、さらにその中のtemplateシートをひな形にして(ややこしいな)、そのシートのB:3位置にそのディレクトリにあるPNGファイルを75%のサイズで貼付ける。
画像1枚貼付けるごとにシートを替えるので、貼付けた画像分だけシートができる(シートの数って最大いくつ?)。最後に、result.xlsって名前で保存しておしまい。
import org.codehaus.groovy.scriptom.* import org.codehaus.groovy.scriptom.tlb.office.* import org.codehaus.groovy.scriptom.tlb.office.excel.* Scriptom.inApartment { def dir = new File("c:/temp") def xlApp = new ActiveXObject('Excel.Application') xlApp.with { visible = false displayAlerts = false automationSecurity = MsoAutomationSecurity.msoAutomationSecurityForceDisable alertBeforeOverwriting = false askToUpdateLinks = false featureInstall = MsoFeatureInstall.msoFeatureInstallNone } def workbook = xlApp.workbooks.open("${dir.path}/template.xls") def anchor = workbook.sheets(1) def idx = 1 dir.eachFileMatch(~/.*\.png$/) { image -> workbook.worksheets("template").copy(anchor) workbook.worksheets("template (2)").with { name = "新しいシート_${idx++}" range("B3").select() pictures.insert(image.path).shapeRange.with { select() scaleWidth(0.75, MsoTriState.msoTrue, MsoScaleFrom.msoScaleFromTopLeft) scaleHeight(0.75, MsoTriState.msoTrue, MsoScaleFrom.msoScaleFromTopLeft) } } } workbook.saveAs("${dir.path}/result.xls") workbook.close() xlApp.visible = true xlApp.quit() }
あとは、用途に応じて書換えればいいか。それはそうと、ExcelHelper版作ってみたらExcelのプロセスが大量に残ってエラい目にあった。先のスクリプトでは、最後にExcelを可視化して手動でExcelを終了させてんだけど、もっとスマートなやり方はないものか...。
#ActiveXObject.safeRelease()なんて、それっぽいAPIはあるんだけどね。
(追記) xlApp.quit()
で死んでくれた。行儀良くするなら、try-catch-finallyで囲ってfinallyでやるべきなんだろな。
ScriptomでWordに画像を貼付ける
ついでにWord版も作ってみた。こっちも、とあるディレクトリ(c:\temp)にあるひな形ファイル(template.doc)を元に画像を貼付けて結果ファイル(result.doc)を書き出すよ。
Excel版と趣向が違うのは、画像の貼付け場所をフィールドで指定していること。フィールドタイプは{Comments}、フィールドの値+".png"をファイル名として画像を貼付けてる(サイズは75%)。
#「画像ファイルが無かった」とかのエラー処理はやってないので、よろしく。
import org.codehaus.groovy.scriptom.* import org.codehaus.groovy.scriptom.tlb.office.word.* Scriptom.inApartment { def dir = new File("c:/temp") def wdApp = new ActiveXObject('Word.Application') wdApp.visible = false def doc = wdApp.documents.open("${dir.path}/template.doc") def fields = doc.fields fields.update() fields.each { field -> if (field.type == WdFieldType.wdFieldComments) { def filename = "${field.result.text}.png" field.result.with { text = "" inlineShapes.addPicture("${dir.path}/${filename}").with { scaleWidth = 70 scaleHeight = 70 } } } } doc.saveAs("${dir.path}/result.doc") doc.close() wdApp.visible = true wdApp.quit() }
「WSHのほうが簡単じゃね?」なんて野暮なことは言わない。
(追記) 最後に可視化(wdApp.visible = true)して手で終らせるか、wdApp.quit()
で終らせるかは、まあ好みの問題だな。