PDFBoxを使ってPDFを作成する(その2)

PDFBoxを使ってPDFを作成しようとしたところ・・・という話でした。

5.改行、改ページができない

できない、と書きましたができるんです。
改行は
cos.newLine();
改ページは
page = new PDPage();
document.addPage(page);

でできます。でもそうじゃないんです!
長い文やページを超える文を出力するときに、自動で改行や改ページしてほしいんです!
結論。できません。
そういうものかもしれませんが、なんとなく自動でできるような気がしていました。
ということで、文字数/行数を自分でカウントして、よきところで改行/改ページを入れる方法で解決しました。
コードは汚いので割愛します。。

6.ファイル保存でOutOfMemoryError発生

今回、1000ページ(数百MB)以上のPDFを作成することもあったのですが、
document.save("sample.pdf")
のところでOutOfMemoryが発生することがありました。
調べたところ、ページ数が多いと発生することがあるという記事を見つけました。
(ちなみにJDK1.6限定で、1.7だと発生しないとのことです。今回の環境は1.6でした。)
この記事なんですが、リンク切れで表示できません。一応、URLはこちらです。
http://www.gcgate.jp/engineerblog/2013/12/06/223/
記事によると
・ある一定ページ数になったらPDFをファイルに書き込む
・その書き込んだPDFファイルを読み込みページを追加する
・繰り返す
で解決したということだったので、これを試したのですが解決せず。
いろいろ試して、PDFファイルを分割して保存する方法で解決できました。
これもコードは割愛しますが、ページ数を自分でカウントして、決まった件数のときにファイルを保存する、という流れです。
今回のケースは、ページ数が多いというより、ファイルサイズの大きさによるような気がします。
分割する際ファイルサイズでできればいいのですが、それは厳しいのでページ数で区切りました。

7.作成したファイルで検索ができない

すみません。これはまだ解決できていません。
1つ前の記事で書いた通り、今回日本語を表示するためにIPAゴシックを使いました。
すると、作成したPDFをAdobeのPDFリーダー等で開いて、検索しようとすると
検索できるファイルと検索できないファイルがありました。何か特定の文字が含まれると検索できないようなのですが、原因となる文字は特定できていません。
また、PDFBoxで何かしら対策ができるのか、も今のところ不明です。

他のライブラリは使っていないので比較ができないのですが、PDFBox、便利は便利だけどすごく使いやすくはない、というふわっとした感想で終わりたいと思います。
あ、公式サイトのFAQは結構役立ちました。

PDFBoxを使ってPDFを作成する(その1)

JavaでPDFファイルを作成することになり、いろいろライブラリを見た結果、一番よさげだったApache PDFBoxを使うことにしました。
一応やりたいことはできたものの、困ったことやわからないことがポロポロとあったので、そのあたり書き残しておこうと思います。
ごくごく基本的な使い方(HelloWorld的な)について説明しているページはいくつか見つけたものの、そこから先の細かい使い方を書いてくれているページがあまりなかったので、どこかの誰かの役に立てばいいなと思いつつ。。。

1.ダウンロード

公式サイトのダウンロードページからダウンロードします。

2.HelloWorld

特に難しいことはありません。以下のコードでHelloWorldと出力されます。正確には出力されたPDFファイルが作成されます。ですね。
細かい説明は省きます。
PDDocument document = new PDDocument();
PDPage page = new PDPage();
document.addPage(page);
PDFont font = PDType1Font.HELVETICA_BOLD;
PDPageContentStream cos= new PDPageContentStream(document, page);
cos.beginText();
cos.newLineAtOffset(0f, 0f);
cos.setFont(font, 12);
cos.setLeading(12);
cos.showText("Hello World");
cos.endText();
cos.close();
document.save("helloworld.pdf");
document.close();

※PDPageContentStreamは、1ページにつき1回生成します。
1ページの中に異なるフォントや異なる文字サイズで出力する場合は、
cos.beginText();
から
cos.endText();
までを繰り返します。

3.日本語

必要に応じてフォントをダウンロードしてください。ちなみに今回はIPAフォントを使いました。
そして、
PDFont font = PDType1Font.HELVETICA_BOLD;
の部分を
PDFont font = PDType0Font.load(document, new File("/usr/share/fonts/ipa-gothic/ipag.ttf"));
とすることで、日本語も表示することができます。

4.画像

PDImageXObject ximage = PDImageXObject.createFromFile("photo.jpg", document);
cos.drawImage(ximage, 100, 100, ximage.getWidth(), ximage.getHeight());

で画像が表示できます。

文字の表示にしろ画像の表示にしろ、それぞれ表示位置を指定できるので、1つのページに文章と画像を表示することももちろん可能です。
表示位置は、実際に出力してみて、微調整した方がいいと思います。
また、画像の表示は文字の表示に比べてかなり時間がかかります。(画像のサイズが大きいと特に)

ここまでが基本的な使い方になります。日本語も表示できる、画像も表示できる、よしよし・・・と思ったのも束の間、ちょこちょこと問題が発生するのでした。

続く

既存サイトのスマートフォン対応

はじめまして。シーマークの宮崎です。
ブログのサブタイトルに「裏秋葉」とありますが、私は今流行り(?)の
在宅勤務のため、実は秋葉原にはいません。
在宅勤務といっても、節電対策とは全く関係ないのですが。。。
ということで、(今のところは)東京より涼しい長野から書いていきたいと思います。

さて、今年の夏も携帯キャリアから新しい機種が発表・発売されています。
スマートフォンが多くなった、と感じている方は多いのではないでしょうか。
2010年度のスマートフォンの割合は、
出荷台数においては22.7%、また契約数では8.8%
ということですが(http://wirelesswire.jp/News_in_Japan/201107081931.html)
実感値としてはもっと多いように感じます。
先日都内の駅のホームで周囲を見たところ、若い人が多かったせいもあるかもしれませんが
携帯電話を触っている人のほとんどがスマートフォンでした。
先ほどの記事でも、今後もスマートフォンの割合は増加するという予測がされており、
「スマートフォン対応サイト」が必須となってくるかと思います。

乱暴な言い方をしてしまうと、PCサイトにしろ携帯サイトにしろ、
スマートフォンでも見ることはできます。
私自身、「スマートフォン対応サイトって・・・」ともやもやしたところがありました。
「スマートフォン対応」とは、何をすべきなのか、何ができるのか。
特に既存のサイトをスマートフォン対応する場合、を中心にして
これから書いていけたらと思います。