首页 > 解决方案 > 如何更正 TypeError:Unicode 对象必须在使用 ReportLab 散列之前进行编码

问题描述

最近,我一直在工作ReportLab。目前,我想使用 PDF 生成可点击的目录ReportLab

当我尝试查看它是如何工作的时,我不断收到此错误:TypeError: Unicode-objects must be encoded before hashing

当我尝试使用ReportLab库在 Python 3.7.4 上执行此代码时:

class MyDocTemplate(BaseDocTemplate):
    def __init__(self, filename, **kw):
        self.allowSplitting = 0
        apply(BaseDocTemplate.__init__, (self, filename), kw)
        template = PageTemplate('normal', [Frame(2.5*cm, 2.5*cm, 15*cm, 25*cm, id='F1')])
        self.addPageTemplates(template)


    def afterFlowable(self, flowable):
        "Registers TOC entries."
        if flowable.__class__.__name__ == 'Paragraph':
            text = flowable.getPlainText()
            style = flowable.style.name
            if style == 'Heading1':
                level = 0
            elif style == 'Heading2':
                level = 1
            else:
                return
            E = [level, text, self.page]
            #if we have a bookmark name append that to our notify data
            bn = getattr(flowable,'_bookmarkName',None)
            if bn is not None: E.append(bn)
            self.notify('TOCEntry', tuple(E))

centered = PS(name = 'centered',
    fontSize = 30,
    leading = 16,
    alignment = 1,
    spaceAfter = 20)

h1 = PS(
    name = 'Heading1',
    fontSize = 14,
    leading = 16)


h2 = PS(name = 'Heading2',
    fontSize = 12,
    leading = 14)


# Build story.
story = []

toc = TableOfContents()
toc.levelStyles = [
    PS(fontName='Times-Bold', fontSize=20, name='TOCHeading1', leftIndent=20, firstLineIndent=-20, spaceBefore=10, leading=16),
    PS(fontSize=18, name='TOCHeading2', leftIndent=40, firstLineIndent=-20, spaceBefore=5, leading=12),
]
story.append(toc)

def doHeading(text,sty):
    from hashlib import sha1
    #create bookmarkname
    bn=sha1(text+sty.name).hexdigest()
    #modify paragraph text to include an anchor point with name bn
    h=Paragraph(text+'<a name="%s"/>' % bn,sty)
    #store the bookmark name on the flowable so afterFlowable can see this
    h._bookmarkName=bn
    story.append(h)

story.append(Paragraph('<b>Table of contents</b>', centered))
story.append(PageBreak())
doHeading('First heading', h1)
story.append(Paragraph('Text in first heading', PS('body')))
doHeading('First sub heading', h2)
story.append(Paragraph('Text in first sub heading', PS('body')))
story.append(PageBreak())
doHeading('Second sub heading', h2)
story.append(Paragraph('Text in second sub heading', PS('body')))
story.append(PageBreak())
doHeading('Last heading', h1)
story.append(Paragraph('Text in last heading', PS('body')))
doc = MyDocTemplate('mintoc.pdf')
doc.multiBuild(story)

我试图解决这个问题,但我无法正确解决这个问题。感谢您在这方面的帮助。

标签: pythondjangodatatablesreportlabpython-unicode

解决方案


你应该传递字节,而不是字符串,所以问题就在这里:

bn=sha1(text+sty.name).hexdigest()

你可以做的就是像这样改变它:

bn=sha1((text+sty.name).encode("utf8")).hexdigest()

此外,您应该真正将sha1导入移动到文件顶部,无需在每次运行函数时调用它


推荐阅读