🦔

Linux 環境のサーバで Office ファイルを PDF に変換する

に公開

最初に結論

shelfio/aws-lambda-libreoffice のアプローチで自前実装する

shelfio/aws-lambda-libreoffice は LibreOffice をコンテナイメージ版の AWS Lambda で動かすプロジェクトであり、shelfio/libreoffice-lambda-base-image というベースイメージとそれを前提とした Node.js ライブラリである shelfio/aws-lambda-libreoffice から成る。

リリース当時の紹介ブログは以下。

https://medium.com/shelf-io-engineering/running-libreoffice-in-aws-lambda-2022-edition-open-sourced-9bb0028911d8

とても良いプロジェクトなのだが、2024/12 現在メンテナンスが滞っているように見える。(依存している LibreOffice のバージョンが 7.6.7 のままで、アップグレードする PR も放置されている)

なので、2024/12 現在ではこのプロジェクトのアプローチを参考にしつつ元ライブラリをフォークしたり古い部分は自前で実装し直すのが良いだろう。

以下はそのようにして作った Lambda で動く Office -> PDF 変換サーバの実装例。

https://github.com/daido1976/aws-office-preview-example/tree/main/lambda

Gotenberg を使う

Gotenberg は API ベースで Office ファイル含む様々なドキュメント形式のファイルを PDF に変換できる OSS で、内部で LibreOffice を使っている。

https://gotenberg.dev/docs/routes#convert-with-libreoffice

公式にサポートされている Docker Compose や Kubernetes、Cloud Run でデプロイできる場合はこちらを使った方が自前実装をしなくて良いので楽だろう。

https://gotenberg.dev/docs/getting-started/installation

Docker イメージが公開されているので、コンテナをデプロイできるプラットフォームならある程度動くはず。

https://hub.docker.com/r/gotenberg/gotenberg/

AWS Lambda では動かない様子だが...。

https://github.com/gotenberg/gotenberg/issues/540

筆者は AWS App Runner にデプロイしてみたが、特に詰まるところなくデプロイできた。

その他

LibreOffice を利用した PDF 変換の他社事例

AWS の公式ブログでも LibreOffice を利用した PDF 変換のアーキテクチャが紹介されており、shelfio/libreoffice-lambda-layer という前述した shelfio/libreoffice-lambda-base-image の前身プロジェクトが利用されている。

https://aws.amazon.com/jp/blogs/architecture/convert-and-watermark-documents-automatically-with-amazon-s3-object-lambda/

ちなみに Slack も Office ファイルのプレビュー機能を実現するのに、LibreOffice を使って PDF に変換している様子。

https://zenn.dev/daido1976/scraps/9326b6148d8b48

Windows 環境のサーバを動かせる場合

Windows 環境のサーバを動かせるなら PowerShell 経由で Office を操作して PDF エクスポートするのが良いかもしれない。
以下はナレッジワーク社の例。

https://note.com/knowledgework/n/nd42cb342f5a0

PowerPoint などの Office 系ファイルは Windows OS でしか動作しないため、Windows OS 環境に Converter を構築しています。現在は、仮想専用サーバーにインストールした Windows OS 内で PowerShell を通して Office を操作し、ファイルを開いて PDF をエクスポートします。

Discussion