UnicodeEncodeError: 'latin-1' 编解码器无法编码字符 '\u2013'(写入 PDF)

Cap*_*Ron 6 python pdf unicode fpdf python-3.7

Unicode使用 python 写入 .pdf时,我遇到了变量内容问题。

它输出这个错误:

UnicodeEncodeError: 'latin-1' codec can't encode character '\u2013'
Run Code Online (Sandbox Code Playgroud)

基本上是什么被抓住了。

我曾尝试采用该变量,其中内容有一个“破折号”并用“ .encode('utf-8')”重新定义它,例如,如下所示:

Body = msg.Body

BodyC = Body.encode('utf-8')
Run Code Online (Sandbox Code Playgroud)

现在我收到以下错误:

Traceback (most recent call last):
  File "script.py", line 37, in <module>
    pdf.cell(200, 10, txt="Bod: " + BodyC,  ln=4, align="C")
TypeError: can only concatenate str (not "bytes") to str
Run Code Online (Sandbox Code Playgroud)

下面是我的完整代码,我怎么能简单地修复 ' Body' 变量内容中的Unicode 错误。

转换为utf-8or western, ' latin-1'之外的任何内容。有什么建议?

完整代码:

from fpdf import FPDF
import win32com.client

outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
msg = outlook.OpenSharedItem(r"C:\User\language\python\Msg-To-PDF\test_msg.msg")

print (msg.SenderName)
print (msg.SenderEmailAddress)
print (msg.SentOn)
print (msg.To)
print (msg.CC)
print (msg.BCC)
print (msg.Subject)
print (msg.Body)

SenderName = msg.SenderName
SenderEmailAddress = msg.SenderEmailAddress
SentOn = msg.SentOn
To = msg.To
CC = msg.CC
BCC = msg.BCC
Subject = msg.Subject
Body = msg.Body
BodyC = Body.encode('utf-8')

pdf = FPDF()
pdf.add_page()

# pdf.add_font('DejaVu', '', 'DejaVuSansCondensed.ttf', uni=True)
pdf.set_font("Helvetica", style = '', size = 11)
pdf.cell(200, 10, txt="From: " + SenderName, ln=1, align="C")
# pdf.cell(200, 10, border=SentOn, ln=1, align="C")
pdf.cell(200, 10, txt="To: " + To, ln=1, align="C")
pdf.cell(200, 10, txt="CC: " + CC, ln=1, align="C")
pdf.cell(200, 10, txt="BCC: " + BCC, ln=1, align="C")
pdf.cell(200, 10, txt="Subject: " + Subject, ln=1, align="C")
pdf.cell(200, 10, txt="Bod: " + BodyC,  ln=4, align="C")

pdf.output("Sample.pdf")
Run Code Online (Sandbox Code Playgroud)
  • 我怎样才能变出来'latin1'

  • 无论如何只是在全球范围内解决这些问题?

Eri*_*ken 10

解决方法是将所有文本转换为 latin-1 编码,然后再将其传递给库。您可以使用以下命令执行此操作:

text2 = text.encode('latin-1', 'replace').decode('latin-1')
Run Code Online (Sandbox Code Playgroud)

text2将不含任何非拉丁 1 字符。但是,某些字符可能会替换为?


Eri*_*ken 5

出现此错误的原因是您尝试在 PDF 中呈现超出编码代码范围的字符latin-1。FPDF 使用latin-1其所有内置字体的默认编码。

因此,作为解决方法,您可以从文本中删除所有不适合latin-1编码的字符。(有关此解决方法,请参阅我的其他答案)。

要修复此错误并能够在 PDF 中呈现这些字符,您需要使用支持更广泛字符的字体。为了解决这个问题,FPDF 库支持 Unicode 字体。

例如,您可以获得免费的Google Noto 字体,它支持广泛的 Unicode 端点。对于大多数西方语言,我会推荐 NotoSans 字体集。但您还可以获得许多其他语言和文字的字体,包括中文、希伯来语或阿拉伯语。

以下是如何在 FPDF 代码中启用 Unicode 字体:

首先,您需要告诉 FPDF 库在哪里可以找到字体文件。fonts在此示例中,我将其设置为当前文件夹的子文件夹。

import fpdf
fpdf.set_global("SYSTEM_TTFONTS", os.path.join(os.path.dirname(__file__),'fonts'))
Run Code Online (Sandbox Code Playgroud)

然后您需要将字体添加到 PDF 文档中。在此示例中,我添加了 NotoSans 字体,样式为普通、粗体、斜体和粗斜体:

pdf = fpdf.FPDF()
pdf.add_font("NotoSans", style="", fname="NotoSans-Regular.ttf", uni=True)
pdf.add_font("NotoSans", style="B", fname="NotoSans-Bold.ttf", uni=True)
pdf.add_font("NotoSans", style="I", fname="NotoSans-Italic.ttf", uni=True)
pdf.add_font("NotoSans", style="BI", fname="NotoSans-BoldItalic.ttf", uni=True)
Run Code Online (Sandbox Code Playgroud)

现在您可以在 PDF 文档中正常使用新字体set_font()。这是普通文本的示例:

pdf.set_font("NotoSans", size=12)
Run Code Online (Sandbox Code Playgroud)