Officeがインストールされていない環境で、DelphiまたはC++BuilderからExcelワークシートをPDFにエクスポートするには、HotXLSのワークシートまたはワークブックでSaveAsPDFを呼び出します。HotXLSはネイティブのVCL Excelコンポーネントであり、そのワークシートからPDFへのエクスポート機能は、Excelの列幅とセルの表示テキストを自動マルチページ改ページ付きのA4ページにマッピングし、シートの使用領域を自己完結型のPDF 1.4ファイルとしてレンダリングします。Excel of コピー、プリンタードライバー、および外部DLLはレンダリングに関与しません
HotXLSはPDFをピクセル単位で正確なレンダリングエンジンとしてではなく、そのCSV、TSV、およびHTMLエクスポートパスの兄弟にあたるデータ提示形式として扱います。エクスポートは、グリッド内に表示される値、列の比率、セルの周囲のグリッド線などの表形式のコンテンツとレイアウトを再現します。この位置づけは、最初から適切な期待値を設定するために重要であり、この記事の残りの部分ではその具体的な境界線について説明します
OfficeなしでDelphiでExcelをPDFに変換する方法
最も簡単な方法は、1回呼び出すだけです。TXLSWorksheetはSaveAsPDF(FileName)とSaveAsPDF(Stream)を公開しており、TXLSWorkbookもアクティブシートに委譲する同じ2つのオーバーロードを公開しています。それぞれが成功時に1、失敗時に-1のIntegerを返すため、呼び出しを独自の例外処理でラップすることなく結果を分岐できます
uses
lxHandle;
var
Book: TXLSWorkbook;
begin
Book := TXLSWorkbook.Create;
try
Book.Open('sales-june.xlsx');
// Render the active sheet's used range straight to report.pdf.
if Book.SaveAsPDF('report.pdf') = 1 then
Writeln('PDF written');
finally
Book.Free;
end;
end;
ワークシートでSaveAsPDFを呼び出すと、HotXLSはそのシートのUsedRange(データが入力されているすべてのセルのバウンディングボックス)をエクスポートします。ワークブックのオーバーロードはアクティブシートに委譲する便利な機能であるため、複数シートのレポートでは、必要なシートをループするか、呼び出し前にアクティブシートを選択します。すべてのタブを結合するワークブック全体の一括処理モードはありません。各呼び出しで1つのシートまたは1つの範囲がレンダリングされます
HotXLSはどのようにして使用領域をPDFページに変換するのか
HotXLSは使用領域をセルごとにたどり、改ページされたグリッドとしてレイアウトします。列の形状はExcelから直接取得されます。各列幅はExcelの幅単位からタイポグラフィックポイントに変換され、列が極端につぶれないように最小限の底値が設定されます。すべての列を合わせた幅が使用可能なページよりも広い場合、HotXLSはそれらを均等に縮小して収めます。すでに収まっている場合は、シート全体に引き伸ばすことなく、自然な幅のままにします
次に、行は次の行が下部マージンを超えるまでページの下に向かって流れます。その時点でHotXLSは新しいページを開いて続行するため、1,000行のシートでも開発者が改ページの管理をすることなく自動的に改ページされます。すべてのセルは、数値形式が適用された後に生成される表示文字列であるFormattedTextを印刷するため、日付はシートに表示されている日付の通りに表示され、通貨セルは桁区切り文字と記号を保持します。列からはみ出したテキストは、隣のセルにこぼれることなく、セルの幅でクリップされます
方向、マージン、およびフォントサイズの制御
デフォルトのレイアウト以外の制御を行うには、エクスポーターを直接操作します。TXLSPDFExportは、1行のヘルパーの背後にあるクラスであり、Orientation(xlsPdfPortraitまたはxlsPdfLandscape、デフォルトはポートレート)、Margin(ポイント、デフォルトは40)、およびFontSize(ポイント、デフォルトは9)の3つのプロパティを公開しています。SaveAsPDFを呼び出す前にこれらを設定すると、ドキュメント全体に適用されます
uses
lxHandle, lxPDF;
var
Book: TXLSWorkbook;
Exporter: TXLSPDFExport;
begin
Book := TXLSWorkbook.Create;
try
Book.Open('wide-ledger.xlsx');
Exporter := TXLSPDFExport.Create;
try
Exporter.Orientation := xlsPdfLandscape; // fit wide sheets on the page
Exporter.Margin := 28; // tighter page margin, in points
Exporter.FontSize := 8; // denser rows
Exporter.SaveAsPDF(Book.ActiveSheet, 'ledger.pdf');
finally
Exporter.Free;
end;
finally
Book.Free;
end;
end;
TXLSPDFExportは、SaveAsPDF(Range: IXLSRange; ...)を通じてシート全体の代わりに対象範囲も受け入れることができます。これは、スクラッチ計算も保持しているシートからサマリーブロックだけをエクスポートする方法です。この範囲のオーバーロードは、ワークシートヘルパーが内部で使用しているものと同じであるため、レイアウト、スケーリング、および改ページの動作は、使用領域全体を渡す場合でも、手動で選択した範囲を渡す場合でもまったく同じになります
var
Book: TXLSWorkbook;
Exporter: TXLSPDFExport;
Summary: IXLSRange;
begin
Book := TXLSWorkbook.Create;
try
Book.Open('quarter.xlsx');
// Export only the summary block, not the scratch columns beside it.
Summary := Book.Sheets[1].Range['A1', 'F20'];
Exporter := TXLSPDFExport.Create;
try
Exporter.SaveAsPDF(Summary, 'summary.pdf');
finally
Exporter.Free;
end;
finally
Book.Free;
end;
end;
HotXLSがフォントを埋め込まない理由:HelveticaとWinAnsiのトレードオフ
HotXLSは、PDFに組み込まれているHelveticaとWinAnsiEncodingを使用してテキストを書き込みます。これは、明確な依存関係ゼロの選択ですが、1つの実質的な制限があります。Helveticaは、適合するすべてのPDFリーダーがすでに備えている標準の14個のフォントの1つであるため、エクスポーターはフォントプログラムを一切埋め込みません。これによりファイルサイズが小さく保たれ、ライセンスや配布の必要なくどこでも開くことができます。この選択の代償は、ページが表示できる文字セットにあります
WinAnsiEncodingはWindows-1252セットをカバーしているため、ラテン文字、一般的な句読点、および通常の西欧言語のアクセント記号は正しくレンダリングされ、HotXLSはいくつかの活版文字、カーリークォート、en/emダッシュ、ユーロ記号をCP1252のスロットに折り込みます。その範囲外の文字、つまりCJK文字、キリル文字、ギリシャ文字、およびアラビア文字は、ページ上で疑問符に崩れてしまいます。シートに非ラテンテキストが含まれている場合、このエクスポーターは適していないため、完全なスタイリングに対応したPDFレンダラーが適しています
ワークシートからPDFへのエクスポートの限界
HotXLSはコンテンツと構造をレンダリングしますが、シートの完全な視覚的スタイルはレンダリングしません。セルの塗りつぶし、境界線スタイル、セルごとのフォントや色、グラフ、および埋め込み画像はエクスポーターの描画対象外であり、均一なグリッド線を持つテキストグリッドが出力されます。これはHTMLおよびRTFエクスポーターが準拠しているものと同じルールであり、テーマではなく数値が意味を持つレポートやデータ引き渡しに適しています
スタイリッシュでブランドが一貫したドキュメントを作成することが目的の場合、通常はまずスプレッドシートテンプレートに数値を組み立てます。これについては、テンプレート駆動のレポート生成ワークフローで詳しく説明されています。また、COMや実行中のExcelインスタンスには一切関与しないため、このパイプラインはHotXLSが全体を通して使用しているのと同じOffice不要の自動化モデルに適合します。つまり、純粋なPascalであり、ヘッドレスサーバーにデプロイ可能で、ライセンスや保守の手間もありません
自己完結型PDF、バイト単位の精度
HotXLSはPDFファイルの構造を手作業で構築し、正確なバイトオフセットからクロスリファレンステーブルを計算します。これが、出力結果がすべてのリーダーで開く理由です。各オブジェクトをシリアル化する際、HotXLSはそのオブジェクトのバイトを追加する前に開始オフセットを記録し、書き込んだ長さだけ現在位置を進めます。これにより、xrefテーブルは各オブジェクトに正確に配置され、startxrefはそのテーブルの開始位置を示します。これらのオフセットが1バイトでもずれていると、リーダーはファイル全体を拒否するため、自己計算されたオフセットはエクスポーターの非常に重要な仕様になります
この動作には、知っておくべき厳密な結果が伴います。Pagesノードはオブジェクト1として最初に書き込まれますが、子ページのリストはすべてのページが出力されるまで確定しないため、HotXLSはプレースホルダーとして予約し、オフセットパスが実行される前に最終的な子ページとカウントを書き込みます(実行後は行われません)。オブジェクトのバイト数がxref用に測定されると、それらは固定されます。その後1バイトでも変更すると、それ以降のすべてのオフセットがずれ、テーブルが破損します。これは小さな規律ですが、下位ライブラリを使用せずに規格に準拠したPDF 1.4を実現するためのものです
ここで紹介したSaveAsPDFメソッドとTXLSPDFExportクラスは、CSV、HTML、RTFエクスポーター、およびDelphiとC++Builder用の完全なワークシートAPIとともに、HotXLS Delphi Excelコンポーネントに同梱されています