SXSSFWorkbookの不具合 #apachePoi

qiita.com

知らなかったので再現プログラムを書いてみた。

import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
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.xssf.streaming.SXSSFWorkbook;

public class WriteTest {

    public static void main(String[] args) {

        String outputFilePath = "out.xlsx";
        Workbook book = null;
        FileOutputStream fout = null;

        try {
            book = new SXSSFWorkbook();

            Font font = book.createFont();
            font.setFontName("MS ゴシック");
            font.setFontHeightInPoints((short) 9);

            CellStyle style = book.createCellStyle();
            style.setWrapText(true);

            Sheet sheet = book.createSheet();

            Row row = sheet.createRow(0);
            Cell cell0 = row.createCell(0);
            cell0.setCellValue("aaa\r\nbbb");
            cell0.setCellStyle(style);

            Cell cell1 = row.createCell(1);
            cell1.setCellValue("aaa\rbbb");
            cell1.setCellStyle(style);

            Cell cell2 = row.createCell(2);
            cell2.setCellValue("aaa\nbbb");
            cell2.setCellStyle(style);

            Cell cell3 = row.createCell(3);
            cell3.setCellValue("aaa\\nbbb");
            cell3.setCellStyle(style);
            
            fout = new FileOutputStream(outputFilePath);
            book.write(fout);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                book.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

処理結果はこうなり、A1セルの改行が2回行われていることが確認出来る。

f:id:su_zu_ki_1010:20170818100746p:plain

原因となるコードはpoi-ooxml-3.xx.jarの org.apache.poi.xssf.streaming.SheetDataWriter.javaの371行目から379行目の部分。 ※3.17-beta1でも直っていないことを確認した。

// Special characters
case '\n':
case '\r':
    if (counter > last) {
        _out.write(chars, last, counter - last);
    }
    _out.write("
");
    last = counter + 1;
    break;

#xa;はxml文書で改行コードを表すらしい。

www.4d.com

当面の対応は、\r\nを\r、あるいは\nに置換するしかなさそうだけど、本対応はapacheにバグレポートを書くことだろうなぁ。 githubだったらissueに書けばいいんだろうけど、apache poiはsubversionで活動されているので報告先がわからない…。

というか、SXSSFWorkbookってあまり使われていないのかな。