none
C#でDB上のエクセルをストリーム化してBookを作成しようとすると例外が発生する。 RRS feed

  • 質問

  • お世話になります。

    DB上にエクセルファイルがあり、ストリームに変換し、Bookを作成したいのですが、例外System.IndexOutOfRangeExceptionが発生してしまいます。エクセルファイル(Office2013)は単純な1シートであり、NPOIは最新版を使用しています。

    ソースコードは、以下です。例外は、最終行で発生します。

    どなたか、解決方法をご存知の方、お教えください。

               //ブック読み込み(テンプレート)
                _logger.LogInformation(LoggingEvents.AppLog, "START of Template restore.");
                var excelTemplate = new ExcelReport(_db, _logger) { TemplateId = FdId.FD1210 };
                _logger.LogInformation(LoggingEvents.AppLog, "End of Template restore.");
    
                byte[] buffer = excelTemplate.GetExcelTemplate();
                _logger.LogInformation(LoggingEvents.AppLog, "End of Template restore(2).");
                MemoryStream stream = new MemoryStream(buffer);
                _logger.LogInformation(LoggingEvents.AppLog, "End of Template restore(3).");
                //IWorkbook book = WorkbookFactory.Create(stream);
                XSSFWorkbook book = new XSSFWorkbook(stream);
    

    2018年12月20日 11:04

回答

  • ご提示いただいたソースでは、Excel データは byte[] buffer 上に取り込まれているのですよね。

    一度、オンメモリの byte[] に展開されている以上、その元データの所在がファイルであるか DB 上にあるかは、特に影響しないものと思います。

    なので、buffer に取り出した Excel データそのものが既に破損しているか、あるいは NPOI 側の不具合の可能性が疑われます。別の Excel データで試してみるとか、あるいは、NPOI 以外のライブラリで読めるかなどを追検証してみては如何でしょう。

    なお当方環境では、NPOI 2.4.1 にて下記のコードが動作することを確認しました。

    byte[] buffer = System.IO.File.ReadAllBytes(@"D:\test.xlsx");
    System.IO.MemoryStream ms;
                
    ms = new System.IO.MemoryStream((byte[])buffer.Clone());
    var book1 = NPOI.SS.UserModel.WorkbookFactory.Create(ms);
    book1.Close();
    
    ms = new System.IO.MemoryStream((byte[])buffer.Clone());
    var book2 = new NPOI.XSSF.UserModel.XSSFWorkbook(ms);
    book2.Close();
    
    ms = new System.IO.MemoryStream((byte[])buffer.Clone());
    var book3 = new NPOI.HSSF.UserModel.HSSFWorkbook(ms);
    book3.Close();
    

    • 回答としてマーク MitsuoTAKEI 2018年12月21日 7:49
    2018年12月21日 6:21

すべての返信

  • ご提示いただいたソースでは、Excel データは byte[] buffer 上に取り込まれているのですよね。

    一度、オンメモリの byte[] に展開されている以上、その元データの所在がファイルであるか DB 上にあるかは、特に影響しないものと思います。

    なので、buffer に取り出した Excel データそのものが既に破損しているか、あるいは NPOI 側の不具合の可能性が疑われます。別の Excel データで試してみるとか、あるいは、NPOI 以外のライブラリで読めるかなどを追検証してみては如何でしょう。

    なお当方環境では、NPOI 2.4.1 にて下記のコードが動作することを確認しました。

    byte[] buffer = System.IO.File.ReadAllBytes(@"D:\test.xlsx");
    System.IO.MemoryStream ms;
                
    ms = new System.IO.MemoryStream((byte[])buffer.Clone());
    var book1 = NPOI.SS.UserModel.WorkbookFactory.Create(ms);
    book1.Close();
    
    ms = new System.IO.MemoryStream((byte[])buffer.Clone());
    var book2 = new NPOI.XSSF.UserModel.XSSFWorkbook(ms);
    book2.Close();
    
    ms = new System.IO.MemoryStream((byte[])buffer.Clone());
    var book3 = new NPOI.HSSF.UserModel.HSSFWorkbook(ms);
    book3.Close();
    

    • 回答としてマーク MitsuoTAKEI 2018年12月21日 7:49
    2018年12月21日 6:21
  • ご回答ありがとうございました。

    MySQLのレコードから、エクセルファイル(テンプレート)をByte[]に読み込みます。

    原因がわかりました。テンプレートが正しくなく、ブランクのシートのエクセルファイルが、

    誤ってDBに反映されており、正しく登録し直したところ、うまく動きました。

    例外処理を実装する必要がありそうです。

    2018年12月21日 8:00