如何在 App Engine 上使用 xhtml2pdf 生成带有自定义字体的 PDF?
How to generate a PDF with custom font with xhtml2pdf on App Engine?
xhtml2pdf 可以很好地在 App Engine 上生成简单的 PDF。
但现在我需要在生成的 PDF 中添加自定义字体,我似乎没有找到一个简单的解决方案来做到这一点。
我将此 CSS 添加到 HTML 以转换为 PDF:
@font-face {
font-family: OpenSans;
src: url("http://mydomain/fonts/Open-Sans-regular.ttf");
}
body {
font-family: OpenSans;
}
产生此错误:
File "[..]/xhtml2pdf/util.py", line 613, in getNamedFile
self.tmp_file = tempfile.NamedTemporaryFile()
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/dist/tempfile.py", line 61, in PlaceHolder
raise NotImplementedError("Only tempfile.TemporaryFile is available for use")
NotImplementedError: Only tempfile.TemporaryFile is available for use
GAE 不支持 tempfile
,因此我尝试通过在 GCS 中创建临时文件来替换 tempfile.NamedTemporaryFile()
,如下所示:
self.tmp_file = gcs.open('/gcs_bucket_temp/temp_file',
'w',
retry_params=gcs.RetryParams(backoff_factor=1.1))
但这会产生难以修复的重大更改:xhtml2pdf 对 ttfonts.py
中的临时文件进行了大量读取访问(例如 ttfonts.py:321 unpack('>L',self._ttf_data[self._pos - 4:self._pos])[0]
),这似乎很难迁移到 GCS 文件。
有没有人能够在 App Engine 上使用 xhtml2pdf 生成带有自定义字体的 PDF?
以下是我必须对 xhtml2pdf 库进行的更改,以允许 App Engine 上的自定义 @font-face 支持。基本上使用 GCS 来存储临时文件而不是文件系统。
在ttfonts.py:239
中替换:
self.filename, f = TTFOpenFile(f)
self._ttf_data = f.read()
作者:
self.filename = f
gcs_file = gcs.open(f) #, 'w', retry_params=gcs.RetryParams(backoff_factor=1.1))
self._ttf_data = gcs_file.read()
gcs_file.close()
在util.py:608
中替换:
self.tmp_file = tempfile.NamedTemporaryFile()
if self.file:
shutil.copyfileobj(self.file, self.tmp_file)
else:
self.tmp_file.write(self.getData())
self.tmp_file.flush()
return self.tmp_file
作者:
filename = '/%s/temp_file'%gcs_bucket
self.tmp_file = gcs.open(filename, 'w', retry_params=gcs.RetryParams(backoff_factor=1.1))
if self.file:
self.tmp_file.write(self.file._fetch_response.content)
else:
self.tmp_file.write(self.getData())
self.tmp_file.close()
return filename
这似乎可以解决问题。自定义字体现在可以很好地显示在生成的 PDF 中。
xhtml2pdf 可以很好地在 App Engine 上生成简单的 PDF。
但现在我需要在生成的 PDF 中添加自定义字体,我似乎没有找到一个简单的解决方案来做到这一点。
我将此 CSS 添加到 HTML 以转换为 PDF:
@font-face {
font-family: OpenSans;
src: url("http://mydomain/fonts/Open-Sans-regular.ttf");
}
body {
font-family: OpenSans;
}
产生此错误:
File "[..]/xhtml2pdf/util.py", line 613, in getNamedFile
self.tmp_file = tempfile.NamedTemporaryFile()
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/dist/tempfile.py", line 61, in PlaceHolder
raise NotImplementedError("Only tempfile.TemporaryFile is available for use")
NotImplementedError: Only tempfile.TemporaryFile is available for use
GAE 不支持 tempfile
,因此我尝试通过在 GCS 中创建临时文件来替换 tempfile.NamedTemporaryFile()
,如下所示:
self.tmp_file = gcs.open('/gcs_bucket_temp/temp_file',
'w',
retry_params=gcs.RetryParams(backoff_factor=1.1))
但这会产生难以修复的重大更改:xhtml2pdf 对 ttfonts.py
中的临时文件进行了大量读取访问(例如 ttfonts.py:321 unpack('>L',self._ttf_data[self._pos - 4:self._pos])[0]
),这似乎很难迁移到 GCS 文件。
有没有人能够在 App Engine 上使用 xhtml2pdf 生成带有自定义字体的 PDF?
以下是我必须对 xhtml2pdf 库进行的更改,以允许 App Engine 上的自定义 @font-face 支持。基本上使用 GCS 来存储临时文件而不是文件系统。
在ttfonts.py:239
中替换:
self.filename, f = TTFOpenFile(f)
self._ttf_data = f.read()
作者:
self.filename = f
gcs_file = gcs.open(f) #, 'w', retry_params=gcs.RetryParams(backoff_factor=1.1))
self._ttf_data = gcs_file.read()
gcs_file.close()
在util.py:608
中替换:
self.tmp_file = tempfile.NamedTemporaryFile()
if self.file:
shutil.copyfileobj(self.file, self.tmp_file)
else:
self.tmp_file.write(self.getData())
self.tmp_file.flush()
return self.tmp_file
作者:
filename = '/%s/temp_file'%gcs_bucket
self.tmp_file = gcs.open(filename, 'w', retry_params=gcs.RetryParams(backoff_factor=1.1))
if self.file:
self.tmp_file.write(self.file._fetch_response.content)
else:
self.tmp_file.write(self.getData())
self.tmp_file.close()
return filename
这似乎可以解决问题。自定义字体现在可以很好地显示在生成的 PDF 中。