使用python写入.pdf时,Unicode
的内容可变,我遇到了问题。
正在输出此错误:
UnicodeEncodeError: 'latin-1' codec can't encode character '\u2013'
这基本上是什么?
我尝试使用该变量,其中的内容带有'em破折号',并使用例如'.encode('utf-8')
'重新定义,例如,如下:
Body = msg.Body
BodyC = Body.encode('utf-8')
现在我得到以下错误:
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
下面是我的完整代码,如何才能简单地在“ Body
”变量内容中修复Unicode错误。
转换为utf-8
之外的任何内容,都转换为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")
'latin1'
中进行更改? 答案 0 :(得分:1)
一种解决方法是将所有文本转换为latin-1编码,然后再传递给库。您可以使用以下命令进行操作:
text2 = text.encode('latin-1', 'replace').decode('latin-1')
text2
将不包含任何非拉丁1字符。但是,某些字符可能会替换为?
答案 1 :(得分:1)
您还可以通过.set_doc_option()
方法(文档here)更改编码。我尝试了对我有用的Erik方法,但是在添加了更多复杂性(例如第二个PDF并使用了需要创建新类的write_html()方法)之后,我又回到了同样的错误。如您所说,更改整个文档的编码应该可以解决整个问题。
readthedocs页面上说,您只能使用latin-1或Windows-1252,但是根据调试器,pdf.set_doc_option('core_fonts_encoding', 'utf-8')
对我有用。请注意,某些字符将需要修复,例如在PDF中显示为¢™的撇号(')。
希望这是您正在寻找的全球解决方案,即使延迟了几个月!
答案 2 :(得分:0)
此错误的原因是您试图在PDF中呈现latin-1
编码的代码范围之外的字符。 FPDF使用latin-1
作为其所有内置字体的默认编码。
因此,作为解决方法,您可以从文本中删除所有不适合latin-1
编码的字符。 (有关此解决方法,请参见我的其他答案)。
要修复此错误并能够在PDF中呈现这些字符,您需要使用支持更多字符的字体。为了解决这个问题,FPDF库支持Unicode字体。
例如,您可以获得免费的Google Noto fonts,它支持多种Unicode端点。对于大多数西方语言,我建议使用NotoSans字体集。但是您还可以获取许多其他语言和脚本的字体,包括中文,希伯来语或阿拉伯语。
以下是在代码中为FPDF启用Unicode字体的方法:
首先,您需要告诉FPDF库可以在哪里找到字体文件。在此示例中,我将其设置为当前文件夹的子文件夹fonts
。
import fpdf
fpdf.set_global("SYSTEM_TTFONTS", os.path.join(os.path.dirname(__file__),'fonts'))
然后,您需要将字体添加到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)
现在,您可以通过set_font()
在PDF文档中正常使用新字体了。这是普通文本的示例:
pdf.set_font("NotoSans", size=12)