0

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:

enter image description here

Community
  • 1
  • 1
Masud Morshed
  • 87
  • 1
  • 10

2 Answers2

2

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();
})

Result Image

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.

Radwan Abu-Odeh
  • 1,897
  • 9
  • 16
0

I prefer svg for images, it works perfect with django and pdfkit

Template:

<img src={{svg_url}}>

View

svg_url = 'http://127.0.0.1:8000/static/images/qrcode.svg/'
template = get_template('path_to/template.html')
html = template.render({'svg_url ':svg_url })
pdfkit.from_string(html, 'output.pdf',configuration=config)