diegomura / diegomura/react-pdf

react-pdf not rendering images correctly during pdf.(<Document>).toBlob()

Open
#2,842 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
16.8k
Forks
1.3k
Avg merge
5h 6m
Merged PRs (30d)
52

Description

**Describe the bug**
Since react-pdf is not accepting SVG images i have created a function which first converts the svg into png and then to base64 string. This solution is working fine when rendering the pdf using the PDFViewer. However i do not want to render it on front end but im trying to convert the entire pdf to base64 so i can send it as email attachement.

**To Reproduce**
Steps to reproduce the behavior including code snippet (if applies):
1. Hook for converting svg images to base64/png:
```
const convertSvgToPngBase64 = async (svgPath, width, height, scaleFactor = 2) => {
const fetchSvgContent = async (svgPath) => {
const response = await fetch(svgPath);
if (!response.ok) {
throw new Error('Failed to fetch SVG content');
}
return response.text();
};

try {
const svgContent = await fetchSvgContent(svgPath);
const encodedSvgString = encodeURIComponent(svgContent);

const svgImage = new Image();
svgImage.src = 'data:image/svg+xml;charset=utf-8,' + encodedSvgString;

return new Promise((resolve, reject) => {
svgImage.onload = () => {
const canvas = document.createElement('canvas');
canvas.width = width * scaleFactor;
canvas.height = height * scaleFactor;
const ctx = canvas.getContext('2d');

// Ensure the canvas is cleared before drawing
ctx.clearRect(0, 0, canvas.width, canvas.height);

// Draw the SVG onto the canvas at the higher resolution
ctx.drawImage(svgImage, 0, 0, canvas.width, canvas.height);

// Scale down the canvas to the desired size
const finalCanvas = document.createElement('canvas');
finalCanvas.width = width;
finalCanvas.height = height;
const finalCtx = finalCanvas.getContext('2d');
finalCtx.drawImage(canvas, 0, 0, width, height);

const pngDataUrl = finalCanvas.toDataURL('image/png');
if (pngDataUrl) {
const base64Png = pngDataUrl.split(',')[1];
resolve(`data:image/png;base64,${base64Png}`);
} else {
reject(new Error("PNG data URL generation failed"));
}
};

svgImage.onerror = (error) => {
reject(new Error("Failed to load SVG image: " + error.message));
};
});
} catch (error) {
console.error('Error converting SVG to PNG:', error);
throw error;
}
};
```
2.React component to construct the Document:
```
import React, { useState, useEffect } from 'react';
import { Page, Text, View, Document, StyleSheet } from '@react-pdf/renderer';
import usePdfReportHooks from '/src/hooks/usePdfReportHooks';

import PDF_REPORT_VEHICLE_INFO from '/src/components/ReportPage/pdf/PDF_REPORT_VEHICLE_INFO';

import LogoSvg from "/media/AutoCheck 1.svg";
import CyPlateSvg from "/media/cyPlate.svg";

const PdfDocument = ({ vehicleData }) => {
const { convertSvgToPngBase64 } = usePdfReportHooks();
const [imagesBase64, setImagesBase64] = useState({});

useEffect(() => {
const fetchData = async () => {
try {
const images = await Promise.all([
convertSvgToPngBase64(LogoSvg, 700, 700, 1),
convertSvgToPngBase64(CyPlateSvg, 700, 700, 1),
...
]);

setImagesBase64({
logoBase64: images[0],
cyPlateBase64: images[1],
...
});

} catch (error) {
console.error('Error loading images:', error);
}
};

fetchData();
}, [convertSvgToPngBase64]);

const styles = StyleSheet.create({
...
});

return (







);
};

export default PdfDocument;
```
3. Render this Document using PDFViewer:
```
return (



);
```
Until this point the code should work. Images should rendered on the PDF.

