サーバーサイドでEXCELを読み込む(NPOI、EPPlus、Koogra)

前回「サーバーサイドでEXCELを読み込む(NPOI、EPPlus)」の続き。


Koogra というライブラリを紹介してもらった。


改めて整理すると。

名称 OpenXML バージョン リリース日 ライセンス
NPOI × 1.2.5 2012/5/4 Apache License 2.0
EPPlus 3.0.0.2 2012/1/31 LGPL
Koogra 3.1.5 2010/3/24 MIT License


参照設定は、NPOIはNPOI.dllを、EPPlusはEPPlus.dllを設定したんだけど、KoograはNet.SourceForge.Koogra.dllとIonic.Utils.Zip.dllの2つの設定が必要だった。


中身は同じの*.xlsと*.xlsxを用意して、読み込んでみる。
表は一部歯抜けにした状態で、一つだけ書式を"日付"にしたセルを用意した。
出来るだけ同じ出力結果となるように、一部空文字を入れたりしている。

Imports NPOI.HSSF.UserModel
Imports Net.SourceForge.Koogra
Imports OfficeOpenXml
Imports System.IO
Imports System.Text

Module Module1

    Sub Main()
        Dim xlsxPath = "C:\Book1.xlsx"
        Dim xlsPath = "C:\Book1.xls"

        EPPlus(xlsxPath)

        NPOI(xlsPath)

        Koogra(xlsxPath)
        Koogra(xlsPath)

    End Sub

    Private Sub EPPlus(path As String)

        Dim str = New List(Of String)
        Using package As New ExcelPackage(New FileInfo(path))
            Dim sheet = package.Workbook.Worksheets(1)
            For i = 1 To sheet.Dimension.End.Row
                str.Add("--- " & i & "行目")
                For j = 1 To sheet.Dimension.End.Column
                    If IsDate(sheet.Cells(i, j).Value) Then
                        str.Add(CDate(sheet.Cells(i, j).Value).ToString("yyyy/MM/dd"))
                    Else
                        If IsNothing(sheet.Cells(i, j).Value) = False Then
                            str.Add(sheet.Cells(i, j).Value.ToString)
                        Else
                            str.Add("")
                        End If
                    End If
                Next
            Next
        End Using

        Using sw As New StreamWriter("C:\EPPlus.txt", False, Encoding.Default)
            For Each s In str
                sw.WriteLine(s)
            Next
        End Using
    End Sub

    Private Sub NPOI(path As String)

        Dim str = New List(Of String)
        Using fs As New FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)
            Dim sheet = DirectCast(New HSSFWorkbook(fs).GetSheetAt(0), HSSFSheet)

            For i = 0 To sheet.LastRowNum
                str.Add("--- " & i + 1 & "行目")
                Dim row = DirectCast(sheet.GetRow(i), HSSFRow)
                For Each cell In row.Cells
                    If cell.CellStyle.DataFormat = 14 AndAlso cell.ToString <> "" Then
                        str.Add(cell.DateCellValue.ToString("yyyy/MM/dd"))
                    Else
                        str.Add(cell.ToString)
                    End If
                Next
            Next
        End Using

        Using sw As New StreamWriter("C:\NPOI.txt", False, Encoding.Default)
            For Each s In str
                sw.WriteLine(s)
            Next
        End Using
    End Sub

    Private Sub Koogra(path As String)

        Dim str = New List(Of String)
        If path.EndsWith("xlsx") Then
            Dim ws = New Excel2007.Workbook(path).GetWorksheet(0)
            For i = ws.CellMap.FirstRow To ws.CellMap.LastRow
                str.Add("--- " & i + 1 & "行目")
                Dim row = ws.GetRow(i)
                For j = ws.CellMap.FirstCol To ws.CellMap.LastCol
                    If IsNothing(row.GetCell(j).Value) = False Then
                        str.Add(row.GetCell(j).Value.ToString)
                    Else
                        str.Add("")
                    End If
                Next
            Next

            Using sw As New StreamWriter("C:\KoograX.txt", False, Encoding.Default)
                For Each s In str
                    sw.WriteLine(s)
                Next
            End Using
        Else
            Dim ws = New Excel.Workbook(path).Sheets(0)
            For i = ws.Rows.MinRow To ws.Rows.MaxRow
                str.Add("--- " & i + 1 & "行目")
                Dim row = ws.Rows(i)
                For j = row.Cells.MinCol To row.Cells.MaxCol
                    If IsNothing(row.Cells(j)) = False Then
                        If IsNothing(row.Cells(j).Value) = False Then
                            If row.Cells(j).Style.Format.FormatValue = "M/D/YY" Then
                                str.Add(Date.FromOADate(CDbl(row.Cells(j).Value)).ToString("yyyy/MM/dd"))
                            Else
                                str.Add(row.Cells(j).Value.ToString)
                            End If
                        Else
                            str.Add("")
                        End If
                    End If
                Next
            Next

            Using sw As New StreamWriter("C:\Koogra.txt", False, Encoding.Default)
                For Each s In str
                    sw.WriteLine(s)
                Next
            End Using
        End If
    End Sub

End Module


これでも出力は完全には一致しなかった。


例えば、行の最後に空セルとかがあると、Koogra の row.Cells.MaxCol は行ごとに値が変わる。
今回は、空セルも含めて表のイメージのまま抜き出したいので、実現するにはもう少しコードで対応しないといけない。
あと、どうもKoograのExcel2007.Workbookで読み込んだときは、セルの書式が取れない。(該当しそうなプロパティが存在しない。)


見落としているのかな。