Image To PDF Converter using React
Image To PDF Converter using React is a web application that allows users to upload images and convert them into PDF documents. It uses React’s state management and file handling capabilities to provide a user-friendly interface for image upload, display, deletion, and PDF generation. This application enhances productivity by simplifying the process of creating PDF files from images directly within the browser.
Output Preview: Let us have a look at how the final output will look like
Steps to Create Image To PDF project:
Step 1: Create a new React JS project using the following command
npx create-react-app <<Project_Name>>
Step 2: Change to the project directory.
cd <<Project_Name>>
Step 3: Install the requires modules
npm install jspdf,
npm install file-saver
Project Structure:
The updated dependencies in package.json will look like this:
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"file-saver": "^2.0.5",
"html2canvas": "^1.4.1",
"jspdf": "^2.5.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
Approach to create Image to PDF Converter:
- Initialize a new React project using Create React App or your preferred method.
- Create a component to handle image uploads using
<input type="file">
and FileReader API to read image files as data URLs. - Use state to manage the uploaded images and display them in the UI as thumbnails or previews.
- Utilize a PDF library like jsPDF to dynamically generate a PDF document from the uploaded images. Map each image to a PDF page and add them to the document.
- Provide user actions such as deleting uploaded images, and include a button to trigger the PDF generation process.
Example: This example to shows the conversion of image to pdf.
/* App.css */
body {
margin: 0;
padding: 0;
box-sizing: border-box;
background-color: white;
font-family: 'PT Serif', serif;
}
.nav {
padding: 0.5rem 1rem;
background: white;
border-bottom: 1px solid rgb(245, 244, 244);
position: sticky;
top: 0;
z-index: 1;
display: flex;
justify-content: space-between;
align-items: center;
font-family: 'Kanit', sans-serif;
}
.logo {
padding-left: 85px;
font-size: 3rem;
color: rgb(182, 34, 34);
}
.pdf-btn,
.upload-btn {
border: none;
outline: none;
background: #4f4c5e;
color: white;
border-radius: 8px;
padding: 0.5rem 1rem;
font-size: 1rem;
margin-right: 1rem;
cursor: pointer;
}
.container {
margin: 2rem auto;
padding: 0 1rem;
}
.image-preview {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.image-item {
margin: 1rem;
position: relative;
}
.delete-btn {
position: absolute;
top: 0.5rem;
right: 0.5rem;
background: #f44336;
color: white;
border: none;
border-radius: 50%;
padding: 0.3rem;
cursor: pointer;
transition: background 0.3s;
}
.delete-btn:hover {
background: #d32f2f;
}
/* Drop box styling */
.drop-box {
border: 2px dashed #6a5858;
border-radius: 5px;
padding: 10rem;
text-align: center;
cursor: pointer;
margin-top: 2rem;
margin-left: 170px;
margin-right: 200px;
}
.drop-box:hover {
background-color: #f9f9f9;
}
.drop-text {
font-size: 1rem;
color: #888;
}
.drop-text:hover {
color: #555;
}
.pdf {
margin-left: 80px;
}
import React, { useState } from 'react';
import './App.css';
import jsPDF from 'jspdf';
const App = () => {
const [images, setImages] = useState([]);
const handleImageUpload = (event) => {
const files = event.target.files;
const newImages = [...images];
for (let i = 0; i < files.length; i++) {
const file = files[i];
const reader = new FileReader();
reader.onload = () => {
newImages.push({
data: reader.result,
name: file.name,
});
setImages(newImages);
};
reader.readAsDataURL(file);
}
};
const handleDrop = (event) => {
event.preventDefault();
const files = event.dataTransfer.files;
const newImages = [...images];
for (let i = 0; i < files.length; i++) {
const file = files[i];
const reader = new FileReader();
reader.onload = () => {
newImages.push({
data: reader.result,
name: file.name,
});
setImages(newImages);
};
reader.readAsDataURL(file);
}
};
const handleDragOver = (event) => {
event.preventDefault();
};
const handleDelete = (index) => {
const updatedImages = [...images];
updatedImages.splice(index, 1);
setImages(updatedImages);
};
const generatePDF = () => {
const doc = new jsPDF();
images.forEach((image, index) => {
if (index > 0) {
doc.addPage();
}
doc.text(image.name, 10, 10);
doc.addImage(image.data, 'JPEG', 10, 20, 180, 160);
});
doc.save('converted_images.pdf');
};
return (
<div className="app">
<div className="nav">
<img src=
"https://media.w3wiki.net/wp-content/uploads/20240320031658/pdf.png">
</img>
<div className="logo">
Image to PDF Converter
</div>
<label htmlFor="image-upload"
className="upload-btn">
Upload Images
</label>
<input
type="file"
id="image-upload"
accept="image/*"
multiple
onChange={handleImageUpload}
style={{ display: 'none' }}
/>
</div>
<div
className="container"
onDrop={handleDrop}
onDragOver={handleDragOver}
>
{images.length === 0 ? (
<div className="drop-box">
<span className="drop-text">
Drag and drop images here
</span>
<input
type="file"
id="image-upload-drop"
accept="image/*"
multiple
onChange={handleImageUpload}
style={{ display: 'none' }}
/>
</div>
) : (
<div className="image-preview">
{images.map((image, index) => (
<div key={index} className="image-item">
<img src={image.data} alt={image.name} />
<button
className="delete-btn"
onClick={() => handleDelete(index)}>
Delete
</button>
<button className="pdf-btn"
onClick={generatePDF}>
Convert to PDF
</button>
</div>
))}
</div>
)}
</div>
</div>
);
};
export default App;
Steps to run the project:
Step 1: Type the following command in terminal.
npm start
Step 2: Open web-browser and type the following URL
http://localhost:3000/
Output:
Contact Us