背景
年前的時(shí)候虑乖,開發(fā)一個(gè)電子雜志項(xiàng)目坪郭,功能需求是通過上傳pdf文件褂删,將其轉(zhuǎn)為圖片格式收叶,所以雜志的內(nèi)容其實(shí)就是一張張圖片
不過當(dāng)時(shí)技術(shù)要求用后端實(shí)現(xiàn)结啼,所以使用的是PHP實(shí)現(xiàn)該功能蝗肪。項(xiàng)目完成后轻掩,尋思著在前端是否也能實(shí)現(xiàn)pdf轉(zhuǎn)圖片的功能补鼻。一番研究后剃执,果真可行誓禁。以下就分享如何通過前端js將pdf文件轉(zhuǎn)為圖片格式,并且支持翻頁預(yù)覽肾档、以及圖片打包下載
效果預(yù)覽
所需工具
- pdf.js(負(fù)責(zé)API解析现横,可將pdf文件渲染成canvas實(shí)現(xiàn)預(yù)覽)
- pdf.worker.js(負(fù)責(zé)核心解析)
- jszip.js(將圖片打包成生成.zip文件)
- Filesaver.js(保存下載zip文件)
工具下載
一、pdf.js及pdf.worker.js下載地址:
http://mozilla.github.io/pdf.js/getting_started/#download
1.選擇穩(wěn)定版下載
2.解壓后將bulid中的pdf.js及pdf.worker.js拷貝到項(xiàng)目中
二阁最、jszip.js及Filesaver.js下載地址:
https://stuk.github.io/jszip/
1.點(diǎn)擊download.JSZip
2.解壓后將dist文件夾下的jszip.js文件以及vendor文件夾下的FileSaver.js文件拷貝到項(xiàng)目中
至此戒祠,所需工具已齊全。以下直接附上項(xiàng)目完整代碼(代碼可直接復(fù)制使用速种,查看效果姜盈。對應(yīng)的文件需自行下載引入)
源代碼:嫌麻煩的小伙伴可以直接在公眾號后回復(fù):pdf轉(zhuǎn)圖片
代碼實(shí)現(xiàn)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>PDF文件轉(zhuǎn)圖片</title>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" src="js/pdf.js"></script>
<script type="text/javascript" src="js/pdf.worker.js"></script>
<script type="text/javascript" src="js/jszip.js"></script>
<script type="text/javascript" src="js/FileSaver.js"></script>
<style type="text/css">
button {
width: 120px;
height: 30px;
background: none;
border: 1px solid #b1afaf;
border-radius: 5px;
font-size: 12px;
font-weight: 1000;
color: #384240;
cursor: pointer;
outline: none;
margin: 0 0.5%
}
button:hover {
background: #ccc;
}
#container {
width: 600px;
height: 780px;
margin-top: 1%;
border-radius: 2px;
border: 2px solid #a29b9b;
}
.pdfInfos {
margin: 0 2%;
}
</style>
</head>
<body>
<div style="margin-top:1%">
<button id="prevpage">上一頁</button>
<button id="nextpage">下一頁</button>
<button id="exportImg">導(dǎo)出圖片</button>
<button onclick="choosePdf()">選擇一個(gè)pdf文件</button>
<input style="display:none" id='chooseFile' type='file' accept="application/pdf">
</div>
<div style="margin-top:1%">
<span class="pdfInfos">頁碼:<span id="currentPages"></span><span id="totalPages"></span></span>
<span class="pdfInfos">文件名:<span id="fileName"></span></span>
<span class="pdfInfos">文件大小:<span id="fileSize"></span></span>
</div>
<div style="position: relative;">
<div id="container"></div>
<img id="imgloading" style="position: absolute;top: 20%;left: 2%;display:none" src="loading.gif">
</div>
</body>
<script>
var currentPages,totalPages //聲明一個(gè)當(dāng)前頁碼及總頁數(shù)變量
var scale = 2; //設(shè)置縮放比例配阵,越大生成圖片越清晰
$('#chooseFile').change(function() {
var pdfFilePath = $('#chooseFile').val();
if(pdfFilePath) {
$("#imgloading").css('display','block');
$("#container").empty(); //清空上一PDF文件展示圖
currentPages=1; //重置當(dāng)前頁數(shù)
totalPages=0; //重置總頁數(shù)
var filesdata = $('#chooseFile')[0].files; //jquery獲取到文件 返回屬性的值
var fileSize = filesdata[0].size; //文件大小
var mb;
if(fileSize) {
mb = fileSize / 1048576;
if(mb > 10) {
alert("文件大小不能>10M");
return;
}
}
$("#fileName").text(filesdata[0].name);
$("#fileSize").text(mb.toFixed(2) + "Mb");
var reader = new FileReader();
reader.readAsDataURL(filesdata[0]); //將文件讀取為 DataURL
reader.onload = function(e) { //文件讀取成功完成時(shí)觸發(fā)
pdfjsLib.getDocument(this.result).then(function(pdf) { //調(diào)用pdf.js獲取文件
if(pdf) {
totalPages = pdf.numPages; //獲取pdf文件總頁數(shù)
$("#currentPages").text("1/");
$("#totalPages").text(totalPages);
//遍歷動(dòng)態(tài)創(chuàng)建canvas
for(var i = 1; i <= totalPages; i++) {
var canvas = document.createElement('canvas');
canvas.id = "pageNum" + i;
$("#container").append(canvas);
var context = canvas.getContext('2d');
renderImg(pdf,i,context);
}
}
});
};
}
});
//渲染生成圖片
function renderImg(pdfFile,pageNumber,canvasContext) {
pdfFile.getPage(pageNumber).then(function(page) { //逐頁解析PDF
var viewport = page.getViewport(scale); // 頁面縮放比例
var newcanvas = canvasContext.canvas;
//設(shè)置canvas真實(shí)寬高
newcanvas.width = viewport.width;
newcanvas.height = viewport.height;
//設(shè)置canvas在瀏覽中寬高
newcanvas.style.width = "100%";
newcanvas.style.height = "100%";
//默認(rèn)顯示第一頁馏颂,其他頁隱藏
if (pageNumber!=1) {
newcanvas.style.display = "none";
}
var renderContext = {
canvasContext: canvasContext,
viewport: viewport
};
page.render(renderContext); //渲染生成
});
$("#imgloading").css('display','none');
return;
};
//上一頁
$("#prevpage").click(function(){
if (!currentPages||currentPages <= 1) {
return;
}
nowpage=currentPages;
currentPages--;
$("#currentPages").text(currentPages+"/");
var prevcanvas = document.getElementById("pageNum"+currentPages);
var currentcanvas = document.getElementById("pageNum"+nowpage);
currentcanvas.style.display = "none";
prevcanvas.style.display = "block";
})
//下一頁
$("#nextpage").click(function(){
if (!currentPages||currentPages>=totalPages) {
return;
}
nowpage=currentPages;
currentPages++;
$("#currentPages").text(currentPages+"/");
var nextcanvas = document.getElementById("pageNum"+currentPages);
var currentcanvas = document.getElementById("pageNum"+nowpage);
currentcanvas.style.display = "none";
nextcanvas.style.display = "block";
})
//導(dǎo)出圖片
$("#exportImg").click(function() {
if (!$('#chooseFile').val()) {
alert('請先上傳pdf文件')
return false;
}
$("#imgloading").css('display','block');
var zip = new JSZip(); //創(chuàng)建一個(gè)JSZip實(shí)例
var images = zip.folder("images"); //創(chuàng)建一個(gè)文件夾用來存放圖片
//遍歷canvas,將其生成圖片放進(jìn)文件夾images中
$("canvas").each(function(index, ele) {
var canvas = document.getElementById("pageNum" + (index + 1));
//將圖片放進(jìn)文件夾images中
//參數(shù)1為圖片名稱棋傍,參數(shù)2為圖片數(shù)據(jù)(格式為base64救拉,需去除base64前綴 data:image/png;base64)
images.file("photo-" + (index + 1) + ".png", splitBase64(canvas.toDataURL("image/png", 1.0)), {
base64: true
});
})
//打包下載
zip.generateAsync({
type: "blob"
}).then(function(content) {
saveAs(content, "picture.zip"); //saveAs依賴的js文件是FileSaver.js
$("#imgloading").css('display','none');
});
});
//截取base64前綴
function splitBase64(dataurl) {
var arr = dataurl.split(',')
return arr[1]
}
function choosePdf(){
$("#chooseFile").click()
}
</script>
</html>
項(xiàng)目實(shí)現(xiàn)原理分析
- 首先利用pdf.js將上傳的pdf文件轉(zhuǎn)化成canvas
- 然后使用jszip.js將canvas打包圖片生成.zip文件
- 最后使用Filesaver.js將zip文件保存下載
項(xiàng)目注意要點(diǎn)
- 由于pdf文件是通過上傳的,因此需要通過js的FileReader()對象將其讀取為DataURL瘫拣,pdf.js文件才可讀取渲染
- JSZip對象的.file()函數(shù)中第二個(gè)參數(shù)傳入的是base64格式圖片亿絮,但是要去掉base64前綴標(biāo)識
最后
覺得文章不錯(cuò)的,請點(diǎn)個(gè)贊哇麸拄!
文章首發(fā)于微信公眾號:GitWeb派昧,歡迎關(guān)注學(xué)習(xí)技術(shù)討論交流。
微信交流群:公眾號內(nèi)加好友拢切,拉你入群