iTextを使ってPDFを生成しようとしたが、サーブレットではうまくいくのにJSPだと日本語が化ける。
これは、jasperが.JSPを.JAVAに変換する際に日本語の文字コードを変えてしまうためだ。そこで、iTextに文字列を渡す前に逆に変換するメソッドをはさんでみた。
なんとなくうまくいっているが、変換元のcharsetをなぜUTF-8ではなくISO-8859-1にしないとうまくいかないのか良くわからない。とりあえず、こんな感じ。
出力結果は一応出るのだが、Tomcatのstdout.logに次のようなエラーログが残っている
●追記:
iTextの開発者によると、環境によってはJSPからバイナリデータを生成する際に余計な改行コードや空白文字が入って、トラブルの原因になることがあるらしい。
●2011/5/20追記
新しいバージョンのiTextでライブラリを作り直しました。Tomcat7で使っている限りではログにエラーが出ていない感じです。
http://www.orquesta.org/takegata/Article/ArticleView.jsp?article_id=825
●2011/6/2追記
やっぱり出てます。やはりサーブレットにしないとエラーは出てしまうみたいですね。実害は無いみたいですけど。
●2011/7/18追記
スクリプトレットの外側で改行しなければエラーは出ないようです。
参考:http://d.hatena.ne.jp/hanye0708/20110226/1298698199
これは、jasperが.JSPを.JAVAに変換する際に日本語の文字コードを変えてしまうためだ。そこで、iTextに文字列を渡す前に逆に変換するメソッドをはさんでみた。
なんとなくうまくいっているが、変換元のcharsetをなぜUTF-8ではなくISO-8859-1にしないとうまくいかないのか良くわからない。とりあえず、こんな感じ。
<%@ page
language="java"
import="java.io.*, com.lowagie.text.*, com.lowagie.text.pdf.*"
%>
<%@ page contentType="application/pdf"%>
<%!
String getSjis(String str) throws java.io.UnsupportedEncodingException{
String str2=new String(str.getBytes("ISO-8859-1"),"SJIS");//謎
return str2;
}
%>
<%
Document document = new Document();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
PdfWriter pdfwriter = PdfWriter.getInstance( document, buffer );
document.open();
BaseFont bf = BaseFont.createFont("HeiseiKakuGo-W5","UniJIS-UCS2-H",false);
PdfContentByte pcb = pdfwriter.getDirectContent();
pcb.beginText();
pcb.setTextMatrix(180,700);
pcb.setFontAndSize(bf,50);
pcb.setLeading(15);
pcb.showText(getSjis("がちょ〜ん"));
pcb.endText();
document.close();
response.setContentLength(buffer.size());
ServletOutputStream output = response.getOutputStream();
buffer.writeTo(output);
output.flush();
%>
出力結果 ⇒ http://www.orquesta.org/takegata/test/gachon.jsplanguage="java"
import="java.io.*, com.lowagie.text.*, com.lowagie.text.pdf.*"
%>
<%@ page contentType="application/pdf"%>
<%!
String getSjis(String str) throws java.io.UnsupportedEncodingException{
String str2=new String(str.getBytes("ISO-8859-1"),"SJIS");//謎
return str2;
}
%>
<%
Document document = new Document();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
PdfWriter pdfwriter = PdfWriter.getInstance( document, buffer );
document.open();
BaseFont bf = BaseFont.createFont("HeiseiKakuGo-W5","UniJIS-UCS2-H",false);
PdfContentByte pcb = pdfwriter.getDirectContent();
pcb.beginText();
pcb.setTextMatrix(180,700);
pcb.setFontAndSize(bf,50);
pcb.setLeading(15);
pcb.showText(getSjis("がちょ〜ん"));
pcb.endText();
document.close();
response.setContentLength(buffer.size());
ServletOutputStream output = response.getOutputStream();
buffer.writeTo(output);
output.flush();
%>
出力結果は一応出るのだが、Tomcatのstdout.logに次のようなエラーログが残っている
java.lang.IllegalStateException: getOutputStream()はこのレスポンスに対して既に呼び出されています
やっぱりサーブレットが無難か・・。●追記:
iTextの開発者によると、環境によってはJSPからバイナリデータを生成する際に余計な改行コードや空白文字が入って、トラブルの原因になることがあるらしい。
●2011/5/20追記
新しいバージョンのiTextでライブラリを作り直しました。Tomcat7で使っている限りではログにエラーが出ていない感じです。
http://www.orquesta.org/takegata/Article/ArticleView.jsp?article_id=825
●2011/6/2追記
やっぱり出てます。やはりサーブレットにしないとエラーは出てしまうみたいですね。実害は無いみたいですけど。
●2011/7/18追記
スクリプトレットの外側で改行しなければエラーは出ないようです。
参考:http://d.hatena.ne.jp/hanye0708/20110226/1298698199
投稿:竹形 誠司[takegata]/2006年 11月 11日 22時 58分
/更新:2011年 07月 18日 20時 30分
iText の行末禁則について
by KILROY[KILROY]
iText で CJK フォント(要するに漢字とカナ)で書かれた文章を出力する際に、「行末禁則が働かない」という問題があります。
つまり、「、」「。」などの「前」で「ここで切っちゃダメ」、「後」で「ここで切ってよし」を指定しているのに、どうしても行頭に「、」や「。」が来てしまうことがあります。
これは iText の割付のロジックの問題で、iText のソース自体に手を入れる以外に、本質的な解決方法がありません。
回避策としては「、」「。」などの「前後」で「ここで切っちゃダメ」を返すようにする方法があるのですが、「a、b、c、d のいずれも」とかいった文(半角文字に挟まれた形で禁則文字が1字だけ存在する)が来た場合、「a、b、c、d」が一個の単語のように「どこでも切れない」塊になってしまうという副作用が出ます。
元の文が修正できる場合は、「ここで切りたい」という「、」の後に、明示的に半角のスペースを入れることで対応はできますが、完全自動で PDF を作成しようとした場合は、やはり iText そのものの修正が必要になります。
つまり、「、」「。」などの「前」で「ここで切っちゃダメ」、「後」で「ここで切ってよし」を指定しているのに、どうしても行頭に「、」や「。」が来てしまうことがあります。
これは iText の割付のロジックの問題で、iText のソース自体に手を入れる以外に、本質的な解決方法がありません。
回避策としては「、」「。」などの「前後」で「ここで切っちゃダメ」を返すようにする方法があるのですが、「a、b、c、d のいずれも」とかいった文(半角文字に挟まれた形で禁則文字が1字だけ存在する)が来た場合、「a、b、c、d」が一個の単語のように「どこでも切れない」塊になってしまうという副作用が出ます。
元の文が修正できる場合は、「ここで切りたい」という「、」の後に、明示的に半角のスペースを入れることで対応はできますが、完全自動で PDF を作成しようとした場合は、やはり iText そのものの修正が必要になります。
投稿:KILROY[KILROY]/2007年 03月 25日 10時 07分
/更新:2007年 03月 25日 10時 07分