diegomura / diegomura/react-pdf
react-pdf not rendering images correctly during pdf.(<Document>).toBlob()
- 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
Assessment
This issue has not been assessed yet.