frappe-syntax-print について
Frappe v14、v15、v16で印刷フォーマットやPDFを作成する開発者向けのリファレンスです。Jinjaとレポート用JSテンプレート、Letter Head、PDF API、v15以降のPrint Designerを扱い、エンジンやバージョンの違いも説明します。
主な機能
- 01標準、Jinja、レポート用JSの印刷形式
- 02Print Designerの対応バージョンとエンジン
- 03Letter Headとヘッダー・フッターの設定
- 04PDF生成APIとダウンロードエンドポイント
- 05改ページ、印刷CSS、テンプレートフィルター
活用シーン
- 01カスタムの帳票フォーマットを作成
- 02レポート用JS印刷テンプレートを設定
- 03Letter Head付きPDFを生成
- 04印刷レイアウトと改ページを調整
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ impertio-studio/ frappe_claude_skill_package --skill frappe-syntax-printインストール後、Claude Code で/frappe-syntax-printを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/anti-patterns.mdjinja-print-formats.mdpdf-api.md詳細
Frappe の印刷フォーマットと PDF 生成
Frappe v14/v15/v16 における印刷フォーマット、レターヘッド、PDF 生成の確定的なリファレンスです。
このスキルを使用する場面
次の場合に使用します:
- 印刷フォーマット(Jinja または JS)を作成または変更する
- プログラムから PDF を生成する(
get_pdf、ダウンロードエンドポイント) - 印刷出力用のレターヘッド(ヘッダー/フッター)を設定する
- Print Designer(v15 以降)を使用する
- 改ページ、印刷 CSS、または横向きレイアウトを実装する
- レポート印刷フォーマット({%= %} 構文)を作成する
次の場合には使用しないでください:
- 一般的な Jinja テンプレート構文(メール、ポータル)—
frappe-syntax-jinjaを参照してください - クライアントスクリプトの UI ロジック —
frappe-syntax-clientscriptsを参照してください - Web ビューまたはポータルページ —
frappe-syntax-jinjaを参照してください
判断ツリー:どの印刷フォーマットタイプを選ぶか?
Need a printable/PDF document?
├─ YES → Is it a Query/Script Report?
│ ├─ YES → Use JS Template ({%= %} microtemplate)
│ │ Set print_format_for = "Report"
│ └─ NO → Need visual drag-and-drop editor?
│ ├─ YES → On v15+?
│ │ ├─ YES → Use Print Designer (WeasyPrint)
│ │ └─ NO → NOT available on v14. Use Jinja.
│ └─ NO → Need full layout control?
│ ├─ YES → Use Jinja Print Format (custom_format=1)
│ └─ NO → Use Standard Print Format (auto layout)
└─ NO → This skill does not apply.
印刷フォーマットの種類
| タイプ | エンジン | バージョン | 使用する場面 |
|---|---|---|---|
| 標準 | DocType のフィールドレイアウトから自動生成 | v14 以降 | カスタマイズが不要な場合 |
| Jinja | サーバー側 Jinja2(wkhtmltopdf) | v14 以降 | レイアウトを完全に制御する場合 |
| JS テンプレート | クライアント側マイクロテンプレート | v14 以降 | レポート印刷フォーマットのみ |
| Print Designer | WeasyPrint/Chrome | v15 以降 | ビジュアルなドラッグ&ドロップビルダー |
標準印刷フォーマット
常にデフォルトです。Frappe は DocType のフィールドからレイアウトを自動生成します。コードは不要です。Print Settings とフィールドの print_hide プロパティで制御します。
Jinja 印刷フォーマット
Print Format ドキュメントで custom_format = 1 に設定します。サーバー側レンダリングによる完全な Jinja2 を使用します。
すべての Jinja 印刷フォーマットで使用できるコンテキスト変数:
| 変数 | 型 | 内容 |
|---|---|---|
doc | Document | 印刷対象のドキュメント |
meta | Meta | DocType のメタデータ |
layout | list | フィールドレイアウトのセクション |
letter_head | str | レンダリング済みのレターヘッド HTML |
footer | str | レンダリング済みのフッター HTML |
print_settings | dict | Print Settings の設定 |
frappe | module | frappe モジュールへの完全なアクセス |
例 — 最小限の Jinja 印刷フォーマット:
<h1>{{ doc.name }}</h1>
<p>Customer: {{ doc.customer_name }}</p>
<p>Date: {{ doc.posting_date | global_date_format }}</p>
<table class="table table-bordered">
<thead>
<tr><th>Item</th><th>Qty</th><th>Rate</th><th>Amount</th></tr>
</thead>
<tbody>
{% for row in doc.items %}
<tr>
<td>{{ row.item_name }}</td>
<td>{{ row.qty }}</td>
<td>{{ frappe.utils.fmt_money(row.rate, currency=doc.currency) }}</td>
<td>{{ frappe.utils.fmt_money(row.amount, currency=doc.currency) }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<p><strong>Grand Total:</strong> {{ frappe.utils.fmt_money(doc.grand_total, currency=doc.currency) }}</p>
JS テンプレート(レポート印刷フォーマット)
クエリレポートとスクリプトレポートでのみ使用します。Jinja ではなく、{%= %} マイクロテンプレート構文を使用します。
// In report's .js file
{%= row.item_name %}
{% if (row.qty > 10) { %}
<strong>Bulk order</strong>
{% } %}
{% for (var i = 0; i < rows.length; i++) { %}
<tr>
<td>{%= rows[i].item_name %}</td>
<td>{%= rows[i].qty %}</td>
</tr>
{% } %}
重要: Jinja の {{ }} 構文と JS の {%= %} 構文を絶対に混在させないでください。これらは完全に別のテンプレートエンジンです。
Print Designer(v15 以降のみ)
- 独立したアプリ:
bench get-app print_designer - WeasyPrint を使用します(wkhtmltopdf ではありません)
- ブラウザー上でビジュアルなドラッグ&ドロップビルダーを使用します
- v14 では Print Designer を絶対に使用しないでください。利用できません
レターヘッド
レターヘッドを使用すると、すべての印刷フォーマットで一貫したヘッダー/フッターを表示できます。
設定
| フィールド | 用途 |
|---|---|
source | "Image" または "HTML" |
content | ヘッダー HTML(doc コンテキストで Jinja レンダリング) |
footer | フッター HTML(Jinja レンダリング、PDF のみ) |
image | ヘッダー画像(source = "Image" の場合) |
align | 画像の配置:Left、Center、Right |
重要: footer フィールドは PDF 出力にのみ表示され、ブラウザーの印刷プレビューには表示されません。
Jinja テンプレート内のレターヘッド
# Server-side: render Letter Head programmatically
from frappe.utils.print_format import render_letterhead_for_print
letterhead_html = render_letterhead_for_print(
letter_head_name="My Company",
doc=doc
)
動的なレターヘッドの内容
レターヘッドの content フィールドと footer フィールドは、doc コンテキストを使った Jinja に対応しています。
<div style="text-align: right;">
<strong>{{ doc.company }}</strong><br>
Date: {{ doc.posting_date | global_date_format }}
</div>
PDF 生成 API
API の完全なリファレンスは
references/pdf-api.mdを参照してください。
クイックリファレンス
# Generate PDF bytes from HTML
from frappe.utils.pdf import get_pdf
pdf_bytes = get_pdf(html_string, options=None)
# Generate PDF from a specific document + print format
from frappe.utils.print_format import download_pdf
download_pdf(doctype, name, format=None, doc=None, no_letterhead=0)
ダウンロードエンドポイント
# Single document PDF
GET /api/method/frappe.utils.print_format.download_pdf
?doctype=Sales Invoice
&name=SINV-00001
&format=My Print Format
&no_letterhead=0
# Multiple documents in one PDF
GET /api/method/frappe.utils.print_format.download_multi_pdf
?doctype=Sales Invoice
&name=["SINV-00001","SINV-00002"]
&format=My Print Format
PDF エンジンの選択(v15 以降)
| エンジン | 場合 | 設定 |
|---|---|---|
| wkhtmltopdf | v14 のデフォルト、v15 以降のフォールバック | デフォルト |
| Chrome | Chromium がインストールされた v15 以降 | Print Format で pdf_generator = "chrome" |
| WeasyPrint | Print Designer フォーマットのみ | Print Designer で自動 |
v14 では常に wkhtmltopdf を使用してください。v15 以降では、Chrome のほうが CSS3 のサポートに優れています。
改ページと印刷 CSS
改ページ用クラス
<div class="page-break"></div>
<div style="page-break-after: always;"></div>
<div style="page-break-before: always;"></div>
印刷 CSS クラス(Frappe 組み込み)
| クラス | 効果 |
|---|---|
.print-format | コンテナー:最大幅 8.3in、最小高さ 11.69in(A4 縦向き) |
.print-format.landscape | 幅 11.69in(A4 横向き) |
.page-break | page-break-after: always |
.print-heading | 印刷タイトルのスタイル |
.hidden-pdf | PDF 出力時のみ非表示 |
.visible-pdf | PDF 出力時のみ表示 |
PDF ヘッダー/フッター HTML
# In hooks.py — inject header/footer into every PDF
pdf_header_html = "myapp.utils.get_pdf_header"
pdf_body_html = "myapp.utils.get_pdf_body"
pdf_footer_html = "myapp.utils.get_pdf_footer"
<div id="header-html">
<span class="page"></span> of <span class="topage"></span>
</div>
<div id="footer-html">
<p style="text-align: center; font-size: 9px;">
Printed on {{ frappe.utils.nowdate() }}
</p>
</div>
印刷 CSS のベストプラクティス
/* ALWAYS use relative units for print widths */
@media print {
.print-format {
max-width: 100%;
margin: 0;
padding: 15mm;
}
/* Prevent table rows from splitting across pages */
tr {
page-break-inside: avoid;
}
/* Constrain images */
img {
max-width: 100%;
height: auto;
}
}
カスタムアプリの印刷フォーマット
アプリに印刷フォーマットを同梱する
myapp/
└── mymodule/
└── print_format/
└── my_custom_format/
├── my_custom_format.json # Print Format doc
└── my_custom_format.html # Jinja template
JSON ファイルでは必ず次の値を設定してください:
{
"doctype": "Print Format",
"name": "My Custom Format",
"doc_type": "Sales Invoice",
"module": "My Module",
"standard": "Yes",
"custom_format": 1,
"print_format_type": "Jinja"
}
アプリに同梱する印刷フォーマットでは、必ず standard = "Yes" と module を設定してください。これにより、サイトレベルのカスタマイズではなく、アプリの一部として認識されます。
印刷フォーマット用 Jinja フィルター
| フィルター | 目的 | 例 |
|---|---|---|
global_date_format | システム設定に従って日付をフォーマットする | {{ doc.posting_date | global_date_format }} |
json | JSON 文字列にシリアライズする | {{ doc.items | json }} |
len | 長さを取得する | {{ doc.items | len }} |
int | 整数にキャストする | {{ value | int }} |
flt | 浮動小数点数にキャストする | {{ value | flt }} |
markdown | Markdown を HTML にレンダリングする | {{ doc.description | markdown }} |
abs | 絶対値を取得する | {{ value | abs }} |
カスタム Jinja フィルター/メソッドを登録する
# In hooks.py
jinja = {
"methods": [
"myapp.utils.jinja.my_custom_method"
],
"filters": [
"myapp.utils.jinja.my_custom_filter"
]
}
# myapp/utils/jinja.py
def my_custom_method(value):
"""Available as {{ my_custom_method(doc.field) }} in templates."""
return value.upper()
def my_custom_filter(value, arg=None):
"""Available as {{ doc.field | my_custom_filter }} in templates."""
return f"[{value}]"
バージョン互換性マトリックス
| 機能 | v14 | v15 | v16 |
|---|---|---|---|
| Jinja 印刷フォーマット | はい | はい | はい |
| JS レポートテンプレート | はい | はい | はい |
| 標準印刷フォーマット | はい | はい | はい |
| レターヘッド(画像/HTML) | はい | はい | はい |
| wkhtmltopdf | デフォルト | フォールバック | フォールバック |
| Chrome PDF エンジン | いいえ | はい | はい |
| WeasyPrint | いいえ | はい | はい |
| Print Designer アプリ | いいえ | はい | はい |
pdf_header_html フック | はい | はい | はい |
download_multi_pdf | はい | はい | はい |
よくあるアンチパターン
修正方法を含む完全な一覧は、
references/anti-patterns.mdを参照してください。
- 絶対にレポート印刷フォーマットで
{{ }}を使用しないでください。{%= %}(JS マイクロテンプレート)を使用します。 - 絶対にテンプレートの
{% for %}ループ内でfrappe.get_doc()を呼び出さないでください。N+1 クエリの原因になります。 - 絶対にJinja テンプレートに重いビジネスロジックを記述しないでください。Python に移し、結果を渡してください。
- 絶対にCSS でページ寸法をハードコードしないでください。
.print-formatクラスまたは相対単位を使用してください。 - 絶対にプログラムから PDF を生成する際に、
no_letterheadパラメーターを無視しないでください。 - 絶対にv14 で Print Designer を使用しないでください。v15 以降が必要です。
- 絶対に印刷テンプレートに大きな base64 画像を埋め込まないでください。
max-width: 100%を指定した URL を使用してください。
リファレンスファイル
- Jinja 印刷フォーマット -- Jinja 構文、変数、フィルター、マクロ
- PDF API -- get_pdf()、ダウンロードエンドポイント、改ページ、フック
- アンチパターン -- よくある印刷フォーマットの誤りと修正方法