需求描述
公司之前设计的审核流程,审核人一栏使用的是文本信息。现根据甲方最新需求,在打印审批单时,需要在审核人一栏显示手写签名。
设计思路
- 设计独立的签名保存模块
- 将用户与签名图片进行关联
- 将图片信息以blob类型保存在数据库中(因为本次需要保存的数据量较小,故采取此种方式)
- 通过easyUI中的datagrid格式化函数,加载并显示图片
创建model&注解
package com.pms.model.system;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
/**
* 用户签名实体类
* @project 项目信息管理系统
* @author 张健
* @date 2017-06-02
* @version 1.0.0
* Copyright(c) YTANG All Rights Reserved
*/
@Entity
@Table(name="T_COMM_SIGN")
public class Sign implements Serializable {
private static final long serialVersionUID = -7302521238967771495L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID_")
protected Long id; //主键
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "USER_ID_", referencedColumnName = "ID_", foreignKey = @ForeignKey(name = "none"))
protected User user; //用户主键
@Lob
@Basic(fetch = FetchType.LAZY)
@Column(name = "IMGS_", columnDefinition = "BLOB",nullable=true)
private byte[] imgs;
@Column(name = "STATUS_")
protected Integer status; //0为锁定, 1为正常;负数为删除,前台可不见
@Column(name = "CREATE_DATE_")
protected Date createDate; //创建时间
@Column(name = "CREATE_USER_")
protected Long createUserId; //创建人
@Column(name = "UPDATE_DATE_")
protected Date updateDate; //最后一次修改时间
@Column(name = "UPDATE_USER_")
protected Long updateUserId; //最后一次修改人
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public byte[] getImgs() {
return imgs;
}
public void setImgs(byte[] imgs) {
this.imgs = imgs;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Long getCreateUserId() {
return createUserId;
}
public void setCreateUserId(Long createUserId) {
this.createUserId = createUserId;
}
public Date getUpdateDate() {
return updateDate;
}
public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
}
public Long getUpdateUserId() {
return updateUserId;
}
public void setUpdateUserId(Long updateUserId) {
this.updateUserId = updateUserId;
}
}
查看数据库
- 创建完注解式model后,运行系统,hebinate会自动创建数据表,上段代码创建的数据库表结构应如下:
设计上传页面
- 新建一个signEdit.jsp
- 页面主要提供两个功能,输入用户名和编号,并且选择待上传的文件
核心代码如下:
- 增加一个上传文件的input输入框,能够选择本地文件
<div>
<input type="file" name="uploadFile" multiple id="uploadFile" accept=".gif,.png"/ style="font-size: 10px;font-family: Microsoft YaHei;border-style: inset;border-width: 2px;padding: 1px;"></a>
</div>
- 增加一个点击按钮事件,能够将上传的文件保存到后台,此处引用了layer的确认组件,如果不需要删掉即可
function saveClick() {
layer.confirm('上传将会清空原有签名,是否继续操作?', {
btn: ['确认','取消'] //按钮
}, function(){
var index = layer.load();
$.ajaxFileUpload({
url:"${pageContext.request.contextPath}/system/sign/import.do",
secureuri: false,
fileElementId:"uploadFile",
dataType: 'text',
type:"POST",
success: function (data, status){
layer.close(index);
var res = data.substring((data.indexOf('>')+1),(data.indexOf('}')+1));
var json = $.parseJSON(res);
if (json.success) {
layer.msg(json.msg, {icon: 6, time: 1000}, function () {
closeClick();
});
parent.$("#dataGrid").datagrid('reload');
}else{
layer.msg(json.msg, {icon: 5});
}
},
error: function (data, status, e){
}
});
}, function(){
}
);
}
保存图片
- 在controller中增加import方法,将前台传过来的图片流保存到数据库中
@ResponseBody
@RequestMapping("/import")
public Json importByExcel(HttpSession session, @RequestParam("uploadFile") CommonsMultipartFile uplodaFile) {
Json json = new Json();
try {
// 根据选择的文件读取流
InputStream inputStream = uplodaFile.getInputStream();
//转换成byte[]
byte[] imgs = new byte[inputStream.available()];
inputStream.read(imgs);
Sign entity = new Sign();
entity.setImgs(imgs);
this.saveOrUpdate(entity);
json.setSuccess(true);
json.setMsg("签名上传成功");
}finally {
if(uplodaFile != null){
uplodaFile.getFileItem().getInputStream().close();
}
}catch (Exception e) {
log.error(message, e);
json.setSuccess(false);
json.setMsg("签名上传失败"+e.getMessage());
}
return json;
}
- 保存成功后,在数据库中应该imgs字段应该如下显示:
读取并显示图片
- 增加一个datagrid
- 给imgs字段,增加格式化函数
field: 'imgs',
title: '签名',
align: 'center',
width: 300,
sortable: false,
formatter: function (value, row, index) {
if (value == null) {
return "无签名图片";
}
return '<img src="${pageContext.request.contextPath}/system/sign/getImage.do?id='+row.id+'" style="width:100px;height:24px;"/>';
}
- 在后台controller中增加getImage方法
@ResponseBody
@RequestMapping("/getImage")
public void getImage(Long id,HttpServletRequest request,HttpServletResponse response) {
Sign entity = signService.findById(id);
byte[] license_img = entity.getImgs();
OutputStream os = null;
if(license_img!=null){
try {
/*response.setContentType("image/png");
os = response.getOutputStream();
os.write(license_img);
os.flush();
os.close();*/
BufferedImage image = ImageIO.read(new ByteArrayInputStream(license_img));
response.setContentType("image/png");
os = response.getOutputStream();
ImageIO.write(image, "gif", os);
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 显示效果如下