質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

servlet

Servletとは、Webページの動的な生成やデータ処理などをサーバ上で実行するために、Javaで作成されたプログラムです。 ショッピングサイトやオンラインバンキングといった、動的なウェブサイトの構築に用いられています。

Q&A

2回答

1309閲覧

Apache poi での空白セルの読込について教えてください。

magmag123

総合スコア15

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

servlet

Servletとは、Webページの動的な生成やデータ処理などをサーバ上で実行するために、Javaで作成されたプログラムです。 ショッピングサイトやオンラインバンキングといった、動的なウェブサイトの構築に用いられています。

0グッド

0クリップ

投稿2023/10/04 10:35

実現したいこと

Apache poi でエクセルファイルを読み込んで配列に格納し、
その配列を二次元配列に格納していく処理について作成しています。

前提

Apache poiでエクセルファイルを読み込んでそれぞれのセルの値を取得し、配列に格納してから二次元配列に格納することはできたのですが、「空白のセル」が飛ばされることに気づきました。

参考にしたサイトによれば、Sheet.getRowやRow.getCellを使用すれば値を「空白のセル」も取得することが
できると記載していたので、導入してみたのですが、「java.lang.NullPointerException:」が発生してしまい、うまく動作することができません。

一応、「java.lang.NullPointerException:」が発生したということは空白セルは飛ばされなくなったと思うのですが、配列に格納することができません。

配列に格納するには何か別の処理が必要なのでしょうか?

どなたかお力添え頂けないでしょうか

発生している問題・エラーメッセージ

java.lang.NullPointerException: Cannot invoke "org.apache.poi.ss.usermodel.Cell.getCellType()" because "cell" is null
at controller.DateChangeController.doPost(DateChangeController.java:249)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:555)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:209)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:481)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:673)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:926)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1791)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:833)

エラーメッセージ

該当のソースコード

xlsxData[] : セルの情報を格納していく配列。
csvData :xlsxData配列を格納していく二次元配列。

Servlet

1List<String[]> csvData = new ArrayList<>(); 2 3 final String FILE_DIR = "C:/pleiades/workspace/DataConvertSystem/src/main/WebContent/xlsx/"; 4 DataFormatter formatter = new DataFormatter(); 5 List<String> filePathList = ExelFileRead.getFilePathList(FILE_DIR); 6 for (String filePath : filePathList) { 7 //Excelを開く 8 File file = new File(filePath); 9 Workbook workbook; 10 // シートの全列をループで表示する処理 11 try { 12 workbook = WorkbookFactory.create(new FileInputStream(file)); 13 //シート1枚目を開く 14 Sheet sheet = workbook.getSheetAt(0); 15 // ヘッダ行だけの二次元配列を作成 16 // ヘッダ行のみ取得 17 Row rowhead = sheet.getRow(0); 18 System.out.println("★:" + rowhead.getLastCellNum()); 19 int element = rowhead.getLastCellNum(); 20 // セル情報格納用の配列を作成 21 //String[] xlsxData = new String[element]; 22 // すべての行のセルを確認しに行っている。 23 int loopcnt=0; 24 String formatcell; 25 for (int i = 0; i <= sheet.getLastRowNum(); i++) { 26 Row row = sheet.getRow(i); 27 String[] xlsxData = new String[element]; 28 int len = (row == null) ? 0 : row.getLastCellNum(); 29 for (int j = 0; j < len; j++) { 30 31 Cell cell = row.getCell(j); 32 //セルの型を判定する 33 CellType cType = cell.getCellType(); 34 switch(cType) { 35 case STRING: 36 // 文字型 37 System.out.println("文字型です。"); 38 System.out.println(cell.getStringCellValue() + "\t"); 39 xlsxData[loopcnt] = cell.getStringCellValue(); 40 break; 41 case NUMERIC: 42 // 数値型、日付型 ※日付もNUMERICと判定されます 43 // 小数点の判定が必要 44 System.out.println("数値型です。"); 45 formatcell = formatter.formatCellValue(cell); 46 System.out.println("文字列変換:" + formatcell); 47 xlsxData[loopcnt] = formatcell; 48 //xlsxData.add(cell.getNumericCellValue()); 49 break; 50 case FORMULA: 51 // Excel関数型 ※例)NOW()、SUM()などのExcelの関数 52 System.out.println("関数です。"); 53 break; 54 case BOOLEAN: 55 // 真偽型 ※例)TRUE、FALSE 56 System.out.println("真偽型です。"); 57 break; 58 case BLANK: 59 //空 ※セルに値がセットされていない場合の型です 60 System.out.println("空です。"); 61 formatcell = formatter.formatCellValue(cell); 62 xlsxData[loopcnt] = formatcell; 63 break; 64 default: 65 break; 66 } 67 loopcnt ++; 68 } 69 csvData.add(xlsxData); 70 loopcnt=0; 71 72 } 73 } catch (EncryptedDocumentException | IOException e) { 74 // TODO 自動生成された catch ブロック 75 e.printStackTrace(); 76 } 77 }

試したこと

参考サイトをもとに修正してみたのですがうまく動作させることができませんでした。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。
参考にしたサイト
https://qiita.com/neko_the_shadow/items/8982cc5102421952a999

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

配列に格納するには何か別の処理が必要なのでしょうか

配列に格納するには…では無くて、そもそも「セルが空」という状態が POI の getCell の結果としてどう表現されているか、ということでしょう。
セルの罫線の中になんの文字が見えなくても、例えば String 型の列で空文字("")であることと 整数型で 0 が入っているのをフォーマットで見えなくしているのとでは、内部的には全く違います。その一つとして「未定義(なんの情報も無い)セル」を getCell すると null が返されることはあり得る話です。(「未定義セル」を null という形で得られている、とも言えます。)
そして getCell で null が得られた時にどうするか、配列には何を入れるのか(/入れないのか)は、お作りになっているプログラムの仕様次第です。
参考にされた先のコードでは、

java

1Cell cell = row.getCell(j); 2list.add((cell == null) ? "" : cell.getStringCellValue());

getCell が null を返した場合は空文字列 "" を入れていますね。

投稿2023/10/04 16:33

編集2023/10/04 17:35
jimbe

総合スコア12756

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

java

1Cell cell = row.getCell(j); 2//セルの型を判定する 3CellType cType = cell.getCellType();

row.getCell(j)の戻り値がnullになる場合があります。そのため、変数cellがnullになり、cell.getCellType()がNPEを起こしているものと思われます。

解決策はいろいろありますが、「getCellTypeを呼び出す前にcellがnullかどうか判定して、nullの場合は以降の処理を行わない」というのがもっとも簡単だとおもいます。

java

1Cell cell = row.getCell(j); 2if (cell == null) { 3 loopcnt++; 4 continue; 5} 6 7//セルの型を判定する 8CellType cType = cell.getCellType();

投稿2023/10/04 15:13

編集2023/10/04 15:15
neko_the_shadow

総合スコア2273

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問