1. tebakane

    Posted

    tebakane
Changes in title
+Go言語でExcel操作ライブラリを書いてみた
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,88 @@
+この記事は[Go (その3) Advent Calendar 2016](http://qiita.com/advent-calendar/2016/go3) 13日目の記事です。
+# Go言語でExcel操作ライブラリを書いてみた
+
+[excl](https://github.com/loadoff/excl) ライブラリ
+
+## なぜそんなもの書いたのか
+
+Go言語にはExcel作成用のライブラリ [xlsx](https://github.com/tealeg/xlsx) がすでに存在します。
+xlsxライブラリは強力で、普通に使用する場合このライブラリが一番だと思います。
+ただ、xlsxライブラリを調査していると今回作成するものの仕様に耐えられない部分がありました。
+
+### xlsxライブラリの利点欠点
+
+#### xlsxライブラリにできること
+・Excelファイルの書き込み・読み込み・新規作成
+・セルの書式設定
+・Excelファイルを解凍せずに扱える
+・OpenXMLの仕様に基づいた開発
+
+#### xlsxライブラリの問題
+・既存のExcelファイルを使用するといろいろなものが消える
+ ・チャートが消える
+ ・画像が消える
+ ・図形が消える
+・マクロの存在するファイルの場合はマクロも消える
+・メモリ使用量が異常に高くなる
+ ・数十メガバイトのデータでも使用メモリがギガを超える
+
+## exclライブラリってなに?
+
+既存のExcelファイルにデータを追加することを目的に作成されたライブラリ
+可能な限りメモリに持たずにファイルに書き出す
+
+### 使い方
+
+```go:main.go
+import(
+ "github.com/loadoff/excl"
+)
+
+func main(){
+ // 読み込みExcelファイル、展開先、新規書き込み先を指定
+ w, _ := excl.NewWorkbook("path/to/read.xlsx", "path/to/expand", "path/to/write.xlsx")
+ // Execlブックを開く
+ w.Open()
+ // シートを開く
+ s, _ := w.OpenSheet("sheet1")
+ // 一行目を取得
+ r := s.GetRow(1)
+ // 1列目のセルを取得
+ c := r.GetCell(1)
+ // セルに10を出力
+ c.SetNumber("10")
+
+ // 2列目のセルにABCDEという文字列を出力
+ c = r.SetString("ABCDE", 2)
+
+ s.Close()
+ w.Close()
+)
+```
+
+### exclライブラリの特徴
+
+・既存のExcelファイルを使用する
+ ・もとの設定は消えないことを前提に開発を行った
+・メモリ使用を抑える
+・マクロファイルも使用できる
+
+### 問題点
+
+・新規作成(空のExcelファイルを用意する必要がある)
+・Excelファイルが展開される
+
+### TODO
+
+・セルの書式を自由に設定する
+・英語化
+
+## 結論
+新規にExcelファイルを作成し、データ量が多くない場合は [xlsx](https://github.com/tealeg/xlsx) ライブラリを使用するべきですが、テンプレート用のExcelファイルが存在する場合は[今回作成したライブラリ](https://github.com/loadoff/excl)が有用かと思います。
+
+今更OpenXMLの仕様についてかなり調べましたが、OpenXMLは複雑だがよくできているなと感じました。
+また、Go言語のxmlライブラリを使用してxmlns属性が存在するファイルをいじると
+予想していない動作をします。
+xmlns:_xmlns="xmlns" みたいな形になってしまい、まったく同じファイルを出力しなおすのに手間取りました。
+[ここらへん](https://github.com/golang/go/issues/13400)で議論されていますが、1.8か1.9で修正予定みたいです。
+[参考](https://play.golang.org/p/rxXydio31M)