はじめに
最近のシステムはほとんどの場合 UTF-8 が標準の文字コードになっており、 Salesforce も例に漏れずあらゆるインタフェースで UTF-8 を採用しています。しかし、稀に Salesforce (Apex) から古いシステムを触る必要があるときや、後処理の都合などで文字列を Shift_JIS や EUC-JP などに変換する必要に迫られる場合があります。Java や Python などの主要なプログラミング言語では標準で文字コードの変換が可能ですが、Apex は文字列の文字コード変換用のメソッドは存在しておらず、少しテクニカルに処理する必要があります。
方針
EncodingUtil.urlEncode
を使えばマルチバイト文字は主要な文字コードに変換することができます。
ただしこのメソッドだと ASCII 文字が変換されないので、 EncodingUtil.urlEncode
に渡す前にASCII文字列だけを個別に16進数表記の文字列に変換します。すべての文字列を変換先の文字コードの16進数表記にしたら EncodingUtil.convertFromHex
で Blob 形式に変換して処理完了となります。
作ったもの
主要な日本語対応の下記文字コードをエンコードできるメソッドを用意しています。
- EUC-JP
- Shift_JIS
- ISO-2022-JP
- UTF-16(BE)
- UTF-16(LE)
- UTF-32(BE)
- UTF-32(LE)
使い方
// 文字コード変換
Blob eucJp = CharacterEncodingUtil.encodeToEucJp('文字列');
Blob shiftJis = CharacterEncodingUtil.encodeToShiftJis('文字列');
Blob iso2022Jp = CharacterEncodingUtil.encodeToIso2022Jp('文字列');
Blob utf16 = CharacterEncodingUtil.encodeToUtf16('文字列');
Blob utf16le = CharacterEncodingUtil.encodeToUtf16LE('文字列');
Blob utf32 = CharacterEncodingUtil.encodeToUtf32('文字列');
Blob utf32le = CharacterEncodingUtil.encodeToUtf32LE('文字列');
// 改行コードを指定して文字コード変換
Blob eucJp = CharacterEncodingUtil.encodeToEucJp('文字列', CharacterEncodingUtil.NewlineSeparator.CRLF);
Blob shiftJis = CharacterEncodingUtil.encodeToShiftJis('文字列', CharacterEncodingUtil.NewlineSeparator.LF);
Blob iso2022Jp = CharacterEncodingUtil.encodeToIso2022Jp('文字列', CharacterEncodingUtil.NewlineSeparator.CR);
Blob utf16 = CharacterEncodingUtil.encodeToUtf16('文字列', CharacterEncodingUtil.NewlineSeparator.CRLF);
Blob utf16le = CharacterEncodingUtil.encodeToUtf16LE('文字列', CharacterEncodingUtil.NewlineSeparator.LF);
Blob utf32 = CharacterEncodingUtil.encodeToUtf32('文字列', CharacterEncodingUtil.NewlineSeparator.CR);
Blob utf32le = CharacterEncodingUtil.encodeToUtf32LE('文字列', CharacterEncodingUtil.NewlineSeparator.CRLF);
// 変換時のデフォルトの改行コードの変更
CharacterEncodingUtil.defaultNewLineSeparator = CharacterEncodingUtil.NewlineSeparator.LF;
// 改行コード LF で EUC-JP にエンコード
Blob eucJp = CharacterEncodingUtil.encodeToEucJp('文字列');
実装例
Apex で Shift_JIS 形式の CSV をファイルとして保存する処理の実装例
String DIGIT = '0123456789';
String ALPHABET = 'loremipsum';
String HIRAGANA = 'いろはにほへと';
String KATAKANA = 'イロハニホヘト';
String HALF_KATAKANA = 'イロパニボペト';
String KANJI = '高崎髙﨑';
String SPACE = ' \t';
String SYMBOL = '!"#$%&()[]{}`~=-\\';
String EMOJI = '😇🏴👶🏿';
String csvHeader = String.join(new List<String>{
'DIGIT',
'ALPHABET',
'HIRAGANA',
'KATAKANA',
'HALF_KATAKANA',
'KANJI',
'SPACE',
'SYMBOL',
'EMOJI'
}, ',');
String csvBody = String.join(new List<String>{
DIGIT,
ALPHABET,
HIRAGANA,
KATAKANA,
HALF_KATAKANA,
KANJI,
SPACE,
SYMBOL,
EMOJI
}, ',');
ContentVersion cv = new ContentVersion();
cv.ContentLocation = 'S';
cv.PathOnClient = 'example.csv';
cv.Title = 'example.csv';
cv.VersionData = CharacterEncodingUtil.encodeToShiftJis(csvHeader + '\n' + csvBody);
insert cv;
制限/留意事項
- 変換先の文字コード上に存在しない文字(特に絵文字や機種依存文字など)は ? に変換されます
- 大量の文字列を変換する場合、CPU時間に注意してください
- 手元の環境だとShift_JIS変換のマルチバイト文字のみで 10,000 文字あたり 200 ~ 250 ms、ASCII文字のみで 10,000 文字あたり 平均 500 ~ 600 msほど消費します
- UTF-16, UTF-32 はさらにASCII文字の処理負荷が1.5 ~ 2倍ほど
- もう少し工夫すればチューニングできる...?
- 手元の環境だとShift_JIS変換のマルチバイト文字のみで 10,000 文字あたり 200 ~ 250 ms、ASCII文字のみで 10,000 文字あたり 平均 500 ~ 600 msほど消費します