2019年6月21日金曜日

Excel-grep

 まぁ、やはり一番、よく使うのはgrepなわけですよ。
 テキストファイルならそれでいいんだけど、Excelファイルががっつりあったりすると泣けてくる。
 Windowsのエクスプローラーから検索できるんだけど、なんか使い方がよくわからないのでストレス。だったらjavaのPOIでExcelの中身を見れるんだから——ABCLで取りこめばいいんじゃね?
 で、つくってみる。

(in-package :cl-user)
(defpackage Excel
(:use :cl :java))
(in-package :Excel)
(add-to-classpath (UIOP/FILESYSTEM:DIRECTORY-FILES #P"POIのはいっているフォルダ")
(defun workbook(file)
"workbookをget"
(let ((in (jinput-stream file)))
(java:jstatic "create"
"org.apache.poi.ss.usermodel.WorkbookFactory"
in)))
(defun sheet(workbook)
(loop repeat (jcall "getNumberOfSheets" workbook)
for x from 0
collect (jcall "getSheetAt" workbook x)))
(defun row(sheet)
(cond ((listp sheet)(mapcar #'row sheet))
(t (loop for x from 0 to (jcall "getLastRowNum" sheet)
collect (jcall "getRow" sheet x)))))
(defun cell(row)
(when row
(cond ((listp row)(mapcar #'cell row))
(t (loop for x from 0 to (jcall "getLastCellNum" row)
collect (jcall "getCell" row x))))))
(defun value(cell)
(when cell
(cond ((listp cell)(mapcar #'value cell))
(t (case (jcall "getCellType" cell)
(0 (jcall "getNumericCellValue" cell))
(1 (jcall "getStringCellValue" cell)))))))
(defun get(file)
(value (cell (row (sheet (workbook file))))))
view raw Excel.lisp hosted with ❤ by GitHub

 あとはslime経由でEmacsにデータを取りこんでごにょごにょする、と。

(defun y-excel(file)
"Excelの値をlistで取得する。"
(slime-eval `(Excel::get ,(expand-file-name file))))
view raw excel.el hosted with ❤ by GitHub

 ちょっと「jinput-stream」をcloseしてないのが気になるけど、ま、いいか。