<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="JPGtoPDF-Style.css">
<title>Multiple JPG To PDF</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
</head>
<div class="container">
<h2>Convert Multiple JPG to A4 PDF</h2>
<input
type="file"
id="files"
multiple
accept=".jpg,.jpeg,image/jpeg">
<button id="btnGenerate">
Generate PDF
</button>
<div id="summary"></div>
<table id="fileTable">
<thead>
<tr>
<th>Preview</th>
<th>File Name</th>
<th>Size (KB)</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<script src="app.js"></script>
<!-- Copy and Paste the Script here -->
</body>
</html>
/* --- Reset and base styles --- */
body{
font-family:Arial, sans-serif;
background:#f4f6f9;
padding:20px;
}
.container{
max-width:900px;
margin:auto;
background:white;
padding:20px;
border-radius:8px;
box-shadow:0 0 10px rgba(0,0,0,.1);
}
button{
padding:10px 20px;
cursor:pointer;
margin-top:10px;
}
table{
width:100%;
border-collapse:collapse;
margin-top:20px;
}
th,td{
border:1px solid #ddd;
padding:8px;
text-align:left;
}
th{
background:#f0f0f0;
}
img.preview{
width:80px;
height:100px;
object-fit:cover;
}
#summary{
margin-top:15px;
font-weight:bold;
}
<!-- Script -->
<script>
const fileInput =
document.getElementById("files");
const tbody =
document.querySelector("#fileTable tbody");
fileInput.addEventListener(
"change",
displayFiles
);
async function displayFiles(){
tbody.innerHTML = "";
const files = fileInput.files;
let totalSize = 0;
for(const file of files){
totalSize += file.size;
const row =
document.createElement("tr");
const imgURL =
URL.createObjectURL(file);
row.innerHTML = `
<td>
<img
class="preview"
src="${imgURL}">
</td>
<td>${file.name}</td>
<td>
${(file.size/1024)
.toFixed(2)}
</td>
`;
tbody.appendChild(row);
}
document.getElementById("summary")
.innerHTML =
`
Selected Files :
${files.length}
<br>
Total Size :
${(totalSize/1024/1024)
.toFixed(2)} MB
`;
}
document
.getElementById("btnGenerate")
.addEventListener(
"click",
generatePDF
);
async function generatePDF(){
const files = fileInput.files;
if(files.length === 0){
alert(
"Select JPG files first"
);
return;
}
const { jsPDF } =
window.jspdf;
const pdf =
new jsPDF({
orientation:"portrait",
unit:"mm",
format:"a4",
compress:true
});
let originalSize = 0;
for(let i=0;i<files.length;i++){
const file = files[i];
originalSize += file.size;
const imageData =
await fileToBase64(file);
const compressed =
await compressImage(
imageData,
1200,
0.60
);
if(i > 0){
pdf.addPage();
}
addImageToA4Page(
pdf,
compressed
);
}
const pdfBlob =
pdf.output("blob");
const pdfSize =
(pdfBlob.size
/1024/1024)
.toFixed(2);
document.getElementById("summary")
.innerHTML +=
`
<br>
Generated PDF :
${pdfSize} MB
`;
savePDF(pdfBlob);
}
function fileToBase64(file){
return new Promise(resolve=>{
const reader =
new FileReader();
reader.onload =
e => resolve(
e.target.result
);
reader.readAsDataURL(file);
});
}
function compressImage(
src,
maxWidth,
quality
){
return new Promise(resolve=>{
const img =
new Image();
img.onload = ()=>{
let width =
img.width;
let height =
img.height;
if(width > maxWidth){
height =
height *
(maxWidth/width);
width =
maxWidth;
}
const canvas =
document.createElement(
"canvas"
);
canvas.width =
width;
canvas.height =
height;
const ctx =
canvas.getContext(
"2d"
);
ctx.drawImage(
img,
0,
0,
width,
height
);
resolve(
canvas.toDataURL(
"image/jpeg",
quality
)
);
};
img.src = src;
});
}
function addImageToA4Page(
pdf,
imageData
){
const pageWidth = 210;
const pageHeight = 297;
const props =
pdf.getImageProperties(
imageData
);
const ratio =
Math.min(
pageWidth /
props.width,
pageHeight /
props.height
);
const width =
props.width *
ratio;
const height =
props.height *
ratio;
const x =
(pageWidth-width)/2;
const y =
(pageHeight-height)/2;
pdf.addImage(
imageData,
"JPEG",
x,
y,
width,
height,
"",
"FAST"
);
}
async function savePDF(pdfBlob){
try{
if(
"showSaveFilePicker"
in window
){
const handle =
await showSaveFilePicker({
suggestedName:
"Documents.pdf",
types:[{
description:
"PDF File",
accept:{
"application/pdf":
[".pdf"]
}
}]
});
const writable =
await handle
.createWritable();
await writable.write(
pdfBlob
);
await writable.close();
alert(
"PDF saved successfully"
);
}
else{
const url =
URL.createObjectURL(
pdfBlob
);
const a =
document.createElement(
"a"
);
a.href = url;
a.download =
"Documents.pdf";
a.click();
URL.revokeObjectURL(url);
}
}catch(error){
console.log(error);
alert(
"Save cancelled"
);
}
}
</script>