2

私は、Unicode 文字を含むテキストを含む pdf ファイルを生成するアプリを作成しています。GAE devserver では問題なく動作しますが、デプロイ後にフォント ファイルをインポートできません (add_font() (pyfpdf) の後でクラッシュします)。

コードは次のとおりです。

# -*- coding: utf-8 -*-
def fun1(): 

from gluon.contrib.pyfpdf import FPDF, HTMLMixin
class MyFPDF(FPDF, HTMLMixin):
    pass

pdf =MyFPDF()
pdf.add_font('DejaVu', '', 'DejaVuSansCondensed.ttf', uni=True)
pdf.add_page()
pdf.set_font('DejaVu','',16)
pdf.write(10,'test-ąśł')

response.headers['Content-Type']='application/pdf'
return pdf.output(dest='S')

フォント ファイル (web2py サーバーで最初に実行した後に生成されるファイル DejaVuSansCondensed.pkl を含む) は、/gluon/contrib/fpdf/font にあります。routers.py には何も追加しませんでした (私はパターンベースのシステムを使用しています)、app.yaml も変更されていません。そして、私はこれを取得します:

In FILE: /base/data/home/apps/s~myapp/web2py-04.369240954601780983/applications/app3/controllers/default.py

Traceback (most recent call last):
  File "/base/data/home/apps/s~myapp/web2py-04.369240954601780983/gluon/restricted.py", line 212, in restricted
    exec ccode in environment
  File "/base/data/home/apps/s~myapp/web2py-04.369240954601780983/applications/app3/controllers/default.py", line 674, in <module>
  File "/base/data/home/apps/s~myapp/web2py-04.369240954601780983/gluon/globals.py", line 194, in <lambda>
    self._caller = lambda f: f()
  File "/base/data/home/apps/s~myapp/web2py-04.369240954601780983/applications/app3/controllers/default.py", line 493, in fun1
    pdf.add_font('DejaVu', '', 'DejaVuSansCondensed.ttf', uni=True)
  File "/base/data/home/apps/s~myapp/web2py-04.369240954601780983/gluon/contrib/fpdf/fpdf.py", line 432, in add_font
    font_dict = pickle.load(fh)
  File "/base/data/home/runtimes/python27p/python27_dist/lib/python2.7/pickle.py", line 1378, in load
    return Unpickler(file).load()
  File "/base/data/home/runtimes/python27/python27_dist/lib/python2.7/pickle.py", line 858, in load
    dispatch[key](self)
  File "/base/data/home/runtimes/python27/python27_dist/lib/python2.7/pickle.py", line 966, in load_string
    raise ValueError, "insecure string pickle"
ValueError: insecure string pickle

ローカル (web2py/rocket と gae の両方) で述べたように、うまく機能します。展開後、次のようなものだけが機能します:

pdf =MyFPDF()
pdf.add_page()
pdf.set_font('Arial','',16)
pdf.write(10,'testąśł')

しかし、「珍しい」文字がなければ...

最善の解決策は、フォント ファイル (DejaVu など) を追加することですが、基本的には、任意のフォントに Unicode 文字が必要です...「ジェネリック GAE Unicode」フォントを使用するための「半分の解決策」かもしれません...次のようなものが存在する場合これ...

4

1 に答える 1

0

提案ありがとうティム!

私はいくつかの解決策を見つけました...それは最善のものではありませんが、うまくいきます...

問題は、GAE で pickle を使用する場合です。(おそらく) 最善の解決策add_font()は、ファイルシステムではなくデータストアに書き込むように、GAE の場合に関数をオーバーロード/書き換えることです。追加のValueError: insecure string pickleエラーが引き続き発生する可能性があります。これに従って b64 エンコーディングを試しまし。しかし、それでもエラーが発生します。だから私の解決策はadd_font()、コメントアウト/削除された部分で関数をオーバーロードすることです:

if os.path.exists(unifilename):
    fh = open(unifilename)
    try:
        font_dict = pickle.load(fh)
    finally:
    fh.close()
else:

try:
    fh = open(unifilename, "w")
    pickle.dump(font_dict, fh)
    fh.close()
except IOError, e:
    if not e.errno == errno.EACCES:
        raise  # Not a permission error.

このため、この関数は、ピクルからデータを読み取るだけでなく、毎回少しずつ計算します... しかし、GAE で動作します。

于 2013-08-05T06:33:56.357 に答える