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

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

Go言語でExcelファイルから特定データを抽出するアプリ作ったよ

   

Go言語でExcelファイルを処理する方法を3回に分けて紹介しました。

 

これらの機能を使って、Execlファイルから特定の条件にマッチしたものだけ抽出するプログラムを作成しました。抽出したデータは別のExcelファイルに保存するようになっています。

各パラメーターはXMLファイルで設定

すべてのパラメーターをプログラム内で設定してしまうと汎用性がなくなるので、XMLファイルにまとめています。このパラメータを変えることで色々なExcelファイルに対応できるようになっています。

<?xml version="1.0" encoding="UTF-8"?>
<ResultSet>
  <List>
  <FileName>C:\...\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

[ad#top-1]

ソースコード

ソースコードは以下の通りです。

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;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()
        newsheet.Cell(0, c).Value = text
        c++
      }
    }
    //検索ヒットした行を新ファイルに追加
    if cnt>=startRow && row.Cells[index].Value==text {
      c := 0
      for _, cell := range row.Cells {
        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("完了!")
}
 

 

検索するExcelファイル

前回同様、住所録をExcelファイルで用意しました。

 

全部で12万行以上のデータがあります。ファイルサイズが3.5MBと大きいファイルです。

実行結果

このプログラムを実行します。

go run ExcelExtraction.go
 

 

実行後、同じフォルダに指定した名前のExcelファイルが現れます。

 

こいつを開くとごらんのとおり、指定した「府中市」のみ抽出してくれています。

 

ちなみに、府中市は東京のほかに広島県にもあります。ちゃんと抽出してくれています。

 

複雑な検索条件には対応できていませんが、もともと僕自身、会社の購買データから自分が発注したデータのみを抽出したかったので、個人的にはこれで目的は達しました。自分の名前の行だけ抽出できればいいので。

複雑な検索条件(or/and, あいまい)に対応すればもっと汎用性が高まりますね。作ってみようかな…。

[ad#ad-1]

スポンサーリンク

 - Go言語