非IT企業に勤める中年サラリーマンのIT日記

非IT企業でしかもITとは全く関係ない部署にいる中年エンジニア。唯一の趣味がプログラミングという”自称”プログラマー。

Go言語のExcel(tealeg/xlsx)パッケージはLinuxでも動いた!(但し多少修正要)

   

以前、Go言語でExcelファイルを扱えるtealeg/xlsxパッケージを紹介しました。このときはもちろんWindows上で動作させたのですが、なんとLinux(lubuntu)上でも使えることが判明しました。

 

Linux(lubuntu)上で動作確認を行ったのは以下のプログラムです。xmlからパラメータを読み込んで、そのパラメーターで指定したExcelファイルの指定条件にヒットした行を抽出して、別のExcelファイルにアウトプットするというやつです。

詳しくはこちらをご覧ください。

広告

このプログラムをLinux上でgo runしてみました。※ソースは上のリンク先にもありますがこの記事の最後にも掲載します。

その前に初期のファイル構成はこんな感じです。ExcelExtraction.goというのがソースです。conf.xmlが設定ファイルです。

 

ExcelファイルをLibreOfficeで開くとこんな感じです。全部で12万行以上のデータがあります。ファイルサイズが3.5MBと大きいファイルです。

 

パラメータ設定するXMLファイルは以下の通り。全国データから府中市を抽出するようになっています。

<?xml version="1.0" encoding="UTF-8"?>
<ResultSet>
  <List>
  <FileName>/home/ueserver/.../address.xlsx</FileName>
  <StartRow>2</StartRow>
  <SheetName>Sheet1</SheetName>
  <SearchCol>3</SearchCol>
  <SearchText>府中市</SearchText>
  <ItemIndex>1</ItemIndex>
  <OutPut>outFile.xlsx</OutPut>
  </List>
</ResultSet>
 

各パラメーターの説明はこちらです。

項目 説明
FileName 元ファイルのパス C:\…\address.xlsx
StartRow データ開始行 2
SheetName 元ファイルのシート名 Sheet1
SearchCol 検索対象の列No. 3
SearchText 検索文字 府中市
ItemIndex 項目行No. 1
OutPut 出力ファイル名 outFile.xlsx

 

で、コンソールを開いて以下のコマンドを打つと

go run ExcelExtraction.go
 

 

エラーが発生してしまいました。

 

# command-line-arguments
./ExcelExtraction.go:74: assignment count mismatch: 2 = 1
./ExcelExtraction.go:85: assignment count mismatch: 2 = 1
 

 

assignmentの数がアンマッチだって跳ねられてしまっているようです。…なぜだ!

問題の箇所は2箇所ありますが、全く同じコードのところでした。

text, _ := cell.String()
 

 

返り値として2個分キャッチしているつもりですが、どうも1個だけだと怒られているようです。Windowsだとこれでいいんだけどな…?

なので、ここを引数を1個に修正しました。下図の赤枠のところです。

 

そして、あらためてgo runしたところ、うまく動いてくれたようです!

 

outFile.xlsxというファイルが現れました。これが検索でヒットした行のみを抽出したファイルです。

 

これを開くとちゃんと抽出されていました。ちなみに「府中市」って東京の他に広島にもあります。ちゃんとヒットしてくれました。

 

ということで、Go言語のExcelを扱うパッケージ(tealeg/xlsx)はLinux上でもちゃんと使えることがわかりました。(ただし、多少修正は必要。)

最後にソースコード全文を掲載しておきます。

package main

import (
  "fmt"
  "github.com/tealeg/xlsx"
  "io/ioutil"
  "encoding/xml"
)

type List struct {
  FileName string
  StartRow int
  SheetName string
  SearchCol int
  SearchText string
  ItemIndex int
  OutPut string
}

type ResultSet struct {
  List []List
}

var conf ResultSet

func getConf(){
  data, _ := ioutil.ReadFile("conf.xml")
  err := xml.Unmarshal(data, &amp;amp;conf)
  if err != nil { panic(err) }
}

func main() {
  //パラメーターをxmlファイルから取得する
  getConf()

  fmt.Println("ファイル読み込み中...")

  //Excelファイルを開く
  excel, err1 := xlsx.OpenFile(conf.List[0].FileName)
  if err1 != nil { fmt.Printf(err1.Error()) }

   fmt.Println("指定シート検索中...")

  //指定シートを検索して変数sheetへ
  var sheet *xlsx.Sheet
  for _, s := range excel.Sheets {
    if s.Name == conf.List[0].SheetName{
      sheet = s
      break
    }
  }

  //パラメーター
  index := conf.List[0].SearchCol-1
  text := conf.List[0].SearchText
  itemIndex := conf.List[0].ItemIndex - 1
  startRow := conf.List[0].StartRow - 1

  //新しいExcelファイルを作成
  newfile := xlsx.NewFile()
  newsheet, err := newfile.AddSheet("Sheet1")
  if err != nil { fmt.Println(err.Error()) }

  fmt.Println("検索中...")

  //検索
  r := 1; cnt := 0
  for _, row := range sheet.Rows {
    //項目行を最初に追加
    if cnt==itemIndex {
      c := 0
      for _, cell := range row.Cells {
        //text, _ := cell.String()
        text := cell.String()
        newsheet.Cell(0, c).Value = text
        c++
      }
    }
    //検索ヒットした行を新ファイルに追加
    if cnt&gt;=startRow &amp;&amp; row.Cells[index].Value==text {
      c := 0
      for _, cell := range row.Cells {
        //text, _ := cell.String()
        text := cell.String()
        newsheet.Cell(r, c).Value = text
        c++
      }
      r++
    }
    cnt++
  }

  //ファイルに保存(ファイル名はパラメーターから取得)
  err = newfile.Save(conf.List[0].OutPut)
  if err != nil { fmt.Println(err.Error()) }

  fmt.Println("完了!")
}
 

 

広告

 - Go言語