0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Android+kotlinでPOIを使ってExcelのデータを読み取る

Last updated at Posted at 2022-12-17

AndroidでExcelのデータを読み取る

JavaでExcelやWord等のOfficeのフォーマットを扱うライブラリにはPOIがあります。Android+kotlinでも同様にPOIが使えます

何に使うの?使いみちは?

何で、今更AndroidでPOIを使ってExcelを読み込む必要がある?と思うかもしれません。google spredsheetあるんじゃない?と思うかもしれません。
Androidには色々なデバイスが付いていますが、そのデバイスがエミュレータには付いていない場合があります。Android端末実機ではなくて、エミュレータで試験する場合、そのデバイスの部分をMock化して、そのでデバイスがプロクラムに渡すデータを、デバックデータとしてExcelで定義するのに使えます。

今、私が開発しているアプリは専用のバーコードカメラの付いたAndroid端末で、バーコードを読み取るアプリを開発しています。このバーコードカメラはエミュレータにはありません。そうなると、エミュレータではデバックどころか全く動かすことができません。

実際にやってみる

ライブラリの依存関係

build.gradleに依存関係を追加します

build.gradle
dependencies {
    (中略)
    implementation 'org.apache.poi:poi:5.2.3'
    implementation 'org.apache.poi:poi-ooxml:5.2.3'
}

POIのバージョンが古いとPOIの依存関係であるxmlbeansのXMLパーサの問題でエラーになります。これが解決されたのが2022年の2月くらいなので、できるだけ最新のバージョンを使います。

(中略)
 Caused by: org.apache.xmlbeans.XmlException: error: The 'namespace-prefix' feature is not supported while the 'namespaces' feature is enabled.
    at org.apache.xmlbeans.impl.store.Locale$SaxLoader.load(Locale.java:2550)
    at org.apache.xmlbeans.impl.store.Locale.lambda$parseToXmlObject$3(Locale.java:715)
    at org.apache.xmlbeans.impl.store.Locale$$ExternalSyntheticLambda7.parse(Unknown Source:6)
    at org.apache.xmlbeans.impl.store.Locale.syncWrap(Locale.java:488)
    at org.apache.xmlbeans.impl.store.Locale.parseToXmlObject(Locale.java:714)
    at org.apache.xmlbeans.impl.schema.SchemaTypeLoaderBase.parse(SchemaTypeLoaderBase.java:233)
    at org.apache.xmlbeans.impl.schema.AbstractDocumentFactory.parse(AbstractDocumentFactory.java:71)
    at org.apache.poi.xssf.model.ThemesTable.<init>(ThemesTable.java:86)
    at org.apache.poi.xssf.usermodel.XSSFRelation$$ExternalSyntheticLambda13.init(Unknown Source:2) 
(中略)

MainActivity

MainActivity.kt
class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater).apply {
            setContentView(this.root)
        }
        val xlsx = File(applicationContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "sample.xlsx")
        Log.d("", xlsx.absolutePath)
        val str = buildString {
            WorkbookFactory.create(xlsx).use { wb ->
                val sheet = wb.getSheet("Sheet1")
                for (r in 0..sheet.lastRowNum) {
                    val row = sheet.getRow(r)
                    for (c in 0..row.lastCellNum -1) {
                        append(row.getCell(c))
                        append(" ")
                    }
                    append("\r\n")
                }
            }
        }
        binding.excelText.text = str
    }
}

Excelデータ

適当にsample.xlsxというファイル名でデータを作ります。
excel.png

ExcelをAndroid端末に転送してやる

このExcelファイルをAndroidStudioのDeviceFileExploerで転送してやります。
物理パスは私がAndroidエミュレータで試した限りでは、以下のようになりましたが、エミュレータの仮想イメージ、実機の機種によって微妙に異なる場合があります。

/storage/emulated/0/Android/data/com.example.poi/files/Download/sample.xlsx

実行してみる

こんな風に表示されます。
Screenshot_20221217_201010.png

POIはJavaで開発していたときもJUnitで単体試験をするときに単体テストフレームワークに組み込んでよく使っていました。テキストよりも、複数シート持てるし、色々な表現ができるので便利です。

最後に

完成版はgitHubに置きました

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?