C#やVB .NETでExcelを使わずにExcelのファイルを読み込むときの定番NPOIを使用せずExcelDataReaderで文字化けなくファイルを読み込むための方法です。
とあるアプリケーションが吐き出した.xls形式のExcelファイルを扱う必要があり、NPOIを用いて読み込もうとしたとき、次のようなエラーが発生しました。
コード例とともに示します。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
Using stream = New FileStream(xlsFilePath, FileMode.Open, FileAccess.Read) Dim xlWorkbook As IWorkbook = WorkbookFactory.Create(stream) Dim xlSheet As ISheet = xlWorkbook.GetSheetAt(0) For rowIndex = 0 To 10 Dim xlRow As HSSFRow = xlSheet.GetRow(rowIndex) Console.WriteLine(xlRow.GetCell(0).StringCellValue) Next xlWorkbook.Close() End Using |
1
2
3
4
5
6
7
8
9
10
11
12
13
|
Using stream = New FileStream(xlsFilePath, FileMode.Open, FileAccess.Read) Dim xlWorkbook As XSSFWorkbook = New XSSFWorkbook(stream) Dim xlSheet As XSSFSheet = xlWorkbook.GetSheetAt(0) For rowIndex = 0 To 10 Dim xlRow As HSSFRow = xlSheet.GetRow(rowIndex) Console.WriteLine(xlRow.GetCell(0).StringCellValue) Next xlWorkbook.Close() End Using |
原因を調べていくと.xlsファイルそのものに問題があるようです。
たしかに、Excelで開いても警告が表示され、操作に制限が課されるファイルだった(編集が行えない)ので、拡張子こそ.xlsでも中身は古いExcelファイル(BIFF5形式)だったようです。
NPOIはBIFF5形式のファイルはサポートしていないので今回のプログラムではNPOIの使用をあきらめざるを得ません。
そこでNPOIと並んでよく使われているExcelDataReaderを用いてファイルを読み込むことにしました。
ExcelDataReaderを用いると、NPOIでは問題だったファイルもファイル自体は読み込むことができました。
しかし、データを細かく見ていくと日本語が格納されたセルは例外こそ発生しないものの100%文字化けが発生し、まともなデータを取り出すことができません。
インターネット上に公開されているサンプルの多くはExcelReaderFactoryクラスのCreateReaderメソッドでReaderを作成するときに、入力ストリームだけを引数として与える例が多いのですが、ここでExcelReaderConfigurationを用いてエンコーディングを指定してあげると文字化けが回避できるようです。
下記にコード例を示します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
' ExcelDataReaderを使用する際は明示的に呼び出さない例外が発生した(.NET Core 2.2) System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance) ' オプション設定でエンコーディングにシフトJISを指定 Dim config = New ExcelReaderConfiguration() config.FallbackEncoding = System.Text.Encoding.GetEncoding(932) Using stream = File.Open(xlsFilePath, FileMode.Open, FileAccess.Read) ' 引数にオプション設定をおこなう reader = ExcelReaderFactory.CreateReader(stream, config) ' データセットとして取得 Dim ds = reader.AsDataSet Dim dtbl = ds.Tables(0) For Each dr As Data.DataRow In dtbl.Rows ' なにかの処理 Console.WriteLine(dr.item(0)) Next End Using |
オプションでエンコーディングを指定できることに気が付くまでは、データを取り出したあとでコンバートできないか試してみたのですが、取り出してしまったあとではどうにもならないようです。
また、文字化けについても、どの.xlsファイルを読み込んでも100%問題を起こすわけではなく、問題を起こす.xlsファイルを読み込んだ場合は100%文字化けが起きるというのが正しい状態説明のようです。
Please give us your valuable comment