実現したいこと
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

バッドをするには、ログインかつ
こちらの条件を満たす必要があります。