Blank pages pdf sent to client with Pdfkit

17 views Asked by At

i am using pdfkit to generate pdf from my mongo database and then send the generated pdf to the client. the problem is the pdf is been generated and a copy of the pdf saved in the server works very well. but the problem is the pdf sent to the client for the user is completely blank it will just contain the number of pages contain in the pdf all completely blank i can't figure out what is wrong. the server code is below `

export async function generatePdf(req, res) {
  const { id, userId } = req.body;
  try {
    console.log('WORKING');
    const story = await UserStory.findById(id);

    if (!story) {
      return res.status(405).json({ success: false, data: 'Story not found' });
    }

    const doc = new pdfkit();
    const outputFilePath = `${story.title ? story.title : story.userTitle}-${story.author}.pdf`;

    // Add Cover Image on the first page
    doc.addPage();
    await downloadAndEmbedImage(doc, story.coverImage);

    // Add Title and author name on the next page
    doc.addPage();
    const titleText = story.title ? story.title : story.userTitle;
    const authorText = `Author: ${story.author}`;
    const centerX = doc.page.width / 2;
    const centerY = doc.page.height / 2;
    doc.fontSize(24).text(titleText, centerX, centerY - 20, { align: 'center' });
    doc.fontSize(16).text(authorText, centerX, centerY + 20, { align: 'center' });

    // Track current Y position
    let currentY = doc.y;

    // Add chapters
    for (const chapter of story.story) {
      // Add chapter content
      doc.addPage();
      doc.fontSize(20).text(chapter.chapterTitle, { align: 'center' });
      doc.fontSize(18).text(chapter.chapterNumber, { align: 'center' });
      doc.fontSize(16).text(chapter.chapterContent);

      // Embed chapter image on the same page
      await downloadAndEmbedImage(doc, chapter.chapterImage);

      // Track current Y position for the next chapter
      currentY = doc.y;
    }

    // Add story image on the last page
    doc.addPage();
    await downloadAndEmbedImage(doc, story.storyImage);

    // Add promotion text on a separate page
    doc.addPage().fontSize(16).text('Made and Produced by Story Generator', { align: 'center' });
    doc.text(`Visit ${process.env.MAIL_WEBSITE_LINK}`, { align: 'center' });

    // End the document
    doc.end();

    // Save PDF to server file
    const stream = fs.createWriteStream(outputFilePath);
    doc.pipe(stream);

    // Once the stream is closed, send the response
    stream.on('finish', () => {
      res.download(outputFilePath, (err) => {
        if (err) {
          console.error('Error sending PDF to client:', err);
          res.status(500).json({ success: false, data: 'Could not send the PDF to the client' });
        } else {
          console.log('PDF sent to client successfully');
          // Optionally, delete the file after sending
          //fs.unlinkSync(outputFilePath);
        }
      });
    });

  } catch (error) {
    console.log('COULD NOT GENERATE STORY', error);
    res.status(500).json({ success: false, data: 'Could not create the PDF' });
  }
}

to download the images
async function downloadAndEmbedImage(doc, imageUrl, yPos = doc.y) {
  try {
    console.log('WORK');
    const imageResponse = await axios.get(imageUrl, { responseType: 'arraybuffer' });
    const imageBuffer = Buffer.from(imageResponse.data, 'binary');

    // Embed the image into the PDF document at yPos
    doc.image(imageBuffer, { width: 300, y: yPos });

  } catch (error) {
    console.error('Error downloading and embedding image:', error);
    // Handle error accordingly
    throw error; // Rethrow error to be caught by the caller
  }
}

`

the client api call:

export async function createStorPdf({ id, userId }) {
    try {
        const res = await axios.post('/api/user/story/generatePdf', { id, userId }, { withCredentials: true });
        const url = window.URL.createObjectURL(new Blob([res.data]));
        const link = document.createElement('a');
        link.href = url;
        link.setAttribute('download', 'story.pdf');
        document.body.appendChild(link);
        link.click();
        return null;
    } catch (error) {
        console.log('ERROR RECREATING CHAPTER STORY ', error);
        if (error.response && error.response.data) {
            const errorMsg = error.response.data.data || 'Failed to generate pdf';
            console.log('MSG', errorMsg);
            toast.error(errorMsg);
            const errorStatus = error.response.status;
            if (errorStatus === 401 || errorStatus === 403) {
                window.location.href = '/login';
            }
            return errorMsg;
        } else {
            return 'An error occurred during the request.';
        }
    }
}

what am i missing please

i want the pdf sent to the client to contain the content in the pdf

0

There are 0 answers