Reports Web Pure Python プログラマーズガイド/APIリファレンス
製品版のライセンス配置と load_license の使い方は、製品版を使い始めるをご覧ください。体験版では登録不要です。
Reports Web Pure Pythonは、ブラウザー内のWASMを使わず、Pythonだけで帳票を読み込み、データを差し込み、表示・保存・印刷するための帳票エンジンです。デスクトップアプリケーションにも、FastAPIなどのサーバー側Webアプリケーションにも組み込めます。
このガイドでは、次の処理を実装できるところまでを扱います。
- PREPD/PREPDJの帳票定義を読み、業務データを設定する
- 帳票全体を1つのPDFへ出力する
- SVG/PNGをページ単位で出力する
- 完成した帳票をPREPE/PREPEJとして保存し、再表示・再印刷する
- デスクトップでプレビュー・印刷する
- Web APIからPDF、ページ単位のSVG、PREPEJを配信する
画面の使い方は、Pure Python デザイナー操作ガイドとPure Python プレビュアー操作ガイドを参照してください。
1. 最初に理解する3つのデータRM001
帳票は「レイアウト」と「値」を分けて扱います。
| データ | Pythonでの表現 | 内容 |
|---|---|---|
| 帳票定義 | ReportDocument |
用紙、文字、罫線、画像、バーコード、繰返しなどのレイアウト |
| 印刷時の値 | dict[str, Any] |
顧客名、日付、金額、商品明細など、帳票へ差し込む値 |
| 完成した印刷データ | PrintDataPackage |
帳票定義と値をページ単位で保持し、後から再表示・再印刷できるデータ |
| 拡張子 | 内容 |
|---|---|
.prepdj |
JSON形式の帳票定義 |
.prepd |
従来形式の帳票定義 |
.prepej |
JSON形式の完成した印刷データ |
.prepe |
従来形式の完成した印刷データ |
基本の流れは、load_report()で定義を読み、Pythonの辞書へ値を入れ、Rendererで出力する、という3段階です。
2. 開発を始めるRM002
2.1 動作環境とインストールRM003
- Python 3.10~3.14(サンプルの推奨環境はPython 3.13)
- PDF、SVG、PNGをサーバーで生成するだけなら、画面を開く必要はありません
- デザイナー、プレビュアー、プリンター出力にはPySide6を使用します
- PDFはパソコンに入っている日本語フォントで作ります。Linuxでは、Noto Sans CJK JPなどの日本語フォントをインストールしてください。日本語フォントがないとPDFを出力できません
ZIPを全体ごと展開し、Native/Pure-Python フォルダーで端末を開きます。同梱SDKをサンプルとは別にインストールする場合の例です。
py -3.13 -m venv .venv
.\.venv\Scripts\python.exe -m pip install ./SDK
macOS/Linuxでは同じフォルダーで次を実行します。
python3 -m venv .venv
.venv/bin/python -m pip install ./SDK
先に動くサンプルを見たい方は、samples/01.あっという間に帳票出力/README.html に沿って進めてください。サンプル専用の仮想環境とSDKの導入手順をまとめています。どちらの場合も、初回の依存パッケージ取得にはインターネット接続が必要です。
2.2 主な公開APIRM004
通常はpao_reportsから次の名前をインポートします。
| API | 役割 |
|---|---|
load_report() / save_report() |
帳票定義ファイルの読み書き |
loads_report() / dumps_report() |
文字列と帳票定義の相互変換 |
ReportDocument / ReportObject |
帳票と配置オブジェクトのモデル |
ObjectType / BarcodeKind |
オブジェクト種別とバーコード種別 |
Renderer / RenderOptions |
PDF、SVG、PNG、印刷の出力 |
page_count() |
帳票の物理ページ数を取得 |
save_print_data() / load_print_data() |
PREPE/PREPEJの読み書き |
RenderControl / RenderCancelled |
進捗通知と処理中止 |
PreviewCache |
ページ画像とSVGの再利用 |
3. 最初の帳票プログラムRM005
01のサンプルを動かせたら、そのフォルダーに first_report.py というファイルを作り、以下を貼り付けます。同梱の帳票定義にタイトルと会社名を入れ、1ページのPDFを作る完全な例です。01の quick_report.py は残したままで構いません。
from pathlib import Path
from pao_reports import Renderer, load_report
root = Path(__file__).resolve().parent
definition = load_report(root / "definition" / "quick-report.prepdj")
values = {
"Title": "はじめてのPython帳票",
"CustomerName": "株式会社サンプル",
}
# 帳票内のオブジェクト名と、辞書のキーを対応付けます。
for item in definition.objects:
if item.name in values:
item.binding = item.name
output = root / "output" / "first-report.pdf"
output.parent.mkdir(parents=True, exist_ok=True)
Renderer().render_pdf(definition, values, output)
print(f"作成しました: {output}")
01で準備した仮想環境を使い、同じフォルダーで実行します。
.\.venv\Scripts\python.exe first_report.py
macOS/Linuxは .venv/bin/python first_report.py です。output/first-report.pdf を開き、タイトルと会社名を確認してください。
ReportObject.binding と辞書のキーが一致すると、その値が表示されます。この例はコードで対応付けています。すでにデザイナーでデータ項目を設定した定義なら、その設定に合わせて辞書を作ればよく、ループでの対応付けは不要です。
以下の章は目的別の抜粋です。definition・values はこの章で作ったもの、DB接続などは利用するアプリで用意したものとして説明します。実際の請求書と明細データを使った完成例は02~04のソースをご覧ください。
4. 印刷データを設定するRM006
4.1 固定項目と明細RM007
文字の枠からのあふれと、明細行がページからあふれる処理は別です。通常文字は枠の寸法・横書き/縦書き・折返しの設定で配置します。長い文字だけで自動改ページはしません。伸縮文字は文字数・バイト数の条件を満たすと枠に合わせて変形し、高さ固定なら横方向を伸縮します。PDF 専用の自動折返し・高さによる切取りは、その設定を使う出力経路に適用されます。書体で字幅・行送りが変わるため、最長の値で画面と PDF を確認してください。
顧客名や発行日のような値は、そのまま設定します。繰返し明細はリストで渡します。
values = {
"伝票番号": "INV-2026-0012",
"顧客名": "株式会社サンプル",
"商品名": ["商品A", "商品B"],
"数量": [2, 1],
"単価": ["50,000", "20,000"],
}
同じ添字の値が同じ明細行に対応します。repeat の回数を超えた行も同じ間隔で、同じページの枠の下へ続けて描きます。Renderer と save_print_data は用紙を越えた分を次ページへ送ります。固定の欄(宛名・合計など)は各ページに同じ値を描きます。合計を最後のページだけに出すには、ページごとに値を分けて Report API で書きます。
Report.add_page → SavePDF は自動改ページをせず、用紙外は切れます。利用側でページを追加してください。
日付、金額、単位など、業務上の表示形式を固定したい場合は、Python側で文字列へ整形してから渡すと意図が明確になります。
4.2 DBの検索結果を対応付けるRM008
rows = connection.execute(
"select product_name, quantity, unit_price from invoice_line "
"where invoice_id = ? order by line_no",
(invoice_id,),
).fetchall()
values = {
"商品名": [row[0] for row in rows],
"数量": [row[1] for row in rows],
"単価": [f"{row[2]:,.0f}" for row in rows],
}
DBの列名を帳票へ暗黙に渡すのではなく、この箇所で帳票項目名へ明示的に対応付けると、DB変更の影響を限定できます。
4.3 画像を差し替えるRM009
画像オブジェクトにbindingがある場合、そのキーへ画像ファイルのパスを渡せます。
values["社印画像"] = str(Path("images/company-seal.png").resolve())
Web APIの利用者から任意のパスやURLを受け取って、そのまま画像として開かないでください。アプリケーション管理下の画像へ対応付ける設計にします。
4.4 空文字で罫線・図形を消すRM010
罫線・四角・円(Line、DynamicLine、Square/Rectangle、Circle/Ellipse)は、値で表示を切り替えられます。
| 書く値 | 罫線・図形 |
|---|---|
""(空文字) |
描かない(消える) |
None、または何も書かない |
定義どおり描く |
""以外の値(例 "1") |
描く。値は表示には使わない |
繰返しの行でも、1つだけの図形でも同じです。最初に書いたときも、別の値のあとに書いたときも同じです。表の行を途中で終える、合計行の上だけ線を引かない、条件で枠を消す、などに使います。次の明細線は、定義にある罫線のオブジェクト名の例です。
values["明細線"] = [None, None, ""] # 3行目の罫線だけ消す
PREPEJへ保存した印刷データでも同じです。図形の値が""なら、Drawingがtrueでも描きません。
文字の欄(Text)は別の規則です。値が""またはNoneなら、文字も枠線も背景色も描きません。SVG・印刷・PDFで同じです。
4.5 何も書かない繰返しは1行目だけ描くRM011
繰返し(RepeatCountが2以上)のある物体に、そのページで何も書かないと、定義どおり1つだけ、1行目の位置に描きます。行の数だけ並べては描きません。
一部の行にだけ書くと、書いた行だけ描きます。書かなかった行は描きません。1行目に書かなければ、1行目も描きません。
表の罫線や枠を全部の行に描くには、描きたい行それぞれにNone(値なし)を書きます。罫線・図形はNoneなら描き、""なら消えます(4.4)。次は、明細の行数ぶん明細線にNoneを書く例です。
values["明細線"] = [None] * len(rows) # 明細の行数ぶん、罫線を描く
文字の欄は、Noneを書くとその行の文字が空になります。定義の文字を出したい行には、その文字を書きます。PREPEJへ保存した印刷データでも同じです。
5. PDF、SVG、PNGを出力するRM012
5.1 PDFは帳票全体を1ファイルへ出力するRM013
平成書体を指定した文字の太字・斜体は、PDF では合成して描きます。
from pao_reports import Renderer, RenderOptions
renderer = Renderer(RenderOptions(dpi=150))
renderer.render_pdf(definition, values, Path("output/report.pdf"))
render_pdf()は、繰返しで生じたページを含む帳票全体を、1つの複数ページPDFへ出力します。pathを省略するとPDFのbytesを返します。
PDFに使えるフォントに字形のない文字(絵文字など)があると、文字を黙って消さずにValueError(PDF_GLYPH_MISSING: ...)を送出します。このときPDFファイルは作られません。
5.2 SVGはページ単位RM014
render_svg_pages は SVG 文字列のリストを返します。出力先を指定した場合は、その下にも page-1.svg などを保存します。
renderer.render_svg_page(
definition, 0, values, Path("output/page-1.svg")
)
ページ番号は0から始まります。全ページをページ別ファイルへ保存する場合は、出力ディレクトリを指定します。
svg_directory = Path("output/svg-pages")
svg_directory.mkdir(parents=True, exist_ok=True)
svg_pages = renderer.render_svg_pages(
definition, values, svg_directory
)
ファイル名はpage-1.svg、page-2.svgのようになります。render_svg()もRenderOptions.pageで指定した1ページだけを返すAPIです。SVGが帳票全体を1ファイルへまとめるAPIではない点に注意してください。
5.3 PNGもページ単位RM015
png_directory = Path("output/png-pages")
png_directory.mkdir(parents=True, exist_ok=True)
images = renderer.render_png_pages(
definition, values, png_directory
)
PNGはpage-1.png、page-2.pngのようにページ単位で保存され、戻り値はPillowの画像オブジェクトのリストです。1ページだけならRenderOptions(page=0)とrender_png()を使用できます。
5.4 ページ数を先に調べるRM016
from pao_reports import page_count
count = page_count(definition)
for page_index in range(count):
renderer.render_svg_page(
definition,
page_index,
values,
Path(f"output/page-{page_index + 1}.svg"),
)
6. PREPEJへ保存し、もう一度出力するRM017
PREPEJ の共通属性は横揃えを Left・Center・Right、縦揃えを Top・Middle・Bottom と書きます。大文字の旧表記も読み込みます。WPF/.NET は大小だけの違いを補正して知らせ、未知の値は適用せずに知らせます。
読み込んだページの definition は値を適用済みです。Report.add_page(page.definition, page.values) でもそのまま描きます。値を差し替えるには元の帳票定義へ新しい値を書きます。日付・時刻・Decimal は str にして描画・保存します。それ以外の未対応型は保存でエラーになります。同じ定義は共有して保存します。
PREPEJは帳票定義と値を含む自己完結した印刷データです。元のPREPDJやDBがなくても、保存した時点の帳票を再表示できます。
from pao_reports import load_print_data, save_print_data
saved = save_print_data(
definition, values, Path("output/invoice.prepej")
)
package = load_print_data(saved)
page = package.pages[0]
if page.definition is None:
raise ValueError("帳票定義を含む印刷データが必要です")
Renderer().render_pdf(
page.definition, page.values, Path("output/invoice-again.pdf")
)
load_print_data()はPrintDataPackageを返し、そのpagesにPrintedPageが入ります。複数のPrintedPageを持つファイルは、各ページのdefinitionとvaluesを組にしたまま扱ってください。付属プレビュアーもこの組を保って再表示します。
.prepeを指定すれば従来XML形式、.prepejを指定すればJSON形式で保存します。
7. デスクトップアプリケーションで使うRM018
7.1 ページ画像を独自画面へ表示するRM019
from pao_reports import QtPreviewSurfaceRenderer
surface = QtPreviewSurfaceRenderer().render_page(
definition, values, 0, dpi=96, background="#FFFFFF"
)
qimage = surface.image
QtPreviewSurfaceRenderer.render_page()はQtPageSurfaceを返します。imageはQImage、widthとheightは生成画像のピクセル寸法です。用紙寸法は元のReportDocument.width_mmとheight_mmを参照します。Qtを使わない画面では、Renderer.render_png()が返すPillow画像を利用できます。
付属プレビュアーの開く、保存、検索、ページ移動、表示倍率についてはプレビュアー操作ガイドを参照してください。
7.2 プリンターへ出力するRM020
from PySide6.QtGui import QGuiApplication
from pao_reports import Renderer
app = QGuiApplication.instance() or QGuiApplication([])
Renderer().print_document(definition, values)
印刷はPySide6のQtPrintSupportを使用し、呼出側がメインスレッド上のQGuiApplicationを所有している必要があります。プリンター名を指定する場合はprinter_name=を使います。独自のQPrinterを渡す場合はprinter=を使います。
Renderer().print_document(
definition, values, printer_name="Office Printer"
)
printer=とprinter_name=を同時には指定できません。物理印刷の可否はOS、ドライバー、プリンター設定にも依存するため、実機で確認してください。
7.3 デスクトップの操作UIを外側から隠すRM021
02/04 Clientに同梱した PreviewWindow を利用する場合は、QtのUIスレッドから次のように操作できます。preview は作成済みの PreviewWindow です。
preview.set_preview_chrome_visible(False) # 帳票だけにする
preview.set_preview_chrome_visible(True) # 全ツールバー・メニュー・ステータス・ページ一覧を表示
通常の初期表示は変わりません。設定ボタンも隠れるので、再表示はアプリ側のボタンから行います。これは同梱サンプルWindowの公開メソッドであり、エンジンSDKの独立したUIコントロールではありません。OSのウィンドウ枠は残ります。既存の set_toolbar_visible は補助ツールバーだけを切り替えるため、帳票だけにする場合は上のメソッドを使用してください。Web用APIとは分けて考えます。
8. Webアプリケーションで使うRM022
Pure Python版は、サーバーで帳票を生成し、PDFまたはページ単位のSVG/PNGをHTTPレスポンスとして返します。ブラウザーの中でPythonエンジンを実行する方式ではありません。
03のREADMEに従って依存パッケージを導入した後、03フォルダーに first_api.py を作ります。以下は、01の帳票定義を使い、PDFを返す小さなWeb APIを追加する例です。既存の app.py は変更しません。
from pathlib import Path
from fastapi import FastAPI, Response
from pao_reports import Renderer, load_report
app = FastAPI()
root = Path(__file__).resolve().parent
definition = load_report(
root.parent / "01.あっという間に帳票出力" / "definition" / "quick-report.prepdj"
)
for item in definition.objects:
if item.name in ("Title", "CustomerName"):
item.binding = item.name
def report_values() -> dict:
return {"Title": "PythonからWeb配信", "CustomerName": "株式会社サンプル"}
@app.get("/api/report.pdf")
def report_pdf() -> Response:
body = Renderer().render_pdf(definition, report_values())
return Response(body, media_type="application/pdf")
03フォルダーの端末で実行します。既存サンプルと区別するため8767番を使います。
.\.venv\Scripts\python.exe -m uvicorn first_api:app --host 127.0.0.1 --port 8767
macOS/Linuxは先頭を .venv/bin/python にします。起動ログを確認して http://127.0.0.1:8767/api/report.pdf を開きます。終了はCtrl+Cです。
ページ単位のSVGも返すには、同じ first_api.py の末尾へ次を追加し、サーバーを再起動します。
from fastapi import HTTPException
from pao_reports import Renderer, page_count
@app.get("/api/report/{page}.svg")
def report_svg(page: int) -> Response:
if page < 0 or page >= page_count(definition):
raise HTTPException(404, "ページがありません")
body = Renderer().render_svg_page(definition, page, report_values())
return Response(body, media_type="image/svg+xml")
1ページ目は http://127.0.0.1:8767/api/report/0.svg です。この例は1ページなので /1.svg は404を返します。PDFとSVGには同じ値を渡しています。
公開APIでは、認証・認可、入力文字数、明細件数、要求サイズ、生成時間、同時実行数、最大ページ数を制限してください。
8.1 付属WebサンプルRM023
samples/03.全帳票をWebでプレビュー を開き、そのREADMEに従って仮想環境と依存パッケージを準備します。準備後、同じフォルダーで起動します。
.\.venv\Scripts\python.exe app.py
macOS/Linuxは .venv/bin/python app.py です。起動ログの Uvicorn running を確認してから http://127.0.0.1:8765/ を開きます。Dockerからの起動も同じREADMEで案内しています。主なAPIは次のとおりです。
| API | 内容 |
|---|---|
GET /api/samples |
公開サンプル一覧 |
GET /api/reports/{id}/svg?page=0 |
指定ページのSVG |
GET /api/reports/{id}/pdf |
帳票全体のPDF |
GET /api/reports/{id}/data |
自己完結PREPEJ |
POST /api/print-data/svg?page=0 |
PREPEJから指定ページのSVGを生成 |
POST /api/print-data/pdf |
PREPEJから帳票全体のPDFを生成 |
GET /health |
稼働状態とエンジン識別子 |
SVG・PDF応答のX-Reports-Engine: PurePythonで、Pure Pythonエンジンが生成したことを確認できます。
8.2 アプリ側からプレビュアーを操作するRM024
帳票だけを業務画面に置き、PDFや検索は自分のアプリのボタンから操作したい場合に使うインターフェースです。ツールバーを隠しても、プレビュアーの機能は停止しません。 設定ボタンまで隠せるため、再表示用のボタンはプレビュアーの外側に置きます。
03「全帳票をWebでプレビュー」と公開デモは、この使い方の実例です。最初はプレビューだけを表示し、帳票選択の横の「ツールバーを表示」を押すとPDF・検索・設定などを表示します。もう一度押すと、設定ボタンとステータスも含めて非表示になります。
表示・非表示を切り替えるコード
以下は03サンプルのプレビュアーを読み込んだ後に置く、アプリ側のコードです。サンプルの native-previewer.js、native-previewer.css、画面の初期化部分を一緒に利用してください。03を編集する場合は、既存の同じボタン・切り替え処理を置き換え、二重に追加しないでください。
<!-- プレビュアーの外側に置くアプリ側のボタン -->
<button type="button" id="togglePreviewToolbar"
aria-controls="nativePreviewer" aria-expanded="false">
ツールバーを表示
</button>
// native-previewer.js の読み込み後に実行します。
const previewer = window.ReportsWebNative;
const button = document.getElementById("togglePreviewToolbar");
function updateButton() {
const visible = previewer.getState().chrome.toolbar;
button.textContent = visible
? "ツールバーを非表示" : "ツールバーを表示";
button.setAttribute("aria-expanded", String(visible));
}
button.addEventListener("click", () => {
if (previewer.getState().chrome.toolbar) previewer.hideAll();
else previewer.showAll();
});
const unsubscribe = previewer.subscribe("chrome-changed", updateButton);
previewer.hideAll(); // 初期画面は帳票だけ
updateButton();
// アプリ側の画面を破棄する場合は unsubscribe() で購読を解除します。
03サンプルでは、プレビュアーを初期化する前の ReportsNativeConfig に externalChromeControl: true を指定しています。この設定では、内部設定から全非表示にした場合も、設定を戻すための小さなボタンをプレビュアー内に残しません。必ず上のような外部ボタンを用意してください。chrome-changed を購読すると、内部設定から切り替えた場合も外部ボタンの文字が追従します。
ツールバーがなくても、PDF・検索・ページ移動を使える
await previewer.showPdfPreview(); // サーバーへPDFを要求し、同じ表示領域へ表示
await previewer.showSvgPreview(); // 通常の印刷プレビューへ戻る
previewer.goToPage(2); // ページ番号は1から
previewer.setZoom("auto"); // 表示領域に合わせた倍率
previewer.search("請求"); // 通常の印刷プレビュー内を検索
ここでの showSvgPreview() はAPI名であり、利用者に見せるボタン名は「印刷プレビュー」で構いません。PDF表示中の検索などはブラウザー内蔵PDFビューアーの機能と区別します。非表示のままPDF表示へ切り替えることもできます。プレビューを最初に開いただけではPDFを要求しません。
| API | 用途・注意 |
|---|---|
hideAll() |
設定・ステータスを含む操作UIを一括非表示にする。開いている設定ダイアログも閉じる |
showAll() |
全コマンドを表示する。以前の個別表示設定を復元する操作ではない |
getState() |
現在のページ・倍率・表示設定などの状態を取得する |
subscribe("chrome-changed", handler) |
表示設定の変更を受け取る。戻り値は購読解除用関数 |
setChrome({commands: {print: false}}) |
印刷など特定のコマンドだけを隠す |
showPdfPreview() / showSvgPreview() |
PDF表示/通常プレビューへ切り替える。切り替え処理は await で待てるが、ブラウザー内蔵PDFビューアーの読込完了を保証するものではない |
print() / savePrintData() / openPrintData() |
印刷・PREPEJ保存・PREPEJを開く。自分のボタンのクリックから呼び出す |
非表示の対象はReports Webの操作UIです。PDF表示中にブラウザー内蔵PDFビューアーが表示する独自のボタンは、このAPIの制御対象ではありません。
このインターフェースは、3つのNative Webサンプルで使うブラウザー側の ReportsWebNative です。サーバーの帳票エンジンのクラスや、デスクトップ用Windowとは別です。WASM版にも一括表示・非表示の機能がありますが、初期化方法やAPIの所属はWASM版のガイドを参照してください。
9. 長い処理を中止し、進捗を受け取るRM025
from pao_reports import RenderCancelled, RenderControl, Renderer
def progress(done: int, total: int) -> None:
print(f"{done}/{total}")
control = RenderControl(progress=progress)
renderer = Renderer(control=control)
try:
renderer.render_pdf(definition, values, Path("output/report.pdf"))
except RenderCancelled:
print("帳票生成を中止しました")
別スレッドなどからcontrol.cancel()を呼ぶと、次のチェックポイントでRenderCancelledが送出されます。同じRenderControlを再利用すると中止状態も引き継がれるため、処理単位で作成してください。
10. キャッシュを利用するRM026
from pao_reports import PreviewCache, Renderer
cache = PreviewCache(limit=16)
renderer = Renderer(cache=cache)
image = renderer.render_png(definition, values)
same_image = renderer.render_png(definition, values)
cache.clear()
同じ帳票定義、データ、描画設定のプレビューを繰り返す場合に利用できます。変更可能なデータを複数リクエストで共有せず、業務要求ごとに辞書を新しく作ってください。
11. モデルAPIリファレンスRM027
11.1 ReportDocumentRM028
主な属性は次のとおりです。寸法の単位はmmです。
| 属性 | 内容 |
|---|---|
title |
帳票名 |
width_mm, height_mm |
用紙の幅と高さ |
paper_size |
A4などの用紙名。はがきはPOSTCARD、任意寸法はCUSTOM |
grid_mm |
デザイナーのグリッド間隔 |
show_grid, snap_to_grid |
グリッド表示と吸着 |
default_font_family, default_font_size_pt |
既定フォント |
is_inch |
用紙サイズの編集表示をインチにする。内部の寸法はmmのまま |
design_color |
新規オブジェクトの文字・線の既定色。背景色ではない |
default_stroke_width, default_stroke_style, default_dash_pattern |
新規オブジェクトの既定線幅・線種・破線パターン |
display_repeat_objects, repeat_object_color |
デザイナーの繰返し補助表示。印刷内容には加えない |
background_x, background_y, background_width, background_height |
帳票背景画像の位置・寸法。幅・高さ0は用紙寸法 |
background_image_path, background_image_data_base64 |
背景画像のファイルまたは埋込データ |
background_image_size_mode, background_image_position |
背景画像のサイズ方法・配置位置 |
objects |
ReportObjectの一覧 |
extensions |
互換性維持用の拡張情報 |
to_dict() |
JSON化できる辞書へ変換 |
11.2 ReportObjectRM029
図形の塗りは fill_enabled=True と fill_color を指定します。fill_style は None のままで構いません。通常文字には輪郭幅は効かず、伸縮文字に効きます。
| 分類 | 主な属性 |
|---|---|
| 種別と名前 | type, name, binding, text |
| 位置と大きさ | x, y, width, height, rotation |
| 繰返し | repeat, repeat_x, repeat_xy_both, interval_x, interval_y |
| 文字 | font_family, font_size_pt, font_unit, bold, italic, underline, strikeout, text_vertical, text_elastic |
| 条件付き伸縮 | fixing_font_height, elastic_over_characters, elastic_over_bytes |
| 均等割り付け | justify, justify_half_width, justify_half_width_kana, justify_excluded_characters, auto_justify_ends, end_space_count |
| PDF専用設定 | pdf_auto_wrap, pdf_clip_overflow, pdf_font_family |
| 配置 | horizontal_alignment, vertical_alignment |
| 色と枠 | text_color, fill_color, fill_enabled, stroke_color, stroke_width, stroke_style |
| 図形 | fill_style, hatch_density, line_type, line_thickness, corner_radius |
| 画像 | image_path, image_data_base64, image_size_mode, image_alignment, image_reverse。クリップは画像を縮めずに、1 ピクセルを 1/96 インチとして置きます。枠からはみ出した部分も描かれます。 |
| バーコード | barcode_kind, barcode_draw_mode, barcode_text_visible, barcode_justify, qr_error_correction, qr_version |
| バーコードの文字・補正 | barcode_text_font_family, barcode_text_font_size_pt, barcode_black_bar_adjuster_by_dot, barcode_white_bar_adjustment, postal_customer_point。黒バー・白バー補正の単位は出力先の 1 ドット(PDF では 1/600 インチ、PNG では 1 ピクセル) |
| 二次元コードの詳細 | data_matrix_code_size, pdf417_size_kind, pdf417_rows, pdf417_columns, pdf417_error_level, pdf417_auto_error_level, pdf417_aspect_ratio |
| 状態 | visible, locked, extensions |
resolved_text(data, repeat_index)は、bindingに対応する値を取得します。通常はRendererが内部で呼ぶため、業務コードから直接呼ぶ必要はありません。
文字サイズの単位はfont_unitで指定します。通常はPointです。従来定義のWorld、Display、Pixel、Inch、Document、Millimeterも読み込み、出力時の解像度に合わせて換算します。font_size_ptという属性名でも、font_unitを変更した場合はその単位の数値になります。
伸縮はtext_elastic=Trueで有効になります。elastic_over_charactersまたはelastic_over_bytesを指定すると、その長さを超えた場合だけ伸縮します。同じ長さでは通常表示、0は条件なしです。文字数はUTF-16の単位数、バイト数はCP932(Shift_JIS)で数えます。デザイナーでは文字数とバイト数の一方を設定すると他方を解除します。fixing_font_height=Trueでは指定フォントの高さを保って横方向を合わせます。
justify=Trueは通常文字の均等割り付けです。半角英数字・半角カナを対象から外した場合や、除外文字を指定した場合は、その連続部分を一まとまりで配置します。伸縮とは別の機能であり、デザイナーでは同時に有効にしません。
PDFの折返し・切取りはpdf_auto_wrap・pdf_clip_overflow、専用フォントはpdf_font_familyで設定します。通常プレビューの設定は変えません。PDFの折返しは、半角を1、全角を2として数えた字数で行を区切ります。pdf_clip_overflowは高さだけを切り、横へははみ出します。
縦書き(text_vertical)の文字が枠に入らないとき、プレビュー・SVG・PNGでは枠の高さに入る字数ごとに左から右へ列を折り返し、枠で切ります。PDFでは、縦の配置が上のとき、1列のまま枠の下へはみ出します。バーコード下の文字だけを変える場合はbarcode_text_font_family・barcode_text_font_size_ptを指定します。空文字・0なら通常フォントを使用します。
11.3 RenderOptionsRM030
| 属性 | 既定値 | 内容 |
|---|---|---|
dpi |
150 | PNG描画などの解像度 |
background |
#FFFFFF |
ページ背景色 |
page |
0 | render_png()、render_svg()で出力する0始まりのページ |
11.4 特定ページ・行・項目だけを変更するRM031
ReportPageBuilder は操作する対象の名前が一意なら使えます。他の物体の名前が重複していても構いません。
図形の塗りは fill_enabled=True と fill_color を指定します。fill_style は None のままで構いません。通常文字には輪郭幅は効かず、伸縮文字に効きます。
ReportPageBuilderは、帳票定義をコピーし、1ページ分の繰返しを展開してから、指定した項目の属性を変更するためのクラスです。フォント専用ではなく、文字色、位置、罫線、表示・非表示など、通常のReportObject属性を変更できます。
from pao_reports.page_builder import ReportPageBuilder
pages = []
for page_number in range(1, 4):
builder = ReportPageBuilder(definition)
if page_number == 2:
# オブジェクト名が「金額」の5行目だけを変更します。行番号は0始まりです。
target = builder.object("金額", 4)
target.font_size_pt = 12
target.font_unit = "Point"
target.text_color = "#0000FF"
pages.append(builder.build())
この例では、definitionに「金額」という名前の項目があり、1ページ内で5行以上繰り返す設定になっているものとします。build()したページは独立したコピーです。後からBuilderを変更しても、元の定義、生成済みのページ、別ページには反映されません。
| 指定方法 | 対象 |
|---|---|
builder.object("金額") |
最初の1件 |
builder.object("金額", 4) |
5行目の1件 |
builder.cell("ラベル", 1, 2) |
XY繰返しの2列目・3行目の1件 |
名前の重複、存在しない項目、範囲外の行・列はエラーになります。XY繰返しにはcell()を使用してください。生成したページはRenderer.render_pdf(pages[0], page_documents=pages)で1つのPDFに出力できます。
12. 読み書きAPIリファレンスRM032
from pao_reports import dumps_report, loads_report, save_report
text = dumps_report(definition, format="json", indent=2)
copy = loads_report(text, format="json", source_name="invoice.prepdj")
save_report(copy, Path("output/invoice.prepdj"))
load_report()とsave_report()は拡張子に応じてJSONまたは従来XMLを扱います。文字列APIではformat="json"またはformat="prepd"を明示できます。
装飾文字(ArtText)は表示・編集せず、読み込み時にお知らせします。元の内容を保持し、共通 JSON にも保存します。WPF 版では作成・描画できます。
入力ファイルは信頼できるものに限定し、公開アップロードではファイルサイズ、オブジェクト数、画像データ量を検証してください。
13. エラー処理と安全性RM033
帳票にない名前の値は ValueError です。物体名かデータ項目名を指定してください。save_print_data にも不明な名前の値は保存されません。Objects がない定義や壊れた定義は日本語の ValueError、存在しないファイルは日本語の FileNotFoundError になります。
from json import JSONDecodeError
from pao_reports import RenderCancelled
try:
definition = load_report(definition_path)
Renderer().render_pdf(definition, values, output_path)
except FileNotFoundError:
# 帳票定義や参照画像が見つからない
...
except (ValueError, JSONDecodeError):
# 入力形式や値が不正。PDFに出せない文字(PDF_GLYPH_MISSING)を含む
...
except RenderCancelled:
# 利用者またはアプリケーションが中止した
...
except OSError:
# 読み書き、保存先、OS資源に関する失敗
...
- 入力された任意のローカルパスやURLを画像として参照させないでください。
- 出力先をアプリケーション管理下に限定してください。
- 一時ファイルは
TemporaryDirectoryなどで確実に破棄してください。 - Web APIでは内部例外をそのまま応答せず、要求IDとともにサーバーログへ記録してください。
- 帳票で使うフォントを本番環境にも配置し、文字幅、改行、PDF表示を確認してください。
14. 目的別の早見表RM034
| やりたいこと | 参照章 | 主なAPI |
|---|---|---|
| 最初のPDFを作る | 3、5.1 | load_report, Renderer.render_pdf |
| 明細を差し込む | 4.1 | dict, ReportObject.binding |
| ページ別SVGを作る | 5.2 | render_svg_page, render_svg_pages |
| ページ別PNGを作る | 5.3 | render_png, render_png_pages |
| 完成帳票を保存・再読込する | 6 | save_print_data, load_print_data |
| 独自プレビューへ組み込む | 7.1 | QtPreviewSurfaceRenderer |
| プリンターへ出力する | 7.2 | Renderer.print_document |
| Webから帳票を返す | 8 | Renderer, FastAPI Response |
| 処理を中止する | 9 | RenderControl, RenderCancelled |
| モデル属性を確認する | 11 | ReportDocument, ReportObject |
15. 付属サンプルを実行するRM035
ZIP内の Native/Pure-Python/samples/README.html がサンプルの入口です。使いたい番号フォルダーをエディターやIDEで開き、その中のREADMEを読みます。
| 番号フォルダー | 学ぶこと |
|---|---|
01.あっという間に帳票出力 |
短いコードでPDF・ページ単位SVG/PNG・PREPEJを作る |
02.全帳票をパソコンでプレビュー |
SQLiteのデータから請求書などを作り、PCで表示・出力する |
03.全帳票をWebでプレビュー |
Pure PythonエンジンをWebアプリで使う |
04.Web API・デスクトップ連携 |
RESTサーバーで作った印刷データを、PCのプレビュアーへ渡す |
各READMEには、仮想環境の準備、実行コマンド、読むソース、編集する箇所、停止方法があります。製品開発用の engine フォルダーをPYTHONPATHへ追加する必要はありません。同梱の SDK を使います。
03のWebアプリと04のRESTサーバーは、直接起動とDocker起動の両方を用意しています。04のデスクトップ画面はPC側で直接起動します。最初は01のタイトルや会社名を変更して、出力結果に反映されることを確かめてください。
16. Report 互換 APIRM036
from pao_reports import Report
report = Report()
report.load_def_file("invoice.prepdj")
report.add_page(values={"field2": ["商品A", "商品B"]})
report.CutByPage = False
report.SwapPdfImage = True
report.SavePDF("output.pdf")
名前は帳票の物体名に合わせます。繰返し回数を超えた行も同じページの下へ続けます。用紙外は切れるので、必要なページは add_page で追加します。
pao_reports.Report は状態型 API を提供します。LoadDefFile(stream, definitionName) は呼出側の stream を閉じず、複数の定義名を保持します。ページ作成前の GetDefFileName(page) は1始まりです。ページ作成後は、page値にかかわらず最初の定義名を返します。
SaveData() は従来形式(.prepe)の zlib/XML 印刷データを返し、LoadData() で再読込できます。CutByPage の既定値は False で、True の場合は選択範囲・部数・順序・照合を決定した後、物理プリンターへ1ページずつ別ジョブとして送ります。レイアウト変更やカッター命令は追加しません。
LoadData(payload, max_expanded_bytes=...) は展開後XMLを既定256 MiBに制限します。信頼できる正当な大容量データだけ、正の整数で上限を明示変更してください。上限超過、破損、途中切れ、末尾データ付きの圧縮入力は、帳票状態を変更する前に拒否されます。
SwapPdfImage の既定値は False です。True ではPDF画像XObjectを安全な一時ファイルへ退避し、シリアライズ時に1件ずつ読み戻して、成功・失敗・キャンセルのいずれでも削除します。SaveXPS はPure Python版の対象外です。
ページ単位の印刷:CutByPageRM037
レシート・ラベルプリンターで、ジョブ終了時のカットをページごとに行いたい場合に使います。ページを作成した Report に report.CutByPage = True を設定し、report.Print(...) で出力します。False では選択したページをまとめ、True ではページごとに別ジョブへ分けます。PDFの改ページや帳票寸法を変える設定ではありません。
カットそのものはプリンターとドライバー側のジョブ終端カット設定に依存します。カッター命令を直接送る機能ではなく、カッターを持たない機器では用紙は切れません。
画像の多いPDF:SwapPdfImageRM038
大きな画像を多数のページに配置し、PDF生成中の保持メモリーを抑えたい場合に使います。
# report はページを作成済みの pao_reports.Report
report.SwapPdfImage = True
report.SavePDF("output.pdf")
Renderer を直接利用する場合は RenderOptions(swap_pdf_image=True) を渡します。画像の位置・大きさや出力方式を変更する指定ではありません。一時領域への書込み権限と空き容量が必要で、ディスクI/Oは増加します。
入力画像、処理中の1画像、最終PDFのバイト列まで退避するわけではありません。大容量の帳票が必ず一定メモリーで処理できるという意味ではなく、通常の小さな帳票では既定の False を使用できます。一時データの削除は通常終了・例外・取消の後処理で行います。プロセスの強制終了や電源断は保証外です。
17. ライセンスRM039
本製品は商用ライセンスです。評価、開発用PC、サーバー配置、再配布、組み込み利用の条件は、製品に付属する使用許諾契約書を確認してください。