前端合成二维码与背景图片,批量导出ZIP下载
背景:需要生成很多的二维码,并且结合背景图片一起生成图片,批量下载到本地,提供给打印厂商进行打印。
方案1:后台合成,后台提供下载.
方案2:前端合成,前端提供下载。
我选择了方案2。这个方案减轻后台压力,也不用后台保存图片。前端随时可以根据数据生成图片,自己下载。
直接上代码(前端页面有部分是用JADE模板写的)
生成二维码+合成背景图+打包
script(type='text/javascript', src='http://cdn.staticfile.org/jquery.qrcode/1.0/jquery.qrcode.min.js')
script(src='http://gildas-lormeau.github.io/zip.js/demos/zip.js')
script(src='http://gildas-lormeau.github.io/zip.js/demos/mime-types.js')
script(type='text/javascript', src='/javascripts/ZipArchive.js')
//- script(type='text/javascript', src='/javascripts/canvas-to-blob')
//- 导出图片的起名规则,柜机二维码用 型号名字 + index ,柜机格子名字用 模型名字 型号名字 + cell +index ,压缩名用 型号名
//- 标题 todo
label#modalname= vmModal.name + ' ' + vmModal.type
br
label(style={'visibility':'hidden','position':'absolute'})#elementCount= batchData.length
button#downloadPdf.btn.btn-info(type='button',onclick) 点击下载zip
<br>
<br>
table#xxxx
script.
var rowCount = document.getElementById("elementCount").innerHTML/1;
console.log('get row count = ',rowCount);
each rowValue,index in batchData
tr
td
- var rowId = 'vmDiv_'+index;
label(style={'visibility':'hidden','position':'absolute'})= rowId
div(id=rowId ,qrCode = rowValue.qrcode , style={'visibility':'hidden','position':'absolute'})
td
- var rowcaId = 'vmCanvas_'+index;
label(style={'visibility':'hidden'})= rowcaId
//- if rowValue.qc_pos != "0,0,0,0"
canvas(id=rowcaId,back_img_url=rowValue.back_img_url,name=rowValue.name,qc_pos=rowValue.qc_pos,wd_pos=rowValue.wd_pos,wd=rowValue.numMark )
//- td
//- label= rowValue.qrcode
//- <script src="./javascripts/jspdf.debug.js"></script>
//- <script src="./javascripts/html2canvas.js"></script>
canvas(id='allImage')
script.
var isDrawEnd = false;
$(function() {
$("#downloadPdf").click(function(){
if(!isDrawEnd){
return;
}
//切换到新增页面
var modalname = document.getElementById('modalname').innerHTML;
zipArc.export(modalname);
});
});
function draw(){
let allWidth = 0;
let allHeight = 0;
let maginBetween = 20;
let compinedImageCount = 0;
let willComC = rowCount;
for(let i=0;i<rowCount;i++){
var index = i;
let rowId = 'vmDiv_'+index;
let rowcaId = 'vmCanvas_'+index;
let qrOrigin = document.getElementById(rowId);
let qrCompined = document.getElementById(rowcaId);
let img=new Image;
img.crossOrigin = 'anonymous';
img.src = qrCompined.getAttribute('back_img_url');
img.onload=function(){
console.log("img width=",img.width,';img height=',img.height);
var qc_pos = qrCompined.getAttribute("qc_pos");
var wd_pos = qrCompined.getAttribute("wd_pos");
var wd = qrCompined.getAttribute("wd");
var qrCode = qrOrigin.getAttribute("qrCode");
var qrPosAry = qc_pos.split(',');
var wdPosAry = wd_pos.split(',');
console.log('create qr id='+rowId+'qrOrigin='+qrOrigin);
$(`#${rowId}`).qrcode({
render: "canvas", //table方式
width: qrPosAry[2], //宽度
height:qrPosAry[2], //高度
text: qrCode, //任意内容
correctLevel:1,
});
//画二维码
var c = qrCompined;
var ctx = c.getContext('2d');
c.width = img.width;
c.height = img.height;
//-ctx.rect(0,0,0,0);
ctx.rect(0,0,img.width,img.height);
ctx.fillStyle='red';
ctx.fill();
img.crossOrigin = 'anonymous';
//画背景
ctx.drawImage(img,0,0,img.width,img.height);
allWidth = Math.max(allWidth,img.width);
allHeight = allHeight + img.height + maginBetween;
//绘制二维码
qrOrigin.crossOrigin = 'anonymous';
ctx.drawImage(qrOrigin.firstChild,qrPosAry[0]/1,qrPosAry[1]/1,qrPosAry[2]/1,qrPosAry[3]/1);
//绘制序号
//设置字体样式
ctx.font = 'bold ' + wdPosAry[3]+'px FZDHTJW_0';
//设置字体填充颜色
console.log(wd_pos);
//- ctx.fillStyle='white';
//- ctx.fillRect(wdPosAry[0],wdPosAry[1],wdPosAry[2],wdPosAry[3]);
ctx.textAlign='center';
ctx.textBaseline="middle";
ctx.fillStyle = "black";
ctx.fillText(wd, parseInt(wdPosAry[0])+parseInt(wdPosAry[2])/2, parseInt(wdPosAry[1])+ parseInt(wdPosAry[3])/2 );
compinedImageCount++;
if(compinedImageCount == willComC){
//所有页面整合为一张
allImageTogether(allWidth,allHeight,maginBetween,compinedImageCount);
}
}
}
}
draw();
var zipArc = new ZipArchive;
console.log('zipArc=',zipArc);
function allImageTogether(allWidth,allHeight,maginBetween,compinedImageCount){
var modalname = document.getElementById('modalname').innerHTML;
//- console.log('sfasfsdfsf',modalname);
//- return;
console.log('totoal width,height=',allWidth+','+allHeight);
var pos = 0;
for(let i=0;i<compinedImageCount;i++){
let index = i;
let rowcaId = 'vmCanvas_'+index;
let qrCompined = document.getElementById(rowcaId);
let imageName = qrCompined.getAttribute('name');
qrCompined.crossOrigin = 'anonymous';
let image = qrCompined.toDataURL();
//- let image = qrCompined.toBlob();
var fileName = imageName + '[' + i + ']' + '.png';
zipArc.addFileImage(fileName,image);
//- ctx.drawImage(qrCompined,0,pos,qrCompined.width ,qrCompined.height);
//- pos += qrCompined.height + maginBetween;
}
isDrawEnd = true;
}
其他 js 代码:
http://download.youkuaiyun.com/detail/qhexin/9620442