4. Now instead of using step 3, we need to convert PDF to base64:
```
import { pdf } from '@react-pdf/renderer';
import PdfDocument from '/src/components/ReportPage/pdf/PdfDocument';

const MyReport = ({vehicleData}) => {
return (

);
};

const blobToBase64 = (blob) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onerror = reject;
reader.onloadend = () => resolve(reader.result.split(',')[1]);
reader.readAsDataURL(blob);
});
};

const generatePdfBase64 = async (vehicleData) => {
try {
// Create PDF document
const document = ;
console.log("document", document);

// Convert PDF document to blob
const blob = await pdf(document).toBlob();
console.log("blob", blob);

// Convert blob to base64 string
const base64String = await blobToBase64(blob);

return base64String; // Return the base64 string
} catch (error) {
console.error('Error generating PDF:', error);
return null; // Return null to indicate an error
}
};

export default generatePdfBase64;

```
5. Try to get base64 from pdf:
```
const getPdfBase64 = async (json) => {
try {
//GET base64String from PdfGenerator
const base64Pdf = await generatePdfBase64(json);

if (base64Pdf) {
console.log('Generated PDF base64 string:', base64Pdf);
// You can now use the base64Pdf string as needed
} else {
console.error('Failed to generate PDF');
}

return { success: false, data: "" };
} catch (error) {
return { success: false, error: `Error while generating PDF: ${error}` };
}
};
```
6. see error:
```
PdfGenerator.jsx:26 false 'Image should receive either a "src" or "source" prop'
_callee$ @ @react-pdf_renderer.js?v=3c5419d1:91491
tryCatch @ @react-pdf_renderer.js?v=3c5419d1:13809
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:13901
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:13836
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14092
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:14109
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:14101
fetchImage2 @ @react-pdf_renderer.js?v=3c5419d1:91530
fetchAssets2 @ @react-pdf_renderer.js?v=3c5419d1:91545
_callee$ @ @react-pdf_renderer.js?v=3c5419d1:91571
tryCatch @ @react-pdf_renderer.js?v=3c5419d1:13809
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:13901
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:13836
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14092
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:14109
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:14101
resolveAssets2 @ @react-pdf_renderer.js?v=3c5419d1:91583
_callee$ @ @react-pdf_renderer.js?v=3c5419d1:28571
tryCatch @ @react-pdf_renderer.js?v=3c5419d1:13809
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:13901
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:13836
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14092
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
Promise.then
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14096
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
Promise.then
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14096
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
Promise.then
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14096
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
Promise.then
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14096
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
Promise.then
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14096
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
Promise.then
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14096
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
Promise.then
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14096
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
Promise.then
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14096
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:14109
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:14101
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:28587
_callee$ @ @react-pdf_renderer.js?v=3c5419d1:97630
tryCatch @ @react-pdf_renderer.js?v=3c5419d1:13809
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:13901
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:13836
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14092
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:14109
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:14101
render6 @ @react-pdf_renderer.js?v=3c5419d1:97645
_callee2$ @ @react-pdf_renderer.js?v=3c5419d1:97665
tryCatch @ @react-pdf_renderer.js?v=3c5419d1:13809
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:13901
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:13836
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14092
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:14109
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:14101
toBlob2 @ @react-pdf_renderer.js?v=3c5419d1:97696
generatePdfBase64 @ PdfGenerator.jsx:26
getPdfBase64 @ SendingPdf.jsx:37
updateCredits @ SendingPdf.jsx:147
await in updateCredits
(anonymous) @ SendingPdf.jsx:195
commitHookEffectListMount @ chunk-GVSLPJMJ.js?v=3c5419d1:16904
commitPassiveMountOnFiber @ chunk-GVSLPJMJ.js?v=3c5419d1:18152
commitPassiveMountEffects_complete @ chunk-GVSLPJMJ.js?v=3c5419d1:18125
commitPassiveMountEffects_begin @ chunk-GVSLPJMJ.js?v=3c5419d1:18115
commitPassiveMountEffects @ chunk-GVSLPJMJ.js?v=3c5419d1:18105
flushPassiveEffectsImpl @ chunk-GVSLPJMJ.js?v=3c5419d1:19486
flushPassiveEffects @ chunk-GVSLPJMJ.js?v=3c5419d1:19443
commitRootImpl @ chunk-GVSLPJMJ.js?v=3c5419d1:19412
commitRoot @ chunk-GVSLPJMJ.js?v=3c5419d1:19273
performSyncWorkOnRoot @ chunk-GVSLPJMJ.js?v=3c5419d1:18891
flushSyncCallbacks @ chunk-GVSLPJMJ.js?v=3c5419d1:9135
(anonymous) @ chunk-GVSLPJMJ.js?v=3c5419d1:18623
Show 74 more frames
Show lessUnderstand this warning
9PdfGenerator.jsx:26 false 'Image should receive either a "src" or "source" prop'
_callee$ @ @react-pdf_renderer.js?v=3c5419d1:91491
tryCatch @ @react-pdf_renderer.js?v=3c5419d1:13809
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:13901
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:13836
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14092
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:14109
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:14101
fetchImage2 @ @react-pdf_renderer.js?v=3c5419d1:91530
fetchAssets2 @ @react-pdf_renderer.js?v=3c5419d1:91545
_callee$ @ @react-pdf_renderer.js?v=3c5419d1:91571
tryCatch @ @react-pdf_renderer.js?v=3c5419d1:13809
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:13901
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:13836
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14092
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:14109
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:14101
resolveAssets2 @ @react-pdf_renderer.js?v=3c5419d1:91583
_callee$ @ @react-pdf_renderer.js?v=3c5419d1:28571
tryCatch @ @react-pdf_renderer.js?v=3c5419d1:13809
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:13901
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:13836
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14092
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
Promise.then
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14096
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
Promise.then
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14096
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
Promise.then
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14096
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
Promise.then
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14096
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
Promise.then
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14096
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
Promise.then
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14096
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
Promise.then
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14096
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
Promise.then
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14096
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
Promise.then
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14096
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
Promise.then
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14096
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
Promise.then
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14096
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
Promise.then
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14096
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
Promise.then
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14096
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
Promise.then
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14096
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:14109
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:14101
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:28587
_callee$ @ @react-pdf_renderer.js?v=3c5419d1:97630
tryCatch @ @react-pdf_renderer.js?v=3c5419d1:13809
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:13901
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:13836
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14092
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:14109
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:14101
render6 @ @react-pdf_renderer.js?v=3c5419d1:97645
_callee2$ @ @react-pdf_renderer.js?v=3c5419d1:97665
tryCatch @ @react-pdf_renderer.js?v=3c5419d1:13809
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:13901
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:13836
asyncGeneratorStep @ @react-pdf_renderer.js?v=3c5419d1:14092
_next @ @react-pdf_renderer.js?v=3c5419d1:14104
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:14109
(anonymous) @ @react-pdf_renderer.js?v=3c5419d1:14101
toBlob2 @ @react-pdf_renderer.js?v=3c5419d1:97696
generatePdfBase64 @ PdfGenerator.jsx:26
getPdfBase64 @ SendingPdf.jsx:37
updateCredits @ SendingPdf.jsx:147
await in updateCredits
(anonymous) @ SendingPdf.jsx:195
commitHookEffectListMount @ chunk-GVSLPJMJ.js?v=3c5419d1:16904
commitPassiveMountOnFiber @ chunk-GVSLPJMJ.js?v=3c5419d1:18152
commitPassiveMountEffects_complete @ chunk-GVSLPJMJ.js?v=3c5419d1:18125
commitPassiveMountEffects_begin @ chunk-GVSLPJMJ.js?v=3c5419d1:18115
commitPassiveMountEffects @ chunk-GVSLPJMJ.js?v=3c5419d1:18105
flushPassiveEffectsImpl @ chunk-GVSLPJMJ.js?v=3c5419d1:19486
flushPassiveEffects @ chunk-GVSLPJMJ.js?v=3c5419d1:19443
commitRootImpl @ chunk-GVSLPJMJ.js?v=3c5419d1:19412
commitRoot @ chunk-GVSLPJMJ.js?v=3c5419d1:19273
performSyncWorkOnRoot @ chunk-GVSLPJMJ.js?v=3c5419d1:18891
flushSyncCallbacks @ chunk-GVSLPJMJ.js?v=3c5419d1:9135
(anonymous) @ chunk-GVSLPJMJ.js?v=3c5419d1:18623
Show 86 more frames
Show lessUnderstand this warning
PdfGenerator.jsx:34 Error generating PDF: TypeError: Cannot read properties of undefined (reading 'width')
```

**Expected behavior**
The code should return a base64 string of type pdf of the PDF Document

Any feedback is appreciated!

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.