I'm dealing with this error I don't know what's the problem I have already added the font Arial and I've also tried to use the function Unicode() but nothing the same error appears
UnicodeEncodeError: 'latin-1' codec can't encode character '\u2019' in position 59: ordinal not in range(256)
p.s: I'm using mac os
and this is the code
import numpy as np
import pandas as pd
from fpdf import FPDF
from PyPDF2 import *
from time import *
import matplotlib.pyplot as plt
#function to convert minutes to date string
def Minutes_To_Date(date_minutes):
if date_minutes>0:
Secondes = int(date_minutes*60)
else :
Secondes = 0
series_format=strftime('%H:%M:%S', gmtime(Secondes))
return series_format
#function to make the data frame into a table in pdf
def output_df_to_pdf(pdf,df):
table_cell_width = 25 # set the height of the cell and the width
table_cell_height = 6
pdf.add_font("Arial", "", "arial.ttf", uni=True)
pdf.set_font("Arial", "B", 8)
cols = df.columns
#type the first row (name of columns)
for col in cols:
pdf.cell(table_cell_width, table_cell_height, col, align = 'C', border = 1)
pdf.ln(table_cell_height)
pdf.set_font("Arial", "", 10)
#type the rows
for row in df.itertuples():
for col in cols :
value = str(getattr(row,col))
pdf.cell(table_cell_width, table_cell_height, value, align = "C", border=1)
pdf.ln(table_cell_height)
#the path of our data
path = r"/Users/mac/Desktop/data_test.xlsx"
#load the data into data frame
df = pd.read_excel(path, sheet_name='Feuil1')
#add the hours columns to the dataframe
df["heure"] = (df["Date dernier envoi"].dt.hour)
#add the "delai de validation " columns to dataframe
df["Délai de validation"] = (df["Date action"] - df["Date dernier envoi"])/np.timedelta64(1, 'm') #calculate period in minutes
#create 2 pivot table one to be seen and the other to make graphs
df_pivot = pd.pivot_table(df, values="Délai de validation", index="heure", columns="Nom Service", aggfunc = "mean" , margins=True)
df_pivot_seen = pd.pivot_table(df, values="Délai de validation", index="heure", columns="Nom Service", aggfunc = "mean")
date_minutes_1 = list(df_pivot_seen["AMPE"]) #convert the data frame column to list
date_minutes_2 = list(df_pivot_seen["AMPI"])
#convert the number of minutes to string in form of date
for i in range(len(date_minutes_1)):
date_minutes_1[i] = Minutes_To_Date(date_minutes_1[i])
date_minutes_2[i] = Minutes_To_Date(date_minutes_2[i])
#convert to data frame
df_pivot_seen["AMPE"] = pd.DataFrame(date_minutes_1)
df_pivot_seen["AMPI"] = pd.DataFrame(date_minutes_2)
#create a diagram
df_pivot.plot()
plt.savefig("chart.png")
#create fpdf object with default values page:A4 and mesure will be in millimeters
pdf = FPDF()
pdf.add_font("Arial", "", "arial.ttf", uni=True)
pdf.add_page()
pdf.set_font("Arial","B", 16)
pdf.cell(40,10,"Rapport d’activité Import/Export de la semaine S52")
pdf.ln(20)
pdf.image("chart.png")
pdf.ln(20)
output_df_to_pdf(pdf, df_pivot_seen)
pdf.output("/Users/mac/Desktop/report.pdf", "F")
print(df_pivot_seen)
UnicodeEncodeError Traceback (most recent call last)
/var/folders/yv/yjnc8p5j64s70dv3dfh9td600000gn/T/ipykernel_76346/884241888.py in <module>
83
84
---> 85 pdf.output("/Users/mac/Desktop/report.pdf")
86
87
~/opt/anaconda3/lib/python3.9/site-packages/fpdf/fpdf.py in output(self, name, dest)
1063 #Finish document if necessary
1064 if(self.state<3):
-> 1065 self.close()
1066 dest=dest.upper()
1067 if(dest==''):
~/opt/anaconda3/lib/python3.9/site-packages/fpdf/fpdf.py in close(self)
244 self._endpage()
245 #close document
--> 246 self._enddoc()
247
248 def add_page(self, orientation=''):
~/opt/anaconda3/lib/python3.9/site-packages/fpdf/fpdf.py in _enddoc(self)
1634 def _enddoc(self):
1635 self._putheader()
-> 1636 self._putpages()
1637 self._putresources()
1638 #Info
~/opt/anaconda3/lib/python3.9/site-packages/fpdf/fpdf.py in _putpages(self)
1168 if self.compress:
1169 # manage binary data as latin1 until PEP461 or similar is implemented
-> 1170 p = self.pages[n].encode("latin1") if PY3K else self.pages[n]
1171 p = zlib.compress(p)
1172 else:
UnicodeEncodeError: 'latin-1' codec can't encode character '\u2019' in position 59: ordinal not in range(256)
CodePudding user response:
I solved this by changing the font. The original font (Arial only allowed latin-1.