最近在做试卷相关的业务,碰到一个场景,需要将试卷在移动端进行卷面还原,考虑到在WEB端实现的A4的样式在移动端上不好实现且比较难看,最终选择通过图片进行预览,这样在移动端也可以进行缩放查看。
业务流程
- 创建试卷卷面
- 将卷面保存为图片
- 在移动端直接展示图片
流程比较简单,下面主要说下关于图片生成以及保存这部分的实现。
使用插件
html2canvas
canvas转图片
图片上传保存
html2canvas
该插件可以实现,将某些HTML中的dom转化成canvas进行展现,使用非常简单,而且还原度相当高。
插件地址:http://html2canvas.hertzen.com/
使用起来超级简单:
html2canvas(document.querySelector("#capture")).then(canvas => {
document.body.appendChild(canvas)
});
将canvas生成图片
代码如下:
let dataurl = canvas.toDataURL('image/png');
上面是将canvas转成base64的字符串,下面将字符串转成form表单中的File对象,然后通过异步将文件保存。
let dataurl = canvas.toDataURL('image/png');
let arr = dataurl.split(',');
let mime = arr[0].match(/:(.*?);/)[1];
let suffix = mime.split('/')[1];
let bstr = atob(arr[1]);
let n = bstr.length;
let u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
//生成File对象
let file = new File([u8arr], `preview.${suffix}`, {type: mime});
let fd = new FormData();
fd.append("file",file);
fd.append("module","preview");
$.ajax({
type : 'post',
url : base+'/file/upload',
data : fd,
processData: false,
contentType:false,
success : function(res){
if(res.success){
resolve(res);
}else{
reject(res.msg);
}
},
error : function(e){
reject("图片信息保存失败,请刷新后重试!");
}
});
关于后台接受
至于下面后端接收图片并处理的这里简单放下代码就不说明了,我这是传到了FTP服务器上保存的,后端是基于spring-boot框架实现的。
/**
* 单文件上传
*
* @param file
* @param request
* @return
*/
@PostMapping("/upload")
@ResponseBody
public Map upload(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
//返回MAP 给前台数据使用
String module = request.getParameter("module");
Map map = new HashMap();
if (!file.isEmpty()) {
try {
String fileName = file.getOriginalFilename();
Attachment attach = new Attachment();
attach.setId(new Uuid().getUUID());
attach.setSystem("smartteaching");
attach.setFileName(fileName);
attach.setModule(module);
attach.setSuffix(FileUtil.getFileExt(fileName));
FtpStorageHandlerImpl fshl = new FtpStorageHandlerImpl();
fshl.upload(file.getInputStream(), attach);
map.put("filePath", attach.getFilePath());
map.put("fileSize", file.getSize());
map.put("fileName", attach.getFileName());
map.put("suffix", attach.getSuffix());
map.put("success", true);
} catch (IOException e) {
e.printStackTrace();
map.put("success", false);
map.put("msg", "上传失败");
}
return map;
} else {
map.put("success", false);
map.put("msg", "文件不存在或为空");
return map;
}
}
结束
到了这一步,完整的从前端将DOM生成图片,并将图片上传至后端就完成了。