竹形誠司 ブログ
Java+MySQL+Tomcat    »トピック一覧
掲示板へのスパムが多いため、「ご質問」のコーナーはユーザー登録制とさせていただきました。お手数ですが、上の「新規ユーザーの登録」メニューより登録をお願いします。
帳票Web
アプリケーション

受注開発始めました
詳しくは こちら
竹形 誠司 著/ラトルズ刊
JSP帳票アプリケーション実践開発入門
JSP帳票アプリケーション
実践開発入門

JSP業務アプリケーション短期開発入門
JSP業務アプリケーション
短期開発入門

Java+MySQL+Tomcatで始めるWebアプリケーション構築入門
Java+MySQL+Tomcatで始めるWebアプリケーション構築入門

Java+MySQL+Tomcatで作る掲示板とブログ
Java+MySQL+Tomcatで作る
掲示板とブログ
JSPからiTextを使う
by 竹形 誠司[takegata]
iTextを使ってPDFを生成しようとしたが、サーブレットではうまくいくのにJSPだと日本語が化ける。

これは、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.jsp

出力結果は一応出るのだが、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 そのものの修正が必要になります。
投稿:KILROY[KILROY]/2007年 03月 25日 10時 07分 /更新:2007年 03月 25日 10時 07分