聞こえないJavaエンジニアが適当に書き連ねていく

つらつらとメモしたり日頃の溜まっている想いを吐き出す場所です。

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ってあまり使われていないのかな。