0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

htmlをPDF化 表示非表示制御 -with weasyprint

Posted at
flask
from flask import Flask, render_template, request, make_response 
from weasyprint import HTML 

app = Flask(__name__) 

@app.route('/pdf') 
def create_pdf(): 
  show_kotsuhi =   request.args.get('show_kotsuhi', 'no') == 'yes' 
  html = render_template('report.html',       show_kotsuhi=show_kotsuhi) 
  pdf = HTML(string=html).write_pdf() 
  response = make_response(pdf) 
  response.headers['Content-Type'] = 'application/pdf' 
  response.headers['Content-Disposition'] = 'inline; 
  filename=report.pdf' return response
  if __name__ == '__main__': app.run() 
report.html
<!DOCTYPE html> 
<html> 
<head>
<meta charset="UTF-8">
<title>経費レポート</title>
</head>
<body> 
<h1>経費レポート</h1>
{% if show_kotsuhi %} 
<h2>交通費のみ表示</h2> 
<p>交通費: 10,000</p>
{% else %} 
<p>交通費は非表示です</p> 
{% endif %}
</body>
</html>
 1. 交通費表示PDF  http://localhost:5000/pdf?show_kotsuhi=yes 

 2. 交通費非表示PDF  http://localhost:5000/pdf?show_kotsuhi=no またはパラメータなし 🔚
1. 必要ライブラリ
pip install Flask WeasyPrint
Flask
from flask import Flask, render_template, request, make_response
from weasyprint import HTML, CSS

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/generate_pdf', methods=['POST'])
def generate_pdf():
    # フォームからのデータを受け取る: 'show_transportation' チェックボックスの値
    show_transportation = request.form.get('show_transportation') == 'on'

    # HTMLテンプレートをレンダリング
    rendered_html = render_template('invoice.html', show_transportation=show_transportation)

    # PDFを生成
    html = HTML(string=rendered_html)
    pdf_bytes = html.write_pdf()

    # レスポンスとしてPDFを返す
    response = make_response(pdf_bytes)
    response.headers['Content-Type'] = 'application/pdf'
    response.headers['Content-Disposition'] = 'attachment; filename=invoice.pdf'
    return response

if __name__ == '__main__':
    app.run(debug=True)

解説:

  • @app.route('/generate_pdf', methods=['POST']):PDF生成

  • request.form.get('show_transportation') == 'on':HTMLフォームからshow_transportationのチェックボックス取得、チェック済み: True、no check : False → show_transportation変数へ。

  • render_template('invoice.html', show_transportation=show_transportation):invoice.html読み込み時

  • 、show_transportation変数で条件分岐準備

  • HTML(string=rendered_html).write_pdf():レンダリングされたHTML文字列からPDF作成

  • make_response:PDFをレスポンスで返。

  • 日本語フォント: *Google Fonts : Noto Sans JP → linkタグでインポート、CSSで指定

  • 本番 CSSでローカルフォント指定

index.html (PDF生成のトリガフォーム)
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>PDF生成オプション</title>
</head>
<body>
    <h1>請求書PDF生成</h1>
    <form action="/generate_pdf" method="post">
        <label>
            <input type="checkbox" name="show_transportation" checked> 交通費を含める
        </label><br><br>
        <button type="submit">PDFを生成</button>
    </form>
</body>
</html>
invoice.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>請求書</title>
    <style>
        body { font-family: 'Noto Sans JP', sans-serif; } /* 日本語フォントを指定 */
        table { width: 100%; border-collapse: collapse; }
        th, td { border: 1px solid black; padding: 8px; text-align: left; }
    </style>
    <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700&display=swap" rel="stylesheet">
</head>
<body>
    <h1>請求書</h1>
    <p>日付: 2025年6月25日</p>
    <p>宛名: 御担当者様</p>

    <table>
        <thead>
            <tr>
                <th>項目</th>
                <th>金額</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>商品A</td>
                <td>10,000</td>
            </tr>
            <tr>
                <td>サービスB</td>
                <td>5,000</td>
            </tr>
            {% if show_transportation %}
            <tr>
                <td>交通費</td>
                <td>2,000</td>
            </tr>
            {% endif %}
            <tr>
                <td>合計</td>
                <td>
                    {% if show_transportation %}
                        {{ 10000 + 5000 + 2000 }}
                    {% else %}
                        {{ 10000 + 5000 }}
                    {% endif %}
                </td>
            </tr>
        </tbody>
    </table>
</body>
</html>

PDF生成ライブ

  • ReportLab: 高機能で複雑なPDF生成むき 学習コスト 高。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?