尝试保存PDF字符串会导致WeasyPrint出现UnicodeDecodeError

时间:2019-01-11 10:09:22

标签: django python-2.7 utf-8 weasyprint

到目前为止,这是我的代码:

from django.template import (Context, Template) # v1.11
from weasyprint import HTML  # v0.42
import codecs

template = Template(codecs.open("/path/to/my/template.html", mode="r", encoding="utf-8").read())
context = Context({})
html = HTML(string=template.render(context))

pdf_file = html.write_pdf()

#with open("/path/to/my/file.pdf", "wb") as f:
#    f.write(self.pdf_file)

错误堆栈:

[17/Jan/2019 08:14:13] INFO [handle_correspondence:54] 'utf8' codec can't
decode byte 0xe2 in position 10: invalid continuation byte. You passed in
'%PDF-1.3\n%\xe2\xe3\xcf\xd3\n1 0 obj\n<</Author <> /Creator (cairo 1.14.6
(http://cairographics.org))\n  /Keywords <> /Producer (WeasyPrint 0.42.3
\\(http://weasyprint.org/\\))>>\nendobj\n2 0 obj\n<</Pages 3 0 R /Type
/Catalog>>\nendobj\n3 0 obj\n<</Count 1 /Kids [4 0 R] /Type
/Pages>>\nendobj\n4 0 obj\n<</BleedBox [0 0 595 841] /Contents 5 0 R
/Group\n  <</CS /DeviceRGB /I true /S /Transparency /Type /Group>>
MediaBox\n  [0 0 595 841] /Parent 3 0 R /Resources 6 0 R /TrimBox [0 0 595
841]\n  /Type /Page>>\nendobj\n5 0 obj\n<</Filter /FlateDecode /Length 15
0 R>>\nstream\nx\x9c+\xe4*T\xd0\x0fH,)I-\xcaSH.V\xd0/0U(N\xceS\xd0O4PH/\xe62P0P0\xb54U\xb001T(JUH\xe3\n\x04B\x00\x8bi\r\x89\nendstream\nendobj\n6 0
obj\n<</ExtGState <</a0 <</CA 1 /ca 1>>>> /Pattern <</p5 7 0
R>>>>\nendobj\n7 0 obj\n<</BBox [0 1123 794 2246] /Length 8 0 R /Matrix
[0.75 0 0 0.75 0 -843.5]\n  /PaintType 1 /PatternType 1 /Resources
<</XObject <</x7 9 0 R>>>>\n  /TilingType 1 /XStep 1588 /YStep
2246>>\nstream\n /x7 Do\n \n\nendstream\nendobj\n8 0 obj\n10\nendobj\n9 0
obj\n<</BBox [0 1123 794 2246] /Filter /FlateDecode /Length 10 0 R
/Resources\n  11 0 R /Subtype /Form /Type /XObject>>\nstream\nx\x9c+\xe4\nT(\xe42P0221S0\xb74\xd63\xb3\xb4T\xd05442\xd235R(JU\x08W\xc8\xe3*\xe42T0\x00B\x10\t\x942VH\xce\xe5\xd2O4PH/V\xd0\xaf04Tp\xc9\xe7\n\x04B\x00`\xf0\x10\x11\nendstream\nendobj\n10 0 obj\n77\nendobj\n11 0 obj\n<</ExtGState
<</a0 <</CA 1 /ca 1>>>> /XObject <</x11 12 0 R>>>>\nendobj\n12 0
obj\n<</BBox [0 1123 0 1123] /Filter /FlateDecode /Length 13 0 R
/Resources\n  14 0 R /Subtype /Form /Type /XObject>>\nstream\nx\x9c+\xe4\n
xe4\x02\x00\x02\x92\x00\xd7\nendstream\nendobj\n13 0 obj\n12\nendobj\n14 0
obj\n<<>>\nendobj\n15 0 obj\n58\nendobj\nxref\n0 16\n0000000000 65535
f\r\n0000000015 00000 n\r\n0000000168 00000 n\r\n0000000215 00000
n\r\n0000000270 00000 n\r\n0000000489 00000 n\r\n0000000620 00000
n\r\n0000000697 00000 n\r\n0000000923 00000 n\r\n0000000941 00000
n\r\n0000001165 00000 n\r\n0000001184 00000 n\r\n0000001264 00000
n\r\n0000001422 00000 n\r\n0000001441 00000 n\r\n0000001462 00000
n\r\ntrailer\n\n<</Info 1 0 R /Root 2 0 R /Size 16>>\nstartxref\n1481
n%%EOF\n' (<type 'str'>)

实际上,它可以通过Web请求(返回PDF作为响应)和通过Shell(手动编写代码)来工作。该代码经过测试,从未给我带来问题。文件以正确的编码保存,在encoding中设置HTML kwarg无济于事;同样,模板的mode值是正确的,因为我看到了其他问题,可能是这个问题。

但是,我添加了一个管理命令以定期使用它(对于较大的PDF,我无法通过网络请求来执行此操作,因为服务器的超时可能会在完成之前激活),当我尝试调用它时,我只会得到{{ 1}}说UnicodeDecodeError

PDF(至少从我的观察中可以看出)最初使用以下字符呈现:

'utf8' codec can't decode byte 0xe2 in position 10: invalid continuation byte

翻译成这样:

%PDF-1.3\n%\xe2\xe3\xcf\xd3\n1 0

所以问题出在字符%PDF-1.3 %âãÏÓ 1 0 obj 上。 But it's a trap

相反,问题出在这行代码:

â

更改为:

pdf_file = html.write_pdf()

按预期工作!

所以我的问题是:在尝试将变量分配给字符串时,Python抛出html.write_pdf() 的原因可能是什么类型?我在自己的代码中挖掘了weasyprint的代码virtualenv,但是我没有看到转换。

1 个答案:

答案 0 :(得分:0)

所以我不知道为什么,但是现在突然起作用了。我实际上并没有进行任何修改:我只是再次运行命令,它就可以工作。

我未将问题标记为已回答,因为将来可能有人遇到与我相同的问题,可以尝试发布正确的问题。

太烦人了。


编辑

因此,看来我是一个非常聪明的人,他尝试将self.pdf_file(即models.FileField)的值设置为所创建PDF的内容而不是文件本身。