Apache FOPを使ってSVGをPDFに変換する

Apache FOP

Apache FOP は、XML文書をPDFやPNGなど印刷可能なフォーマットに変換するためのOSSプロジェクトです。

変換元としてSVGも扱えるので、これを使ってPDFに変換できます。

なお、SVGの部分は、同じくApacheプロジェクトのBatikが使用されています。

使い方

FOPのバイナリ(fop-1.1-bin.zip)をダウンロードします。

FOPのjar(fop-1.1\dist\fop.jar)と、FOPで必要とするライブラリのjar(fop-1.1\lib\*.jar)をクラスパスに設定します。全部で11のjarファイルになります。

  • avalon-framework-4.2.0.jar
  • batik-all-1.7.jar
  • commons-io-1.3.1.jar
  • commons-logging-1.0.4.jar
  • fop.jar
  • serializer-2.7.0.jar
  • xalan-2.7.0.jar
  • xercesImpl-2.7.1.jar
  • xml-apis-1.3.04.jar
  • xml-apis-ext-1.3.04.jar
  • xmlgraphics-commons-1.5.jar

変換処理は簡単で、PDFTranscoder を使って変換するだけです。

SVG2PDFConverter

はまりどころ

flowRoot でエラーになる

Inkscape で作ったSVGを変換しようとしたところ、下記のようなエラーになりました。

Exception in thread "main" org.apache.batik.transcoder.TranscoderException: null
Enclosed Exception:
The current document is unable to create an element of the requested type (namespace: http://www.w3.org/2000/svg, name: flowRoot).
	at org.apache.batik.transcoder.XMLAbstractTranscoder.transcode(Unknown Source)
	at org.apache.batik.transcoder.SVGAbstractTranscoder.transcode(Unknown Source)
	at com.enjoyxstudy.svg2pdf.SVG2PDFConverter.convert(SVG2PDFConverter.java:47)
	at com.enjoyxstudy.svg2pdf.SVG2PDFConverter.main(SVG2PDFConverter.java:29)

flowRoot があるのが原因で、svg要素のversionを1.1->1.2に変えることによりエラーが回避できました。(flowRoot自体、SVG1.2で追加されたものなのかなと調べましたが、WDの時点ではあったけど、SVG Tiny 1.2の時点では消えているっぽいですね)

flowRootがうまく変換されない

flowRootの部分は黒塗りになってしまいました。text使うしかないですね。

日本語がうまく変換されない

日本語部分が"#"となってしまいました。フォントの問題だと思うのですが、原因がはっきりしていません。

上のドキュメントを見ると、auto-detectと設定しておくと、システム上にインストールされているフォントを使ってくれるみたいで、かつ PDFTranscoder は、デフォルトで auto-detect が設定されるようなので、問題ないんじゃないのかなぁと思ったのですが、何か考慮が漏れているようです。