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()で終らせるかは、まあ好みの問題だな。