こんにちは。プロダクト開発本部の小本です。
kickflowでは2024年2月からPDF形式で帳票出力できるようになりました これまで帳票出力ではXLSX形式でのみ出力可能でした。PDF形式での帳票出力では、まずサーバー側でXLSX形式での帳票を作成し、自動的にPDFへ変換してから出力します。
ところで、みなさんはXLSXをPDFに変換する処理は好きですか?自分でWindowsサーバーを用意してMicrosoft Excelをインストールする作業は好きですか? 私はNoです。だからCloudConvertを使っています。
ファイル形式の変換は意外と面倒
XLSX→PDFといったファイル形式を変換する処理を機能を自前で構築しようとすると、以下のような事柄を考えなければなりません。
- 変換ツール(Microsoft Excel等)とそれを動かすサーバー
- 可用性を担保するためのオートスケール・オートヒーリング
- 構成を管理するTerraformなどの仕組み
- ジョブ管理の仕組み
- 変換元のファイル・変換結果のファイルを保存する仕組み(S3など)
- Microsoft Office・Windowsのライセンスを管理する仕組み
その一方、ファイル形式を変換する機能はユーザーにとってはnice to have(「あったら便利」)な機能であり、must have(「それがあるなら買う」)ではありません。自前で構築するのは苦労が多い割に報われません。
そこで、代わりに注目すべきなのがCloudConvertのようなSaaSです。
CloudConvertとは?
https://cloudconvert.com/cloudconvert.com
ファイル形式を変換できるSaaSです。
Microsoft OfficeやPDFをはじめ、200以上のファイル形式に対応しています。
また、「画像にウォーターマークを追加する」「圧縮形式を最適化する」といった処理もできます。
外国のサービスでしょ?安全なの?
ISO 27001認証(いわゆるISMS認証)を取得しており、一定の信頼ができるはず。
Security & Compliance | CloudConvert
ファイル変換精度はどうなの?
CloudConvertでは、XLSXやDOCXについてはMicrosoft Officeを内部で使っています(LibreOfficeも選択できる)。 実際に使ってみても、ある程度の精度があるようです。
ただし、フォントやページングで、PC版のMicrosoft Officeで変換した場合と差異が生じることもあるようです。
料金は?
変換処理の回数に応じた従量課金です。変換処理によって単価は異なります。
また、開発用のサンドボックス環境は無料で使えます。
残念なところ
CloudConvertには、APIキーの発行はユーザー単位でしかできません。そのAPIキーで作成したジョブの結果は当該ユーザーでしか確認できません。
なので、本番運用では「APIキー払出し専用」の共有アカウントを作って、トラブルがあったらその共有アカウントにログインして調査することになります。
とはいえ、トラブルは少ないので、さほど困ってはいません。
CloudConvert APIを試してみる
1. アカウントを発行します
https://cloudconvert.com/register
2. APIキーを発行
ダッシュボードのAuthorization > API Keysで「Sandbox」を選択してAPIキーを作成します。
Personal Access Tokenが生成されるのでコピペしておきます。
3. ファイルのハッシュ値を登録する
Sandbox環境ではホワイトリストに登録したファイルしか変換できません。
$ md5sum sample.xlsx 962d5ee61e4753631fb821a8a203d4a9 sample.xlsx
ダッシュボードの「Sandbox > Whitelisted Sandbox Hashes」からハッシュ値を登録します。
4. ライブラリのインストール
Rubyの場合は gem をインストールします。
$ gem install cloudconvert
環境変数の設定
$ export CLOUDCONVERT_API_KEY=【APIキー】 $ export CLOUDCONVERT_SANDBOX=true
4. コードを書く
ある程度のコードはJob Builderで生成できます。
以下は「XLSXファイルをアップロード→XLSXファイルをPDFに変換→PDFファイルをダウンロード」と処理するコードです。
require 'cloudconvert' input_path = ARGV[0] # 入力ファイル output_path = ARGV[1] # 出力ファイル # job builder では new() に引数が与えられるが、APIキーを環境変数から渡される場合は不要 cloudconvert = CloudConvert::Client.new() # ジョブを作る job = cloudconvert.jobs.create({ "tasks": [ { "name": "import-my-file", "operation": "import/upload" }, { "name": "xlsx-to-pdf", "operation": "convert", "output_format": "pdf", "input": [ "import-my-file" ] }, { "name": "export-my-file", "operation": "export/url", "input": [ "xlsx-to-pdf" ], "inline": false, "archive_multiple_files": false } ] }) # XLSXファイルをimport-my-fileタスクにアップロードする cloudconvert.tasks.upload(File.open(input_path, 'rb'), job.tasks.where(name: "import-my-file").first) # ジョブの完了を待つ job = cloudconvert.jobs.wait(job.id) puts job.status # export-my-fileタスクの結果を取得する task = job.tasks.where(name: "export-my-file").first converted_file = task.result.files.first tf = cloudconvert.download(converted_file.url) # ダウンロードする。戻り値はTempfile # Tempfileをカレントディレクトリにコピーする FileUtils.copy(tf.path, output_path)
実行すると、XLSXファイルをアップロードし、XLSXをPDFに変換して、PDFファイルをダウンロードします。
$ ruby sample.rb input.xlsx output.pdf $ file output.pdf output.pdf: PDF document, version 1.7, 1 pages (zip deflate encoded)
トラブルシューティング
CloudConvertはMicrosoft Officeを使っているはずですが、なぜかPC版のOfficeと結果が異なることがあります(言語やフォントの差か?)。
その場合は以下のような方法で原因を探ります。
- WEB画面から同じファイルをアップロードして変換してみる(APIと同じ変換をできる)
- 変換のパラメータを調整したり、変換元のファイルを修正してみる
しかしながら、経験上、見た目が崩れるときはパラメータをいじっても解決しません。おそらくXLSXファイルやDOCXファイルの内部状態が原因であり、ファイルを作り直してしまって解決することが多いようです。
We are hiring!
kickflow(キックフロー)は、運用・メンテナンスの課題を解決する「圧倒的に使いやすい」クラウドワークフローです。
サービスを開発・運用する仲間を募集しています。株式会社kickflowはソフトウェアエンジニアリングの力で社会の課題をどんどん解決していく会社です。こうした仕事に楽しさとやりがいを感じるという方は、カジュアル面談、ご応募お待ちしています!