Je rencontre un problème avec Unicode
avec un contenu variable lors de l'écriture dans un .pdf avec python.
Il génère cette erreur:
XXX
Ce qui se fait prendre sur un tiret em en gros.
J'ai essayé de prendre cette variable, où le contenu a un «em dash» et de la redéfinir avec un « .encode (« utf-8 »)
» par exemple, ie , ci-dessous:
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")
Et maintenant, j'obtiens l'erreur ci-dessous:
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
Ci-dessous mon code complet, comment pourrais-je simplement corriger mon erreur Unicode dans le contenu de la variable ' Body
'.
Conversion en utf-8
ou western
, tout ce qui est en dehors de ' latin-1
'. Des suggestions?
Code complet:
Body = msg.Body BodyC = Body.encode('utf-8')
'latin1'
?^ 3 Réponses :
Une solution de contournement consiste à convertir tout le texte en encodage latin-1 avant de le transmettre à la bibliothèque. Vous pouvez le faire avec la commande suivante:
text2 = text.encode('latin-1', 'replace').decode('latin-1')
text2
sera libre de tout caractère non latin-1. Cependant, certains caractères peuvent être remplacés par ?
fait ce travail dans Python 3 ... J'ai des problèmes pour que ça marche. Je peux le convertir en une chaîne avec? cependant le fpdf le rejette toujours ...
Oui, j'ai aussi exécuté cela avec Python 3
Mes 'sortent tous à? .... avez-vous utilisé la méthode de substitution de police où vous définissez une police UTF 8?
La raison de cette erreur est que vous essayez d'afficher un caractère de votre PDF qui se trouve en dehors de la plage de codes du codage latin-1
. FPDF utilise latin-1
comme encodage par défaut pour toutes ses polices intégrées.
Pour contourner le problème, vous pouvez simplement supprimer tous les caractères de votre texte qui ne rentrent pas dans latin-1
encodage. (voir mon autre réponse pour cette solution de contournement).
Pour corriger cette erreur et pouvoir rendre ces caractères dans votre PDF, vous devez utiliser des polices qui prennent en charge une plus large gamme de caractères. Pour résoudre ce problème, la bibliothèque FPDF prend en charge la police Unicode.
Par exemple, vous pouvez obtenir les polices Google Noto , qui prend en charge une large gamme de points de terminaison Unicode. Pour la plupart des langues occidentales, je recommanderais le jeu de polices NotoSans. Mais vous pouvez également obtenir des polices pour de nombreuses autres langues et scripts, y compris le chinois, l'hébreu ou l'arabe.
Voici comment activer les polices Unicode dans votre code pour FPDF:
Vous devez d'abord pour indiquer à la bibliothèque FPDF où elle peut trouver les fichiers de polices. Dans cet exemple, je le configure sur le sous-dossier polices
du dossier actuel.
pdf.set_font("NotoSans", size=12)
Ensuite, vous devez ajouter les polices à votre PDF document. Dans cet exemple, j'ajoute les polices NotoSans pour les styles normal, gras, italique et gras-italique:
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)
Vous pouvez maintenant utiliser les nouvelles polices normalement dans votre document PDF avec set_font ()
. Voici un exemple de texte normal:
import fpdf fpdf.set_global("SYSTEM_TTFONTS", os.path.join(os.path.dirname(__file__),'fonts'))
Vous pouvez également modifier l'encodage via la méthode .set_doc_option ()
(documentation ici ). J'ai essayé la méthode d'Erik, qui a fonctionné pour moi, mais après avoir ajouté quelques complexités supplémentaires (comme un deuxième PDF et en utilisant la méthode write_html () qui nécessitait la création d'une nouvelle classe), je suis revenu à la même erreur. La modification de l'encodage de l'ensemble du document devrait résoudre le problème global comme vous l'avez dit.
La page readthedocs indique que vous ne pouvez utiliser que latin-1 ou windows-1252, mais pdf.set_doc_option ('core_fonts_encoding', 'utf-8')
a fonctionné pour moi selon le débogueur. Sachez simplement que certains caractères devront être corrigés, comme l'apostrophe (') qui apparaît comme à ¢  € ÂTM dans le PDF.
J'espère que c'est la solution globale pour ce problème que vous recherchiez, même si plusieurs mois de retard!
Avez-vous essayé de diffuser le msg.Body avec
str (msg.Body)
?Où, que voulez-vous dire?
Body = massage.Body
->Body = str (msg.Body)
?Il produit toujours exactement la même erreur 'UnicodeEncodeError: le codec' latin-1 'ne peut pas encoder le caractère' \ u2013 'en position 485: ordinal pas dans la plage (256)'
Essayez cette réponse: stackoverflow.com/questions/6539881/...
BodyC = Body.encode ('utf-8')
ne fait rien! Un autre point est la sortie d'erreur\ u2013
estunicode
mais l'encodage à l'échelle du système n'est pas correctement défini. Quelques avertissements: User_class quel sous-processus appelle avec l'encodage par défaut? la plupart des erreurs de codage sont générées par des fichiers / objets d'E / S non RAW. @ladygremlin whindows toujours à l'exception de ces erreurs, j'ai résolu l'encodage à l'échelle du système par UTF-8 (pas Unicode).@dsgdfg Ahhh, je ne savais pas que Windows lançait toujours ça. Ce n'est pas mon système d'exploitation de choix. :)
sur python idle
'\ x64 \ x45' + 'teest' = 'dEteest'
signifie que j'ai utilisépython2.7.X
donc si vous utilisezpython3.x code> convertit les octets en chaîne avec le codage source.
@dsgdfg Des suggestions?
Copie possible de Python: UnicodeEncodeError: le codec 'latin-1' ne peut pas encoder le caractère
UnicodeEncodeError: le codec 'latin-1' ne peut pas encoder le caractère
@phuclv donc j'ai corrigé cette erreur spécifique; mais comment puis-je gérer globalement ces problèmes?