久々に、Apache POI に触れます。
Excel 2003 の形式、拡張子 .xls
Excel 2007 からの形式、拡張子 .xlsx
両方に対応するには、
org.apache.poi.ss.usermodel.* にある
WorkbookFactory で、Workbook を取得して
Workbook book = WorkbookFactory.create(inputstream);
org.apache.poi.ss.usermodel.Workbook
org.apache.poi.ss.usermodel.WorkbookFactory
org.apache.poi.ss.usermodel.Cell
org.apache.poi.ss.usermodel.Row
org.apache.poi.ss.usermodel.Sheet
これらを使うんですね。
Stream 処理するように、作業用クラスを用意しておけば充分です。
と、以下に書いたのだけれど、、、
import java.io.InputStream; import java.io.OutputStream; import java.util.function.Consumer; import java.util.function.Predicate; import java.util.stream.IntStream; import java.util.stream.Stream; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.WorkbookFactory; /** * ExcelWorker */ public class ExcelWorker{ private InputStream inst; public ExcelWorker(InputStream inst) { this.inst = inst; } public void readOneSheet(Consumer<Row> action) { try(Workbook book = WorkbookFactory.create(inst)){ Sheet sheet = book.getSheetAt(0); IntStream.rangeClosed(0, sheet.getLastRowNum()).mapToObj(n->sheet.getRow(n)).forEach(row->action.accept(row)); }catch(Exception ex){ throw new RuntimeException(ex); } } public void readOneSheet(Predicate<Row> pre, Consumer<Row> action) { try(Workbook book = WorkbookFactory.create(inst)){ Sheet sheet = book.getSheetAt(0); IntStream.rangeClosed(0, sheet.getLastRowNum()).mapToObj(n->sheet.getRow(n)).filter(pre).forEach(row->action.accept(row)); }catch(Exception ex){ throw new RuntimeException(ex); } } public static Stream<Cell> getCellStream(Row row){ return IntStream.range(0, row.getLastCellNum()).mapToObj(n->row.getCell(n)); } public void writeOneSheet(OutputStream outst, Consumer<Row> action) { try(Workbook book = WorkbookFactory.create(inst)){ Sheet sheet = book.getSheetAt(0); IntStream.rangeClosed(0, sheet.getLastRowNum()).mapToObj(n->sheet.getRow(n)).forEach(row->action.accept(row)); book.write(outst); outst.flush(); }catch(Exception ex){ throw new RuntimeException(ex); } } public void writeOneSheet(OutputStream outst, Predicate<Row> pre, Consumer<Row> action) { try(Workbook book = WorkbookFactory.create(inst)){ Sheet sheet = book.getSheetAt(0); IntStream.rangeClosed(0, sheet.getLastRowNum()).mapToObj(n->sheet.getRow(n)).filter(pre).forEach(row->action.accept(row)); book.write(outst); outst.flush(); }catch(Exception ex){ throw new RuntimeException(ex); } } }
使用サンプルは、、、
File file = new File(Thread.currentThread().getContextClassLoader().getResource("./"+filename).getPath()); try(InputStream inst = new FileInputStream(file)){ ExcelWorker worker = new ExcelWorker(inst); worker.readOneSheet(row->{ System.out.println("--- getRowNum() = " + row.getRowNum()); ExcelWorker.getCellStream(row).forEach(cell->{ System.out.print(" ["+cell.getColumnIndex()+"]="); if (cell.getCellType().equals(CellType.STRING)) { // 文字列 System.out.print(cell.getStringCellValue()); }else if(cell.getCellType().equals(CellType.NUMERIC)) { if (DateUtil.isCellDateFormatted(cell)){ // 日付 or 時刻 //LocalDate date = cell.getDateCellValue().toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); //System.out.print(date); LocalDateTime datetime = cell.getDateCellValue().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); System.out.print(datetime); }else{ // 数値 double d = cell.getNumericCellValue(); System.out.print(d); } }else if(cell.getCellType().equals(CellType.BOOLEAN)) { // TODO Boolean }else if(cell.getCellType().equals(CellType.BLANK)) { // TODO blank } }); System.out.print("\n"); }); }catch(IOException e){ e.printStackTrace(); }
===========================================
POI のバージョンも、上がってました。。。
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>5.1.0</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.1.0</version> </dependency>
poi-ooxml は、対象が xlsx であれば実行時に必要です。