Excel 拡張子 (xls) (xlsx) 両方に対応した操作 Apache POI (2)

よくよく考えたら、
Excel 拡張子 (xls) (xlsx) 両方に対応した操作 Apache POI(1) - Oboe吹きプログラマの黙示録
は、あまり賢くない!

Closeableを実装して、Workbook のインスタンスとすべきだ。

import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.ss.SpreadsheetVersion;
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 implements Closeable{
    private Workbook book;

    public ExcelWorker(InputStream inst) throws EncryptedDocumentException, IOException {
        book = WorkbookFactory.create(inst);
    }
    public SpreadsheetVersion getSpreadsheetVersion() {
        return book.getSpreadsheetVersion();
    }
    public Workbook getWorkbook() {
        return book;
    }
    public void readFirstSheet(Consumer<Row> action) {
        Sheet sheet = book.getSheetAt(0);
        IntStream.rangeClosed(0, sheet.getLastRowNum()).mapToObj(n->sheet.getRow(n)).forEach(row->action.accept(row));
    }
    public void readFirstSheet(Predicate<Row> pre, Consumer<Row> action) {
        Sheet sheet = book.getSheetAt(0);
        IntStream.rangeClosed(0, sheet.getLastRowNum()).mapToObj(n->sheet.getRow(n)).filter(pre).forEach(row->action.accept(row));
    }
    public Stream<Sheet> getSheets(){
        return IntStream.range(0, book.getNumberOfSheets()).mapToObj(n->book.getSheetAt(n));
    }
    public void getSheets(Consumer<Sheet> action){
        IntStream.range(0, book.getNumberOfSheets()).mapToObj(n->book.getSheetAt(n)).forEach(action);
    }
    public static Stream<Row> getRowStream(Sheet sheet) {
        return IntStream.rangeClosed(0, sheet.getLastRowNum()).mapToObj(n->sheet.getRow(n));
    }
    public static Stream<Cell> getCellStream(Row row){
        return IntStream.range(0, row.getLastCellNum()).mapToObj(n->row.getCell(n));
    }
    public static Stream<Sheet> createAndSheets(Workbook book, int size) {
        book.createSheet();
        for(int n=1; n < size;n++) {
            book.cloneSheet(0);
        }
        return StreamSupport.stream(Spliterators.spliteratorUnknownSize(book.sheetIterator(), Spliterator.ORDERED), false);
    }
    public static Stream<Sheet> createAndSheets(Workbook book, String...names) {
        book.createSheet(names[0]);
        for(int n=1; n < names.length;n++) {
            book.createSheet(names[n]);
        }
        return StreamSupport.stream(Spliterators.spliteratorUnknownSize(book.sheetIterator(), Spliterator.ORDERED), false);
    }
    @Override
    public void close() throws IOException{
        book.close();
    }
}

こうすれば、、ちょっと乱暴な書き方だけど、、

String filename = "sample2.xlsx";

File file = new File(Thread.currentThread().getContextClassLoader().getResource("./"+filename).getPath());
try(InputStream inst = new FileInputStream(file); ExcelWorker worker = new ExcelWorker(inst);
    OutputStream outst = new FileOutputStream("out/test2"
    + (worker.getSpreadsheetVersion().equals(SpreadsheetVersion.EXCEL2007) ? ".xlsx" : ".xls" ))
){
    worker.getSheets().forEach(sheet->{
        ExcelWorker.getRowStream(sheet).forEach(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)) {
                }else if(cell.getCellType().equals(CellType.BLANK)) {
                }
                row.createCell(5).setCellValue("Test!");
                });
            });
        });
        worker.getWorkbook().write(outst);
    }catch(IOException e){
        e.printStackTrace();
    }
}