書類送付状生成デモの改造
先日作成した書類送付状生成デモを少し改造してみました。
改造点は以下のとおりです。
- すべてをcontrollerで実装していたのを改め,controllerとviewに分離した。
- viewを切り替えて,PDFとHTML両方の出力形式に対応できるようにした。
Controller部
フォームに出力形式(PDFとHTML)を選択するラジオボタンを追加しました。 どちらを選択したかにより,リダイレクト先のURLを変えています。
web2pyでは,拡張子付きのURLが呼ばれると,最初に拡張子を抜いた名前のcontroller関数が呼ばれます。 次に拡張子付きの名前のviewファイルが探され,あればそのviewを用いてレンダリングが実行されます。
# coding: utf8
from gluon.contrib import simplejson
try:
from cStringIO import StringIO
except:
from StringIO import StringIO
import tools
def index():
def docinput(num):
return TR(TD(INPUT(_name='_no'+str(num), _size=5)),
TD(INPUT(_name='_document'+str(num), _size=60)),
TD(INPUT(_name='_count'+str(num), _size=5)))
form = FORM(
UL(LI(LABEL(u'日付'), INPUT(_name="date", _value="")),
FIELDSET(LEGEND(u'宛先'),
LI(LABEL(u'郵便番号'), INPUT(_name='to_post', _size=8)),
LI(LABEL(u'住所1'), INPUT(_name='to_address1', _size=30)),
LI(LABEL(u'住所2'), INPUT(_name='to_address2', _size=30)),
LI(LABEL(u'会社名'), INPUT(_name='to_company', _size=30)),
LI(LABEL(u'氏名'), INPUT(_name='to_name', _size=30))),
FIELDSET(LEGEND(u'差出人'),
LI(LABEL(u'郵便番号'), INPUT(_name='from_post', _size=8)),
LI(LABEL(u'住所1'), INPUT(_name='from_address1', _size=30)),
LI(LABEL(u'住所2'), INPUT(_name='from_address2', _size=30)),
LI(LABEL(u'会社名'), INPUT(_name='from_company', _size=30)),
LI(LABEL(u'氏名'), INPUT(_name='from_name', _size=30)),
LI(LABEL(u'連絡先1'), INPUT(_name='from_contact1', _size=30)),
LI(LABEL(u'連絡先2'), INPUT(_name='from_contact2', _size=30))),
FIELDSET(LEGEND(u'送付物'),
TABLE(
TR(TH(u'No.'), TH(u'書類名'), TH(u'部数')),
docinput(0), docinput(1), docinput(2), docinput(3),
docinput(4), docinput(5), docinput(6), docinput(7),
docinput(8), docinput(9), docinput(10))),
LI(LABEL(u'出力媒体'),
INPUT(_type="radio", _name="_media", _value="pdf", _checked="checked"), u"PDF ",
INPUT(_type="radio", _name="_media", _value="html"), u"HTML "),
LI(INPUT(_type='submit', _value='帳票出力'),
INPUT(_type='reset', _value='リセット'), _align='right'), _id="simple"))
if form.accepts(request.vars):
response.flash = u'入力を受け付けました'
context = form.vars
context['no'] = [form.vars['_no'+str(i)] for i in range(11)]
context['document'] = [form.vars['_document'+str(i)] for i in range(11)]
context['count'] = [form.vars['_count'+str(i)] for i in range(11)]
if form.vars['_media'] == "pdf":
redirect(URL('render.pdf', vars=context))
else:
redirect(URL('render.html', vars=context))
elif form.errors:
response.flash = u'入力に誤りがあります'
else:
response.flash = u'フォームに入力してください'
return dict(form=form)
def render():
return dict(request.vars)
View部
PDF用のviewファイルを views/cover/render.pdf に, HTML用のviewファイルを views/cover/render.htmlに置きます。
PDF用のviewでは,URLパラメータの内容を元にPDFレンダリング用のパラメータを作成し, Field Reports を呼び出しています。
URLの拡張子が'pdf'の場合は,Content-Typeの指定は特に必要ないようです。
Content-Dispositionでファイル名を指定すると,PDFファイルをダウンロードさせることができます。 ファイル名を指定しないと,ブラウザのウインドウにPDFを表示します。
{{
from field import reports
import os
import gluon.fileutils
settings = {
'template-root': os.path.join(gluon.fileutils.abspath('applications',
request.application), 'resources'),
}
params = {
'settings': settings,
'template': 'templates/sofu.pdf',
'context': response._vars,
}
reports.set_defaults({})
reports.set_log_level(3)
#response.headers['Content-Type'] = 'application/pdf'
#response.headers['Content-Disposition'] = 'attachment; filename="cover.pdf"'
=XML(reports.renders(params))
}
HTML用のviewは手抜きですが,単にURLパラメータの内容をダンプします。
{{extend 'layout.html'}}
<h2>書類送付状</h2>
{{=BEAUTIFY(response._vars)}}
まとめ
書類送付状生成デモを改造して,出力形式をPDFとHTMLで選択できるようにしました。 出力形式の切り替えは,二つのviewをURLにより区別することで実現しています。
今回は,PDF出力を行うページにHTML出力を追加しましたが, 逆に既存のHTML出力を行うページにPDF出力を追加することも可能です。 PDF帳票開発ツール Field Reports の入力パラメータは, LL言語用のWebフレームワークで標準的に用いられる辞書形式を基本としているので, 既存のWebサイトに最小の労力でPDF出力機能を追加することができます。