8. 固定長のカラムの読み書き

固定長のカラムは、書き込み時は任意の長さになるよう空白などを詰め、読み込み時は書き込み時に詰めた空白などの文字を除去するとで実現しています。[v2.1+]

固定長のカラムを定義したい場合は、フィールドにアノテーション @CsvFixedSize [ JavaDoc ] を付与します。

このアノテーションは、 以下の変換用のアノテーションを合成したアノテーションになります。

  • 書き込み時は、パディングするアノテーション @CsvMultiPad [ JavaDoc ]。

  • 読み込み時は、トリムするアノテーション @CsvOneSideTrim [ JavaDoc ]。

8.1. 基本的な設定

@CsvFixedSize の属性を指定することで、細やかな設定ができます。

  • 属性 size にて、固定長のサイズを指定します。

  • 属性 rightAlign で右寄せするかどうか指定します。

    • true のとき右寄せとなります。書き込み時に左側にパディング文字を詰め、読み見込み時に左側の文字をトリミングします。

    • false のとき左寄席で、デフォルト値となります。書き込み時に右側にパディング文字を詰め、読み見込み時に右側の文字をトリミングします。

  • 属性 padChar で、パディングする文字を指定することができます。

    • デフォルトは半角空白です。

    • 値には、半角以外の全角文字の指定可能です。

  • 属性 chopped で、書き込み時に指定したサイズを超えている場合、切り出すか指定します。

    • デフォルトは true で切り出しません。

コード - 8.1.1 Beanの定義例
 1import com.github.mygreen.supercsv.annotation.CsvBean;
 2import com.github.mygreen.supercsv.annotation.CsvColumn;
 3import com.github.mygreen.supercsv.annotation.CsvFixedSize;
 4
 5
 6@CsvBean
 7public class SampleCsv {
 8
 9    // 右詰めする
10    @CsvColumn(number=1)
11    @CsvFixedSize(size=10, rightAlign=true)
12    private int id;
13
14    // パディング文字を全角空白にする。
15    // 全角を入力する前提としたカラムと想定し、さらに @CsvFullChar で半角を全角に変換します。
16    @CsvColumn(number=2, label="氏名")
17    @CsvFixedSize(size=20, padChar=' ')
18    @CsvFullChar
19    private String name;
20
21    // パディング文字をアンダースコア(_)にする。
22    @CsvColumn(number=3, label="生年月日")
23    @CsvFixedSize(length=10, padChar='_')
24    @CsvDateTimeFormat(pattern="uuuu-MM-dd")
25    private LocalDate birthday;
26
27    // 文字サイズを超えている場合は、切り出す。
28    @CsvColumn(number=4, label="備考")
29    @CsvFixedSize(size=20, chopped=true)
30    private String comment;
31
32    // getter, setterは省略
33}

出力されるCSVは下記のようになります。

ヘッダー行が固定長になっていないことがわかります。

コード - 8.1.2 出力されるCSV(1)
1id,氏名,生年月日,備考
2         1,山田 太郎     ,1990-01-12,コメント
3         2,山田 花子     ,__________,

8.2. ヘッダー行の固定長の指定

ヘッダー行もカラムの定義と同様に固定長にしたい場合は、@CsvBean(headerMapper=<ヘッダーのマッピング処理クラス>) でヘッダーの処理方法を変更します。

FixedSizeHeaderMapper [ JavaDoc ] は、フィールドに付与されたアノテーション @CsvFixedSize を元に、見出しに対してパディングを行います。

コード - 8.2.1 ヘッダーのマッピング定義を変更する
 1import com.github.mygreen.supercsv.annotation.CsvBean;
 2import com.github.mygreen.supercsv.annotation.CsvColumn;
 3import com.github.mygreen.supercsv.annotation.CsvFixedSize;
 4import com.github.mygreen.supercsv.builder.FixedSizeHeaderMapper;
 5
 6@CsvBean(header=true, headerMapper=FixedSizeHeaderMapper.class)
 7public class SampleCsv {
 8
 9    // 右詰めする
10    @CsvColumn(number=1)
11    @CsvFixedSize(size=10, rightAlign=true)
12    private int id;
13
14    // 以下、省略
15}
コード - 8.2.2 出力されるCSV - ヘッダーも固定長にする
1        id,氏名        ,生年月日__,備考
2         1,山田 太郎     ,1990-01-12,コメント
3         2,山田 花子     ,__________,

注釈

ヘッダーの見出しが全角、実際の値が半角で出力するような場合、意図した変換がされない場合があります。 その際は、独自に com.github.mygreen.supercsv.builder.HeaderMapper を実装したクラスを指定することで対応できます。

8.3. パディング処理方式の切り替え

固定長としてパディングする場合、サイズカウント方法の考え方は、複数あります。 例えば、半角は1文字、全角は2文字分として換算する。 または、文字のバイト数で換算することもあります。

  • パディング処理の実装を切り替えることができ、@CsvFixedSize の属性 paddingProcessor でパディング処理の実装クラスを指定します。

  • 本ライブラリでは、以下のパディング処理の実装が提供されています。

    • SimplePaddingProcessor [ JavaDoc ] - 文字の種別にかかわらず1文字としてカウントしてパディングします。

    • CharWidthPaddingProcessor [ JavaDoc ] - 文字の幅(半角は1文字、全角は2文字)によってカウントしてパディングします。デフォルトの実装です。

    • ByteSizePaddingProcessor [ JavaDoc ] - バイト数によってカウントしてパディングします。

      • バイト数で換算する場合、文字コードに依存するため、文字コードに対応したサブクラスを指定する必要があります。

  • 独自のパディング処理を指定したい場合は、 com.github.mygreen.supercsv.cellprocessor.conversion.PaddingProcessor を実装したクラスを指定してください。

コード - 8.3.1 ヘッダーのマッピング定義を変更する
 1import com.github.mygreen.supercsv.annotation.CsvBean;
 2import com.github.mygreen.supercsv.annotation.CsvColumn;
 3import com.github.mygreen.supercsv.annotation.CsvFixedSize;
 4import com.github.mygreen.supercsv.builder.FixedSizeHeaderMapper;
 5import com.github.mygreen.supercsv.cellprocessor.conversion.ByteSizePaddingProcessor;
 6import com.github.mygreen.supercsv.cellprocessor.conversion.CharWidthPaddingProcessor;
 7import com.github.mygreen.supercsv.cellprocessor.conversion.SimplePaddingProcessor;
 8
 9@CsvBean(header=true, headerMapper=FixedSizeHeaderMapper.class)
10public class SampleCsv {
11
12    // 文字の種別にかかわらず1文字としてカウントしてパディングします。
13    @CsvColumn(number=1)
14    @CsvFixedSize(size=10, paddingProcessor=SimplePaddingProcessor.class)
15    private int id;
16
17    // 文字の幅(半角は1文字、全角は2文字)によってカウントしてパディングします。
18    @CsvColumn(number=2)
19    @CsvFixedSize(size=20, paddingProcessor=CharWidthPaddingProcessor.class)
20    private String name;
21
22    // バイト数によってカウントしてパディングします。
23    @CsvColumn(number=3)
24    @CsvFixedSize(size=20, paddingProcessor=ByteSizePaddingProcessor.Windows31j.class)
25    private String comment;
26
27    // 以下、省略
28}