マニュアル一覧PDFで読む

Reports Web Pure Python プログラマーズガイド/APIリファレンス

製品版のライセンス配置と load_license の使い方は、製品版を使い始めるをご覧ください。体験版では登録不要です。

Reports Web Pure Pythonは、ブラウザー内のWASMを使わず、Pythonだけで帳票を読み込み、データを差し込み、表示・保存・印刷するための帳票エンジンです。デスクトップアプリケーションにも、FastAPIなどのサーバー側Webアプリケーションにも組み込めます。

このガイドでは、次の処理を実装できるところまでを扱います。

画面の使い方は、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

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資源に関する失敗
    ...

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、サーバー配置、再配布、組み込み利用の条件は、製品に付属する使用許諾契約書を確認してください。