2011年12月16日金曜日

ConfluenceのHTML→PDF変換ライブラリを利用する

JIRA Advent Calendar 2011、15日目です。

ってすみません、ConfluenceネタですがまあJIRA使ってる人は連携して使ったりしますよねとか、そんな感じで。
GradleのユーザーガイドPDFに変換するときにお世話になったので、紹介してみます。

Confluenceは、バンドルされているプラグインでページをPDFに変換して出力できるのですが、この機能に使われているライブラリを使って、XHTMLをPDFに変換しようという話です。

ConfluenceのXHTML→PDF処理にはFlying SaucerというJavaのライブラリが使われています。
Flying Saucerを使うと、XMLやXHTMLファイルを、PDFやSWT、Swingのスクリーンに出力させることができます。デザインはCSSで指定できます。

ただ、このFlying Saucer、PDFに変換したときに、文字列が空白位置でしか改行されません。
英文Onlyならいいのですが、日本語で長文をだらだら書いていると画面外にあふれて見えなくなってしまうわけですね。
ConflueceのPDFエクスポートでの禁則 - azuki note

この問題を、Atlassianさんがパッチを当てて修正しているので、しかもMavenリポジトリ上に上げてくれているので、今回はそれを使います。

@Grape+Groovyスクリプトでもいいですが、いろいろ面倒なのでGradleスクリプトで。

フルのサンプルはGithubに上げたのでそちらを見てもらうとして、ポイントだけ書いておきます。

変換元のHTMLとCSSのサンプル

AtlassianさんのMavenリポジトリからFlying Saucerを取得

AtlassianさんのMavenリポジトリから、パッチの当たったFlying Saucerライブラリを取得します。
GradleとかMavenとかIvyとか、そのあたりの設定に依存関係を追加するのがいいですね。

ライセンスが気になるところですが、LGPLのままみたいなので大丈夫でしょう、多分…

Mavenリポジトリ
https://maven.atlassian.com/repository/public
アーティファクト
org.xhtmlrenderer:xhtmlrenderer:8.3-atlassian

Flying SaucerはPDF生成にiTextを使うのでそちらも

Mavenリポジトリ
セントラルリポジトリ
アーティファクト
com.lowagie:itext:2.0.8
// Gradleの例
buildscript {
    repositories {
        mavenCentral()
        mavenRepo url: "https://maven.atlassian.com/repository/public"
    }
    dependencies {
        classpath "org.xhtmlrenderer:xhtmlrenderer:8.3-atlassian"
        classpath "com.lowagie:itext:2.0.8"
    }
}

PDFへの変換処理

PDFへの変換処理は、次のような感じで書きます。

import org.xhtmlrenderer.pdf.ITextRenderer

def renderer = new ITextRenderer()
renderer.setDocument(new File("sample.html"))
renderer.layout()
new File("sample.pdf").withOutputStream {
    renderer.createPDF(it)
}

このコードを実行すれば、sample.htmlがsample.pdfに変換されます。

CSSでPDFに埋め込むフォントを指定する

日本語を使うには日本語フォントをPDFに埋め込むか参照させる必要があります。変換元のHTMLに次のようなCSSを適用しましょう。

@font-face{
    font-family: "IPAexGothic";
    src: url(ipaexg.ttf);
    -fs-pdf-font-embed: embed;
    -fs-pdf-font-encoding: Identity-H;
}

body {
    font-family: "IPAexGothic";
}

なんか、使えるフォントと使えないフォントがあるみたいです。

fsなんたらはFlying Saucerのベンダー拡張ですね。詳しくはFlying Saucerのユーザーガイドを見てみてください。

長い文章を折り返すための設定

Atlassianさんのパッチが当たったFlying Saucerを使うと、次のようにCSSでword-wrapを指定することで長い文章が折り返されるようになります。

p {
    word-wrap: break-word;  
}

おわりに

いやぁ、便利ですね。ちょっとしたPDF作るだけなら、それ用のHTMLファイル作って変換するのが簡単かもしれません。

さて、かなり脱線気味でしたが、こんなところで。
引き続きJIRA Advent Calendar 2011をお楽しみください。

0 件のコメント:

コメントを投稿