#サーバ上(またはコマンドライン)で、もう何でもかんでもPDFに変換する方法
例として Fedora とか CentOS の新しめのものを想定します。
##Microsoft Office系ファイル
###準備するもの
以下の物をインストールします。
libreoffice
libreoffice-base
libreoffice-calc
libreoffice-core
libreoffice-draw
libreoffice-emailmerge
libreoffice-graphicfilter
libreoffice-headless
libreoffice-impress
libreoffice-langpack-ja
libreoffice-math
libreoffice-opensymbol-fonts
libreoffice-pdfimport
libreoffice-pyuno
libreoffice-ure
libreoffice-writer
使わないものもあるかもしれませんが、普通にlibreofficeをインストールすればまとめて入っちゃうと思います。
ただ、libreoffice-headless は忘れないようにしましょう。
###変換する
libreoffice --headless --nologo --nofirststartwizard --outdir ./ --convert-to pdf ファイル名
※libreofficeのバージョンによっては、--outdir のオプションを --convert-to よりも後に書かないと動かない場合があります。
サンプルの通りに書いて動かない場合は、--outdir を最後に書いてみてください。--2017-02-14
書き換える必要があるのは、--outdir で指定する出力先のディレクトリ、ファイル名ぐらいです。
今回はpdf に変換ということで、--convert-to はpdf にしていますが、ここを掘り下げると思いっきり深みにハマりますので、スルーしておきます。
深みにハマった例(output_filter_nameの出力)はこちら→ http://www.mixp.net/linux/319
対応ファイルは、
- .doc, .docx (MS Word形式)
- .xls, .xlsx (MS Excel形式)
- .ppt, .pptx (MS Power Point形式)
です。
あ、もちろんLibreOfficeのドキュメントもいけます。
他にも対応しているものがあるかもしれませんが、試していません。
再現度は、まぁ、それなりです。
元ファイル名の拡張子が.pdf になって保存されます。
古い情報だと仮想デスクトップを立ち上げて云々という情報もありますが、最近のLinuxだと、なんか自力でゴニョゴニョやってるみたいです。
そのせいで変換に少し時間がかかります。
あと、気をつけるべきなのはサーバのデスクトップ上でLibreoffice が起動しているとコマンドに失敗しますので、注意してください。
##HTML のスナップショット
###準備するもの
wkhtmltopdf
http://wkhtmltopdf.org/downloads.html
↑ここから環境にあったバイナリをダウンロードしてきます。
Redhat 系ならrpm、Debian、Ubuntu 系ならdeb が準備されています。
一応、Windows 用 Mac 用もあります。
###変換する
wkhtmltopdf http(s)://URL 出力ファイル名
でPDF ファイルが生成されます。あら便利。
レンダリングエンジンにはwebkit が使われていますので、Chrome や Opera に近いイメージです。
CSSやJavaScriptも解釈します。
BASIC認証がかかっている場合には、
wkhtmltopdf --username ユーザ名 --password パスワード http(s)://URL 出力ファイル名
でOKです。
サイズはデフォルトでA4でページングされます。
wkhtmltopdf をインストールすると、
wkhtmltoimage も同時にインストールされます。
PDF ではなく画像に変換したい場合は、こちらを使います。
jpg, png は出力先のファイルの拡張子に応じて出力されます。
gif化は失敗します。
##SVG画像
###準備するもの
inkscape というツールをコマンドラインから使用します。
imagemagick でも変換できますが、svg に特化したinkscape の方がよさそうな気がします。
yum install inkscape
みたいな感じでインストールします。
###変換する
inkscape -f ファイル名.svg -A 出力ファイル名.pdf
で変換できます。
-d オプションで解像度が指定できます。
縦書きはフォントがあやしいです。
##その他の画像など
###準備するもの
imageMagick というツールを使います。
ついでにghostscript もインストールしてポストスクリプトに対応させます。
imagemagick
ghostscript
ghostscript-fonts
多分、こんだけです。
###変換する
基本的には、
convert 変換元ファイル名 -page A4 変換後ファイル名.pdf
です。
多分そのままだと、非常に荒いpdf になると思いますので、予め300 dpi で計算して作っておいて、
convert -density 300 変換元ファイル名 -page A4 変換後ファイル名.pdf
とかやると美しいです。
jpg、 gif、 png などの他、svg などにも対応しています。
(svgの変換にはinkscapeの使用をおすすめします。)
tiff もほとんどいけますが、たまに真っ黒画像になったりします。
もともとimageMagickは画像のフォーマット変換や加工をするツールなので、pdf 以外にも使用できます。
これも使い方の解説を始めると本1冊書けちゃいますので割愛します。
###Tiffを撃破する(2018-07-04 追記)
真っ黒Tiffに解決の道が見えたので記載します。
手元のtiff画像では、jpeg圧縮がなんか古そうでしたので、圧縮方法を変えて対処します。
libtiff
をインストールしておきます。
以下のコマンドで変換して、そのあとはいつものconvertコマンドで。
tiffcp -c zip 元のファイル名 圧縮方式変換後のファイル名
convert 圧縮方式変換後のファイル名 -page A4 PDFに変換後ファイル名.pdf
##PDFをPDFに変換する
php で fpdf + fpdi な環境でPDFを触ろうとした場合、現在のバージョンでは、pdf1.5 が読み込めません。
そんな時は、
convert -density 300 元のファイル名.pdf 新しいファイル名.pdf
とやると、pdf1.4になってしまいます(一時的な仕様?)
それを利用して、pdf1.5をpdf1.4に変換して、php でゴニョゴニョいじれるようになります。
ただし、文字情報は画像情報になってしまいます。
##禁断のGIMPバッチモード
古いtiff画像を変換するときに、どうしても真っ黒になってしまうものがありましたので、ついに禁断のGIMPバッチモードに手を染めてしまいました。
GIMPで扱えるファイルならもうなんでもいけちゃいます。
ImageMagick でできないことでもGIMPでできることなら何でもできます。たぶん。
サーバにGIMPを入れるって時点でアレですが、すでにLibreOfficeとかも入れちゃってるので、今更怖いものはありません。
###GIMPのインストール
yum install gimp
いろいろやっていたのでこれだけでいけましたが、PDFに変換するのであれば、ghostscript なんかも必要だと思います。
###GIMPの環境設定
GIMPを使用するにはユーザのホームディレクトリに~/.gimp-2.x といった感じのディレクトリで環境設定ファイルがないといけません。
これはGIMPを初めて起動するときに生成されますので、バッチを実行するユーザで
gimp -i -b '(gimp-quit 0)'
とかで環境を整えておきましょう。
-i はノンインタラクティブモードの指定、-b はバッチコマンドを実行するパラメータで、
(gimp-quit 0) はGIMPを終了するコマンドです。
私の場合apacheユーザで実行させたかったので、以下のPHPを作成してブラウザで叩いて環境設定を行いました。
<?php
print `gimp -i -b (gimp-quit 0)`;
?>
/etc/passwd で apcheユーザのホームディレクトリは調べられます。
私の場合、/usr/share/httpd でした。
ただ上記のディレクトリはrootがオーナーになっていましたので、
chmod 777 /usr/share/httpd
で書き込みを許可しました。セキュリティ?知らん。
これで、/usr/share/httpd/.gimp-2.8 というディレクトリが生成されます。
###バッチの定義と実行
GIMPのバッチはScript-FuというLISP風味のScheme言語で記述していきます。
以下の内容のファイルをconvertTo.scmという名前で(拡張子以外はなんでもいい)
~/.gimp-2.8/scripts の中に保存します。
(define (script-fu-convert-to inFile outFile)
(let* (
(img (car (gimp-file-load 1 inFile inFile)))
(layer (car (gimp-image-active-drawable img)))
)
(gimp-file-save 1 img layer outFile inFile)
)
(gimp-quit 0)
)
LISP系の言語は慣れていないので、インデントの付け方などがイマイチわかりません。
括弧の数が合わなくて結構苦労しました。
内容の細かい説明は省きます。めんどくさいので。
上記のバッチ定義ファイルを保存したら、あとはGIMPをバッチモードで呼び出すだけです。
gimp -i -b '(script-fu-convert-to "sample.tif" "sample.pdf")'
で変換できます。GIMPで識別できるファイル形式なら、拡張子だけでうまいことやってくれます。
<?php
header("Content-Type: application/pdf");
print `gimp -i -b '(script-fu-convert-to "sample.tif" "sample.pdf")';cat "sample.pdf"`;
unlink("sample.pdf");
?>
なんてphpを書いちゃうと、1行で変換したpdfを表示できます。やったね。
エラーチェック?知らん。
結構重い処理だと思いますので、ループで大量に回したりするとどうなるかはわかりません。
##まとめ
上記の方法でWEB上の殆どのデータはPDF化できるのではないでしょうか?
あとは、gs コマンド等でだだーっと結合して、
はい納品。