bpampuch / pdfmake

Client/server side PDF printing in pure JavaScript
http://pdfmake.org
Other
11.66k stars 2.04k forks source link

UnhandledPromiseRejection: The promise rejected with the reason "File 'Roboto-Medium.ttf' not found in virtual file system". #2596

Open jabibamman opened 1 year ago

jabibamman commented 1 year ago

I get the below error when trying to return the pdf promise with NestJs:

UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "File 'Roboto-Medium.ttf' not found in virtual file system".

I'm currently using the 0.2.7 version of pdfMake

import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import * as pdfMake from 'pdfmake/build/pdfmake';
import * as pdfFonts from 'pdfmake/build/vfs_fonts';
import * as fs from 'fs';
import * as path from 'path';

@Injectable()
export class InvoiceService {
  constructor() {
    pdfMake.vfs = pdfFonts.pdfMake.vfs;

  }

  async getImageBase64(imagePath: string): Promise<string> {
    return new Promise((resolve, reject) => {
      fs.readFile(imagePath, { encoding: 'base64' }, (err, data) => {
        if (err) {
          reject(err);
        } else {
          resolve(data);
        }
      });
    });
  }

  async generatePdf(name: string, amount: number, date: string, last4:string, brandCard:string, project:string): Promise<Buffer> {
    if (!name || !amount || !date || !last4 || !brandCard || !project) {    
      throw new HttpException('Missing parameters', HttpStatus.BAD_REQUEST);
    }

    const logoImagePath = path.join(process.cwd(),'src', 'assets', 'logo.png');
    const logoImageBase64 = await this.getImageBase64(logoImagePath);

    const docDefinition = {
        header: {
            columns: [
                {
                  text: `N° Attestation du don : ${Math.floor(Math.random() * 100000) + 1}`,
                  width: '50%',
                  alignment: 'left',
                  margin: [40, 20, 0, 0],
                },
                {
                  text: `${project.toUpperCase()}`,
                  width: '50%',
                  alignment: 'right',
                  margin: [0, 20, 40, 0],
                },
              ],
      },
      content: [
        {
          image: `data:image/png;base64,${logoImageBase64}`,
          width: 150,
          alignment: 'center',
          margin: [0, 0, 0, 20],
        },
        {
          text: `Merci pour votre don à l\'association ${project} !`,
          style: 'header',
          alignment: 'center',
          bold: true,
          fontSize: 20,
          margin: [0, 0, 0, 20],    
        },

        {
          text: 'Récapitulatif de paiement',
          style: 'header',
        },
        {
          text: `Nom sur la carte : ${name.split(' ').map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(' ')}`,
        },
        {
          text: `Montant : ${amount} €`,
        },
        {
          text: `Date : ${date || new Date().toLocaleDateString()}`,
        },
        {
            text: 'Informations de la carte',
            style: 'header',
            margin: [0, 20, 0, 10],
        },
        {
            table: {
                widths: ['*', '*'],
                body: [
                    ['Type de carte', brandCard.charAt(0).toUpperCase() + brandCard.slice(1)],
                    ['Numéro de carte', `**** **** **** ${last4}`],
                ],
            },
        },
      ],
      footer: {   
            columns: [
                {
                    text: 'GreenItForward France - 13 rue d\'Enghien 75010 Paris - 01 80 96 96 96',
                    alignment: 'center',
                    margin: [0, 20, 0, 0],
                },
            ],
      },
      styles: {
        header: {
          fontSize: 18,
          bold: true,
          margin: [0, 0, 0, 10],
        },
      },
    };

    try {
      const pdfDoc = pdfMake.createPdf(docDefinition);
      return new Promise<Buffer>((resolve, reject) => {
        pdfDoc.getBuffer((buffer: Buffer) => {
          resolve(buffer);
        }, (error: any) => {
          reject(error);
        });
      });
    } catch (error) {
      console.error('Error creating PDF:', error);
    }
  }
}
llcoollasa commented 1 year ago

Similar error happens for me even though it was handled by try catch. this happens when pdf tries to create with a invalid image string.

[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "Invalid image: File 'iVBORw0KGgoAAAANSUhEUgAABR0AAAaZCAYAAADBNai5AAAA' not found in virtual file system Images dictionary should contain dataURL entries (or local file paths in node.js)".] { code: 'ERR_UNHANDLED_REJECTION' }