excel ⇒ pdf のコマンドラインでの変換

サーバー上でexcel ⇒ pdf の変換をしたいと考えています。
libreoffice のコマンドラインでの変換を試したところ、フォーマットどおりに変換が行われず、
予期せぬ場所での改ページが発生してしまいます。



何か解決方法はあるのでしょうか?
よろしくお願い致します。


■コマンドライン

# soffice.bin --convert-to pdf --outdir libre_test/ --headless hoge.xlsx

headlessではなく通常の状態(GUI)からExcelファイルを開いてPDFに出力するとどうなりますか?
Linux版LibreOfficeではなくWindows版LibreOfficeで同じように変換をするとどうなりますか?

コマンドラインのオプションとしては(rootユーザーで出力しているのは気になりますが)特におかしなところも無く、考えられるのはフォントの違いからくるレイアウトの崩れぐらいなので、それぞれの環境で出力したPDFを比べて問題を切り分けるぐらいでしょうか。

以下、回答にならないボヤキ

まずExcelの挙動の推測から。

追記(2017-11-20): 少なくともExcel 2016は高さについて非常におかしいというか腐った計算をしている。

  1. A4横、ヘッダ・フッタなし、マージン全部0 拡大縮小なし等は下記の実験と同様。

  2. 標準フォントを「IPAexゴシック 10pt」とした。(要再起動)

  3. A1からA100に「あ1」から「あ100」までを並べる。

  4. ページレイアウト表示にする。

  5. 行の高さを調べる(0.45cm 17pixel)

  6. 何行まで1ページに入っているか確認→51行

  7. A4横のときの縦は210mm/51行だから4.11mm → 0.411cm!?

  8. 0.45 * 51 - 21 = 1.95cm はどこから調達した!?

  9. ちなみに 210 / 0.45 = 46.666であり、実際これをxlsxに保存して、LibreOfficeで印刷プレビューすると1ページ目に46行、2ページ目以降に残り。そう、これがあるべき姿だよね…。こんな状態だったら一致するわけないじゃない!

追記ここまで

  • 実験にあたっては、A4横、ヘッダの高さ、フッタの高さ、上下左右マージンを(特にExcelでは警告を無視して)0に設定。
  • A1からT1まで1から20までの数値をそれぞれ入力しておく。
  • プリンタには印刷できない領域があることが多く、上記警告は(おそらくプリンタドライバからの情報で)照らし合わせたときにその領域まで本文が侵食しようとするようなマージンを設定したときに出現する。
  • 手持ちのExcel 2016では、ファイルタブを選択したとき、サイドバーから「印刷」を選択することができる。この際、右側には印刷プレビューが表示されるが、このとき表示される画像は、上記の不正なマージン設定を無視し、プリンタ側の情報を用いる。
  • 問題把握を簡単にするため、それらが不正でない仮想プリンタとしてPrimoPDFをインストールし、これを基準に考えている。プリンタを切り替えるとプレビューが変わるのがわかるんじゃないかと。また、通常表示したとき、印刷できるページの区切りを表す点線も、これの影響を受ける。
  • さてファイルタブを選んだとき、オプション、基本設定でフォントサイズを10ptにしておく、かつ、念のため、詳細設定の「A4または8.5*11インチの用紙に合わせて内容を調整する」をOFFにした。後者は切り分けの手間を減らすため。
  • Windows 10では画面上では96DPIを標準とするらしく、何か設定項目が消えたとかそういう話も。よく言われてる72DPIがどうなったのかは知らない。このとき、セルの幅は8.43文字(64px)になる。仮に基本設定のフォントサイズを11ptに変更してから、Excelを終了し、新規作成すると、セルの幅が変わっている(8.38文字,72px)が、幅の規則性が正直よくわからない。 以下暫定資料。とりあえずテーマの話は無視して良い。
    https://support.microsoft.com/en-us/help/214123/description-of-how-column-widths-are-determined-in-excel
  • ところで、表示タブのブックの表示には「ページレイアウト」があり、実際にどう印刷されるか確認できるのだが、罫線やグリッドの有無によらず、何故か1.77cm(67pixel)となっている。なお、67[dots]/96[dots/Inch] * 2.54[cm/Inch] ≒ 1.7723[cm]
  • 実際印刷プレビューの内容としてはA4の横297mm / 17.7mm ≒ 16.77で16まで1ページで印刷される。
  • 297[mm] / (64[dots]/96[dots/Inch] * 25.4[mm/Inch]) ≒ 17.53ではない、ということだね。実際標準のときに全ての列が61pxになるようにすると、ページレイアウトで64pxで上記から17まで1ページで表示される。

LibreOfficeの場合はもっと簡単なようだ。

  • なんせ、単位が文字数でなく、幅の初期値が22.86mmという固定値で、Defaultスタイルのフォントサイズを変更しても幅は変化しないからだ。おそらく罫線等に影響されたりしない。各種マージンを0にして、ヘッダーとフッターをオフにして単純に297/22.86だろうなとか考えている。ただ、ヘッダーとフッターの値を0にはできないみたい。これが影響しているかどうかと、この最低値の選定理由は知らない。
  • もしかしたらLibreOffice付属のLiberation Sansが通常のExcel環境にないことを見越してxlsxファイルを作るとき、Expert ConfigurationのSubstFontsMSとかで置き換えられるかもしれないので、置き換えられないよう、適当なフォントを使って一応実験している。
  • で、上記で見てきたように1セルの幅の初期値(絶対値)はLibreOfficeとExcelと異なるし、セル数を基準にしているとトラブることは普通にあるかもしれない。
  • プリンタとかの前提が異なっていたりとかもあるのかな?LibreOfficeのオプションにLoad printer settings with the documentというのがあるが、影響するだろうか?未検証
  • 以上の情報を考慮して各々のアプリケーションでxlsxを保存し、コマンドライン経由でpdfに変換したらまぁ悪くなかったかな。

おまけ。

  • 自分の環境ではheadlessは不要だった。
  • outdirの指定時最後に\は不要だということに手間取る。次項のトラブルに巻き込まれ、切り分けに難航した。
  • 深い階層辿るの面倒だからってC:\とかを俺は使おうとするんだけど、このドライブ直下への書き込みも権限昇格が必要なようで、コマンドライン等で実行したとき、ファイルの競合回避用のファイルとpdfを作れなかった。そう思って、
    このファイルをデスクトップにドラッグドロップで移動させたのだが、このファイルをCalcに読み込ませようとするとUnknown Userにすでにロックされていると言われてしまった。何でだろう。紆余曲折・試行錯誤の末、ドラッグではなくコピーペーストしてコピー元のファイルを削除、ペースト先のファイルは普通に読み込める、という現象に巻き込まれた。どういうことだろう。
  • なんでわざわざ、A4「横」などと指定したのかというと、こういうのと同根だったりしないかなーと。A4縦だとLetterより短いから違和感を覚えにくいかなって思って並行実験してた。
    https://bugs.documentfoundation.org/show_bug.cgi?id=74861

Excel側で印刷時のページ設定で、「拡大縮小」のオプションを、拡大縮小ではなく、「ページ数に合わせて印刷」にして保存し、コンバートすると切れませんでした。私はこれで解決しました。