SalesforceのPDF出力で日本語を表示すると折り返しがされなくて、レイアウトが崩れてしまう現象があります。
結論としては、日本語の文字と文字の間にwbrタグを入れることで対処できます。
次がhtmlのwbrタグを入れる前と入れた後での表示の違いになります。
入れる前と入れた後でその他のhtmlタグは同じです。
上記の通り、wbrタグを入れる前は、日本語の部分がレイアウトが崩れているのがわかります。ですが、wbrタグを入れた後は、折り返しされてレイアウトも崩れていません。
以下wbrを入れるソースコードです。
文字と文字の間にwbrを入れると共に、次の文字「"<" ">" "&" "半角スペース"」のエスケープや改行コードからbrタグへの変換を行っています。
また、wbrが不要な半角文字にはwbrを入れていないため、元々の折り返しにまかせています。(英単語の間で改行はされないようにしています)
[ソースコード]
//wbrタグをいれつつ、エスケープする文字を対応する。
//エスケープは < > & 半角スペースとする。
public String insWBR(String value){
if( String.isempty(value) ){
return '';
}
String retstr = '';
for(integer i=0; i< value.length() ; i++ ){
if( i > 0 ){
if( value.substring(i-1, i).isAsciiPrintable()
|| ( value.substring(i-1, i).codepointAt(0) >= 55296
&& value.substring(i-1, i).codepointAt(0) <= 56319 ) ){
if( ' ' == value.substring(i-1, i) ){
retstr += '<wbr/>';
}
} else {
retstr += '<wbr/>';
}
}
String charval = value.substring(i, i+1);
if( charval == '\n' ){
retstr += '<br/>';
} else if( charval == '&' ){
retstr += '&';
} else if( charval == ' ' ){
retstr += ' ';
} else if( charval == '>' ){
retstr += '>';
} else if( charval == '<' ){
retstr += '<';
} else {
retstr += charval ;
}
}
return retstr;
}
もちろん、htmlタグを含んだ文字列を表示するので、escape="false"の指定が必要です。( <apex:outputtext value="{!wbrvalue}" escape="false"/> )
2017/4/3 変更 サロゲートペアの文字の場合?となってしまうので、サロゲートペアの上位の後はタグを挿入しないように修正しました。
2017/7/24 サロゲートペアの上位文字は固定値ではなく、範囲で判定しなければいけないことに気がつき修正しました。