I'm using pdfkit library to convert Html to pdf and after convert pdf then converted it in base64(String) and send it to as API response. In front-end (React) received base64(String) and create an element with base64(String) for download as pdf. But after download pdf, all images are going to blurry.
Html to Pdf converter ApiClass:
class BasicTutorCVPDF(Resource):
@staticmethod
@is_user_authenticate()
def get(_id):
try:
context = TutorModel.profile_info(_id)
html = render_template("tutorCVPDF.html", context=context)
options = {
'page-size': 'A4',
'margin-top': '0.75in',
'margin-right': '0.75in',
'margin-bottom': '0.75in',
'margin-left': '0.75in',
}
pdfkit.from_string(html, 'public/pdf/tutor_cv.pdf', options=options)
with open("public/pdf/tutor_cv.pdf", "rb") as file:
encode_string = base64.b64encode(file.read())
data = str(encode_string).split("'")[1]
return (ResService.success(None, data), ResService.success(None, data)['status']) if data else \
(ResService.not_acceptable(), ResService.not_acceptable()['status'])
except Exception as err:
LOG.report(err)
return ResService.bad_request(), ResService.bad_request()['status']
Html Template:
<tr>
<td style="text-align: left; width: 280px;">Tutor ID : </td>
<td>{{ context['user_info']['id'] }}</td>
<td rowspan="5" style="text-align: right;"><img src="{{ context['user_info']['photo'] }}" style="height: 160px; width: 160px;" alt=""></td>
</tr>
Receive Base64(String) in front-end:
export const fetchTutorCVPDF = (tutorId) => dispatch => {
req.getRequest({
url: Constants.STATIC + 'tutor-cv-pdf/' + tutorId, auth: 'bearer', }, (cb) => {
const linkSource = `data:application/pdf;base64,${cb}`;
const downloadLink = document.createElement("a");
const fileName = "cv_" + tutorId + ".pdf";
downloadLink.href = linkSource;
downloadLink.download = fileName;
downloadLink.click();
})
};
Downloaded PDF:
I used the code snippets to recreate the same issue.
It actually worked well, without any blur
Controller:
@app.route('/')
def hello_world():
pdffile_content = render_template('template.html')
options = {
'page-size': 'A4',
'margin-top': '0.75in',
'margin-right': '0.75in',
'margin-bottom': '0.75in',
'margin-left': '0.75in',
}
pdfkit.from_string(pdffile_content, 'tutor_cv.pdf', options=options)
with open("tutor_cv.pdf", 'rb') as file:
encoded = base64.b64encode(file.read())
data = str(encoded).split("'")[1]
return data, 200
Template:
<tr>
<td style="text-align: left; width: 280px;">Tutor ID : </td>
<td>123123123123</td>
<td rowspan="5" style="text-align: right;"><img src="https://cdn130.picsart.com/286240699000211.png?r1024x1024" style="height: 160px; width: 160px;" alt=""></td>
</tr>
JS code:
fetch('/').then((result) => result.text()).then(function(result){
const linkSource = `data:application/pdf;base64,${result}`;
const downloadLink = document.createElement("a");
const fileName = "cv.pdf";
downloadLink.href = linkSource;
downloadLink.download = fileName;
downloadLink.click();
})
I think the main problem is not with pdfkit
at all,
I think the original CV template (not the one in the question) has some css styling that are causing this to happen.