前端纯本地实现多图合并导出PDF工具
一、前言
日常工作中经常会遇到批量图片转PDF的场景:扫描证件、截图归档、图纸整理、学习资料成册等。市面上在线图片转PDF工具大多存在两个痛点:一是需要上传图片到第三方服务器,敏感文件有泄露风险;二是批量处理数量有限,大尺寸图片容易压缩模糊。
基于此,本文采用 jsPDF 纯前端方案,所有图片解析、PDF渲染操作全部在浏览器本地完成,不会上传任何文件,支持一次性多选多张图片,自动预览、自动适配A4纸张居中排版,一键导出完整PDF文件,代码无复杂依赖,新建HTML文件直接打开就能使用。
二、技术选型说明
- 核心库 jsPDF 2.5.1
业界成熟前端PDF生成库,支持图片、文字、分页、自定义尺寸,CDN直接引入无需本地安装依赖; - 原生 FileReader + Image API
本地读取图片文件、获取图片原始宽高,实现等比例缩放适配A4页面; - 原生HTML+CSS
极简页面布局,无Vue/React等框架,兼容Chrome、Edge、360等主流现代浏览器。
整体逻辑流程:本地多选图片 → FileReader转base64预览 → 循环加载图片计算缩放比例 → 每页插入一张图片并自动分页 → 浏览器触发PDF下载。
三、完整可运行源码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>多张图片转PDF合并成册</title>
<style>
* {
box-sizing: border-box;
font-family: system-ui, sans-serif;
}
body {
max-width: 900px;
margin: 30px auto;
padding: 0 20px;
}
.preview {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin: 20px 0;
}
.preview img {
width: 120px;
height: auto;
border: 1px solid #ddd;
border-radius: 6px;
object-fit: cover;
}
button {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
background: #409eff;
color: white;
border: none;
border-radius: 6px;
}
button:disabled {
background: #ccc;
cursor: not-allowed;
}
</style>
</head>
<body>
<h2>📷 多张图片合并为一个 PDF</h2>
<input type="file" id="imgInput" accept="image/*" multiple>
<div class="preview" id="preview"></div>
<button id="createPdfBtn" disabled>生成并下载 PDF</button>
<script src="https://cdn.jsdelivr.net/npm/jspdf@2.5.1/dist/jspdf.umd.min.js"></script>
<script>
const { jsPDF } = window.jspdf;
const imgInput = document.getElementById('imgInput');
const preview = document.getElementById('preview');
const createPdfBtn = document.getElementById('createPdfBtn');
let imgFiles = [];
// 选择图片并预览
imgInput.addEventListener('change', (e) => {
const files = Array.from(e.target.files);
if (files.length === 0) return;
preview.innerHTML = '';
imgFiles = [];
files.forEach((file, index) => {
const reader = new FileReader();
reader.onload = (ev) => {
const img = new Image();
img.src = ev.target.result;
preview.appendChild(img);
imgFiles.push({ src: ev.target.result, file });
};
reader.readAsDataURL(file);
});
createPdfBtn.disabled = false;
});
// 生成 PDF
createPdfBtn.addEventListener('click', async () => {
if (imgFiles.length === 0) return;
const pdf = new jsPDF({
orientation: 'portrait', // 竖向 portrait / 横向 landscape
unit: 'mm',
format: 'a4'
});
const a4Width = 210;
const a4Height = 297;
for (let i = 0; i < imgFiles.length; i++) {
const imgData = imgFiles[i].src;
const img = new Image();
img.src = imgData;
await new Promise(resolve => {
img.onload = () => {
const w = img.width;
const h = img.height;
let scale = 1;
if (w > h) {
// 宽图
scale = a4Width / w;
} else {
// 高图
scale = a4Height / h;
}
const imgW = w * scale;
const imgH = h * scale;
const x = (a4Width - imgW) / 2;
const y = (a4Height - imgH) / 2;
if (i > 0) pdf.addPage();
pdf.addImage(imgData, 'JPEG', x, y, imgW, imgH);
resolve();
};
});
}
pdf.save(`图片合并成册_${new Date().getTime()}.pdf`);
});
</script>
</body>
</html>
四、功能详细拆解
4.1 本地图片读取与预览
通过原生 input file multiple 实现多选图片,FileReader 将图片转为Base64字符串:
- 每次选择文件前清空历史缓存与预览区域,避免新旧图片叠加;
- 读取完成后在页面生成缩略图预览,直观确认待合并图片顺序;
- 无图片时导出按钮置灰,防止空PDF生成。

4.2 A4纸张自适应缩放逻辑
A4标准尺寸宽210mm、高297mm,核心缩放规则:
- 横向图片:以页面宽度为基准缩放,保证图片左右不超出纸张;
- 纵向图片:以页面高度为基准缩放,保证图片上下不超出纸张;
- 缩放完成后计算X/Y偏移量,让图片在页面完全居中,留白均匀,视觉更整洁。
4.3 自动分页合并成册
循环遍历图片数组时做分页判断:
- 第一张图片直接写入当前空白页面;
- 从第二张图片开始,调用
pdf.addPage()新建空白A4页,每张图片独占一页,最终合成完整成册PDF。
4.4 本地下载,无文件上传
pdf.save() 方法直接触发浏览器下载,所有图片解析、渲染逻辑全部运行在客户端,图片数据不会通过网络发送到任何服务器,证件、合同、私密截图等敏感文件处理更安全。
五、使用步骤
- 将完整代码复制,新建文本文档粘贴,修改后缀为
img2pdf.html; - 使用Chrome、Edge等现代浏览器双击打开文件;
- 点击文件选择框,批量选中需要合并的图片(JPG/PNG/WebP均支持);
- 页面会自动生成所有图片缩略预览,确认顺序无误;
- 点击「生成并下载PDF」,等待渲染完成后浏览器自动保存PDF文件。


六、自定义扩展修改指南
6.1 切换页面横竖排版
初始化jsPDF配置中修改 orientation 参数:
// 横向A4
orientation: 'landscape'
6.2 修改纸张尺寸
format 参数支持 a3/a5/b5/letter 等标准纸张:
format: 'a5'
6.3 自定义导出文件名
修改save内字符串即可固定名称:
pdf.save("证件扫描合集.pdf");
6.4 进阶拓展方向(可自行二次开发)
- 拖拽排序预览图片,调整PDF内图片顺序;
- 增加删除单张图片按钮,剔除不需要的素材;
- 添加文字水印、页码、页眉页脚;
- 增加图片压缩质量参数,控制PDF文件体积;
- 支持导出后预览PDF,无需下载即可查看效果。