2012年9月10日月曜日

Clojure+leiningen+Apache POI

いつか業務でこっそり使うことを夢見てExcelをいじってみます。

1. leiningenでプロジェクト作成
 lein new poitest

2. 作成されたプロジェクトのディレクトリのproject.cljを編集
(defproject poitest "0.1.0-SNAPSHOT"
  :description "Apache POI Test"
  :dependencies [[org.clojure/clojure "1.4.0"]
                 [org.apache.poi/poi "3.8"]
                 [org.apache.poi/poi-ooxml "3.8"]]
  :main poitest.core)

3. 依存解決
 lein deps

4. コードを書く
(ns poitest.core
  (:gen-class))

(import '(org.apache.poi.xssf.usermodel
          XSSFSheet
          XSSFWorkbook
          XSSFRow
          XSSFCell)
        '(org.apache.poi.ss.usermodel
          WorkbookFactory))

(import '(java.io
          FileInputStream
          FileOutputStream))

(defn load-workbook [path]
  (-> path FileInputStream. WorkbookFactory/create))

(defn rows [^XSSFSheet  sheet]
  (let [nrows (.getPhysicalNumberOfRows sheet)]
    (letfn [(f [i]
              (if (<= nrows i)
                nil
                (cons (.getRow sheet i)
                      (lazy-seq (f (inc i))))))]
      (f 0))))

(defn create-9x9 [path]
  (let [wb (XSSFWorkbook.)
        sh (.createSheet wb)]
    (dorun
     (for [y (range 9)]
       (.createRow sh y)))
    (dorun
     (for [x (range 9) y (range 9)]
       (-> (.createCell (.getRow sh y) x)
           (.setCellValue (str (* (inc x) (inc y)))))))
    (.write wb (FileOutputStream. path))))


(defn -main
  "9x9を書き込んだExcelファイルを作成->ファイルを読み込み3列目の要素を表示"
  [& args]
  (create-9x9 "test.xlsx")
  (let [wb (load-workbook "test.xlsx")
        sh (.getSheetAt wb 0)]
    (dorun 
     (for [r (rows sh)]
       (println (-> (.getCell r 2) .getStringCellValue))))))

5. 実効したりコンパイルしたり
 lein run
 lein uberjar
※ 9/22 追記
こちらのほうがシンプルそう
(defn rows [sheet]
  (keep #(.getRow sheet %)
        (range
         (.getFirstRowNum sheet)
         (inc (.getLastRowNum sheet)))))

0 件のコメント:

コメントを投稿