起步软件技术论坛
搜索
 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 16471|回复: 15

[分享] 动态生成二维码,保存到blobImage,并在报表中显示

  [复制链接]

56

主题

233

帖子

903

积分

高级会员

Rank: 4

积分
903
QQ
发表于 2016-9-30 16:00:10 | 显示全部楼层 |阅读模式
版本: BeX5V3.5 小版本号:
数据库: Oracle 服务器操作系统: Windows 应用服务器: Tomcat
客户端操作系统: Windows 8 浏览器: Chrome
本帖最后由 cactus78 于 2016-10-21 10:10 编辑

找了半天,也没找到一个比较全面的能实现这个功能的帖子,发现好多人问,特分享出来,以便大家参考少走弯路。

参考帖子:
1、动态生成二维码,需要jquery.qrcode.min.js。
源码:https://github.com/haoxiaobo/jquery-qrcode

2、通过Canvas及File API缩放并上传图片
http://blog.csdn.net/renfufei/article/details/9836317        

2、BeX5 ---在报表中显示blobImage上传的图片:
http://bbs.wex5.com/forum.php?mo ... 3135&extra=page%3D4

进入正题:
一、首先生成二维码:
两种情况:
1、生成完毕,直接创建一个超链接,点击便可下载

  1.         Model.prototype.button1Click = function(event){
  2.                 var qrcodeElmt = this.getElementByXid("qrcode");//div的xid
  3.                 qrcodeElmt.innerHTML = "";
  4.                 $(qrcodeElmt).qrcode({
  5.                         render :"canvas",
  6.                         text: "http://www.baidu.com",
  7.                         height: 300,
  8.                         width: 300//,
  9.                         //src: 'img/head.png'
  10.                 });
  11.                 var cavas = qrcodeElmt.children[0];
  12.                 var imgUrl = cavas.toDataURL("image/png");
  13.                 var a = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
  14.                 a.href = imgUrl;
  15.                 a.download = "123";
  16.                 a.innerHTML = "下载图片"
  17.                 var event = document.createEvent('MouseEvents');
  18.                 event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
  19.                 a.dispatchEvent(event);
  20.         };
复制代码



2、生成完成后,用ajax保存到后台blobImage中:
首先,应该有一条相应的数据,(数据库表【对应的概念中的关系】中失少有两个blobImage的字段,一个存储blobImage的字段,类型blob,一个存储blobImage修改时间的字段,类型datetime;还得有个id字段)。
blobImage组件配置如下图:

2016-09-30_120712.jpg


  1.         Model.prototype.button1Click = function(event){
  2.                 var me = this;
  3.                 var blobImage = this.comp("blobImage1");//页面中的blobImage组件
  4.                 var fID = this.comp("dialogData").getValue(blobImage.blobConcept);//获得这条记录的fID(实际上就是概念名)
  5.                 var url = "http://www.baidu.com";

  6.                 var qrcodeElmt = this.getElementByXid("qrcode");
  7.                 qrcodeElmt.innerHTML = "";
  8.                 $(qrcodeElmt).qrcode({
  9.                         render :"canvas",
  10.                         text: url,//这是二维码内储存的信息
  11.                         height: 300,
  12.                         width: 300//,
  13.                         //src: 'img/head.png'
  14.                 });
  15.                 var cavas = qrcodeElmt.children[0];
  16.                 var imgData = cavas.toDataURL("image/png");
  17.                 //alert(imgData);
  18.                 var params = new Request.ActionParam();
  19.                 params.setString("blobDataModel", blobImage.blobDataModel);
  20.                 params.setString("blobConcept", blobImage.blobConcept);
  21.                 params.setString("blobRelation", blobImage.blobRelation);
  22.                 params.setString("blobLastModifiedRelation", blobImage.blobLastModifiedRelation);
  23.                 params.setString("limitSize", blobImage.limitSize);
  24.                 params.setString("blobConceptValue", fID);
  25.                 params.setString("blobData", imgData);
  26.                 //alert(imgData);
  27.                 Request.sendBizRequest({
  28.                         contentType : 'application/xml',//用application/json报错(好像是XX.toJSON不是方法),不知为啥
  29.                         //dataType : "json",
  30.                         context : me.getContext(),
  31.                         parameters : params,
  32.                         action : "blobUpdateAction",//懒了,用了系统的上传
  33.                         callback : function(callbackData) {
  34.                                         blobImage.refresh();//必须刷新,否则不显示
  35.                                         if(!callbackData.state){
  36.                                         Request.errorMessage(callbackData, "执行失败!", null, null);
  37.                                 }
  38.                         }
  39.                 });
  40.         };
复制代码

2016-09-30_141715.jpg

       二、保存到数据库
        process处理前事件,生成设备二维码,保存blobImage之前处理blobData数据,强烈建议自己写一个上传的Action
        挺简单的大概就是 update 概念名 (blob关系名, updatetime关系名) values (?, ?) where 概念名 = ?;再把3个值赋进去就行了。
         如果自定义上传Action就不需要下面这段代码了。

2016-09-30_131719.jpg

  1.         //生成设备二维码,保存blobImage之前处理blobData数据,
  2.         //把byte[]转成InputStream,否则报错,java.lang.IllegalArgumentException: argument type mismatch
  3.         public static void equipmentProcessBeforeBlobUpdateAction() throws IOException {
  4.                 String imageData = null;
  5.                 try{
  6.                         imageData = (String) ContextHelper.getRequestContext().getActionContext().getParameter("blobData");
  7.                 }catch(Exception e){
  8.                         return;//报错说明是系统按钮上传
  9.                 }
  10.                 imageData = imageData.substring(22);
  11.                 //System.out.println(imageData);
  12.                 BASE64Decoder decoder = new BASE64Decoder();
  13.                 byte[] data = decoder.decodeBuffer(imageData);
  14.                 for(int i=0; i < data.length; i++){
  15.                 if(data[i]<0)
  16.                 data[i] += 256;//调整异常数据
  17.                 }
  18.                 InputStream image = new ByteArrayInputStream(data);//把byte转成InputStream
  19.                 ContextHelper.getRequestContext().getActionContext().setParameter("blobData", image);
  20.         }
复制代码



三、在报表中显示:
要在报表中显示图片,需要将单元格设置成display-type:image,然后这个单元格关联的数据必须是一个图片的有效URL,所以需要自定义queryAction把blob下载下来,再组装一个URL,代码如下:

2016-09-30_154020.jpg



  1.         public static Table printMeterCard(String concept,String idColumn,String select,String from,String condition,List range,String filter,Boolean distinct,Integer offset,Integer limit,String columns,String orderBy,String aggregate,String aggregateColumns,Map variables,String dataModel,String fnModel){
  2.         //System.out.println("SELECT " + select + " FROM " + from + "; dataModel:" + dataModel);
  3.                 Table t = BizData.query(concept, idColumn, select, from, condition, range, filter, distinct, offset, limit, columns, orderBy, aggregate,
  4.                 aggregateColumns, variables, dataModel, fnModel);
  5.                 Iterator<Row> it = t.iterator();
  6.                 while (it.hasNext()) {
  7.                         Row r = it.next();
  8.                         String url = "/UI2/system/components/justep/blob/server/download.j"
  9.                         + "?process=/logistics/product/process/equipment/equipmentProcess" //流程名称
  10.                         + "&activity=printMeterCardActivity" //环节名称
  11.                         + "&action=blobDownloadAction" //调用的Action
  12.                         + "&blobDataModel=/logistics/product/data" //数据模块目录
  13.                         + "&blobConcept=PR_Equipment" //概念名
  14.                         + "&blobRelation=fQRCode" //关系名
  15.                         + "&blobConceptValue="
  16.                         + r.getValue("PR_Equipment")
  17.                         + "&$query-version="
  18.                         + com.justep.system.util.CommonUtils.createGUID()
  19.                         + "&bsessionid="
  20.                         + ActionUtils.getRequestContext().getSessionContext().getSessionID();

  21.                         r.setString("fRemark", url); //将url存入table对象,不用增加一个专门的url关系,随便设到一个不需要在报表中显示的关系中即可
  22.                 }
  23.                 return t;
  24.         }
复制代码


评分

参与人数 1威望 +20 收起 理由
Masion + 20 很给力!

查看全部评分

0

主题

79

帖子

325

积分

中级会员

Rank: 3Rank: 3

积分
325
QQ
发表于 2016-9-30 17:59:45 | 显示全部楼层
整理的很全,感谢分享
回复 支持 反对

使用道具 举报

718

主题

2841

帖子

5657

积分

论坛元老

Rank: 8Rank: 8

积分
5657
QQ
发表于 2016-10-6 20:16:15 | 显示全部楼层
很好,留个标记,要换了是我来做这个功能,肯定是在数据库里用一个字段,然后将这个字段通过JS生成二维码
WEX5初学者,欢迎初学者交流
QQ:597558229
tel:15857336322
回复 支持 反对

使用道具 举报

56

主题

233

帖子

903

积分

高级会员

Rank: 4

积分
903
QQ
 楼主| 发表于 2016-10-8 09:37:40 | 显示全部楼层
郭德成 发表于 2016-10-6 20:16
很好,留个标记,要换了是我来做这个功能,肯定是在数据库里用一个字段,然后将这个字段通过JS生成二维码 ...

是的,那样会好一点,以前没弄过,没经验。一开始思路是这样的,就按这个思路做了,结果遇到了一系列问题,正好借这个机会了解了blobImage的原理。
如果直接存储二维码信息的话,好像报表有个显示模式是二维码,不知道好用不。
如果不需要使用报表的话,二维码信息一般都是由其他字段组合而成的,就连字段都不用了。直接在前端组合再生成二维码,更简单,还方便修改。不过这样没弄过,哪位大侠弄过可以分享一下,大家参考。
回复 支持 反对

使用道具 举报

39

主题

168

帖子

421

积分

中级会员

Rank: 3Rank: 3

积分
421
QQ
发表于 2017-3-10 22:23:48 | 显示全部楼层
Uncaught TypeError: Cannot read property 'toDataURL' of undefined

这个是怎么回事呢?
回复 支持 反对

使用道具 举报

377

主题

2594

帖子

5117

积分

论坛元老

Rank: 8Rank: 8

积分
5117
QQ
发表于 2017-3-11 09:17:21 | 显示全部楼层
sweetluo 发表于 2017-3-10 22:23
Uncaught TypeError: Cannot read property 'toDataURL' of undefined

这个是怎么回事呢?

估计你是有什么地方拼写错误
长春鱼熊企业管理咨询有限公司



X5开发出入库培训视频
(出处: 起步论坛)
回复 支持 反对

使用道具 举报

39

主题

168

帖子

421

积分

中级会员

Rank: 3Rank: 3

积分
421
QQ
发表于 2017-3-11 09:25:55 | 显示全部楼层
这个位置没有太多的代码,照着他抄的,就是不行

// 初始化生成二维码
                        var q= this.getElementByXid('qrcode');               
                        $(q).qrcode({
                        render : "img", //渲染方式
                        text : this.comp("userData").val("userTj"), //url地址
                        height : 250,
                        width : 250,
                        src : imgurl //头像地址
                        });
                        //生成下载
                                /*
                                //var canvas  = document.getElementById("ex1");
                                //var dataUrl = canvas.toDataURL();
                                //var pixels = new Uint8Array(canvas.width * canvas.height * 4);
                                //gl.readPixels(0, 0, canvas.width, canvas.height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);

                                var cavas = q.children[0];
                var imgUrl = cavas.toDataURL("image/png"); //此处报错
                var a = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
                a.href = imgUrl;
                a.download = "123";
                a.innerHTML = "下载图片"
                var event = document.createEvent('MouseEvents');
                event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
                a.dispatchEvent(event);
                                */
回复 支持 反对

使用道具 举报

56

主题

233

帖子

903

积分

高级会员

Rank: 4

积分
903
QQ
 楼主| 发表于 2017-3-13 09:05:47 | 显示全部楼层
本帖最后由 cactus78 于 2017-3-13 09:09 编辑
sweetluo 发表于 2017-3-11 09:25
这个位置没有太多的代码,照着他抄的,就是不行

// 初始化生成二维码

1、你这个主要问题是第3行,应该是  render :"canvas",  canvas是HTML5的元素,才有toDataURl()方法,img没有这个方法。
2、还有第一行后面应该有q.innerHTML = "";否则第二次生成的二维码会在第一次生成的后面,第一次生成的不会消失。直接的后果是 var cavas = q.children[0] 永远得到的是第一次生成的。
3、你的src : imgurl 不知道这个变量imgurl之前定义过没有,否则也应该会报错。



回复 支持 反对

使用道具 举报

39

主题

168

帖子

421

积分

中级会员

Rank: 3Rank: 3

积分
421
QQ
发表于 2017-3-13 10:50:16 | 显示全部楼层

极光别名发送失败

谢谢,现在电脑上不报错了,但手机上还是不行,UC,微信都报错
111.jpg
回复 支持 反对

使用道具 举报

39

主题

168

帖子

421

积分

中级会员

Rank: 3Rank: 3

积分
421
QQ
发表于 2017-3-13 10:53:44 | 显示全部楼层
var imgurl=this.comp("userData").val("userPhoto");
                        if(imgurl==null || imgurl==""){imgurl="./intro/img/ico96-96.png";};
                        if(imgurl.substring(0,4) == "http"){
                                imgurl="./intro/img/ico96-96.png";
                        }
                       
                        //生成下载
                               
                                var qrcodeElmt = this.getElementByXid("qrcode");//div的xid
                qrcodeElmt.innerHTML = "";
                $(qrcodeElmt).qrcode({
                                //render : "img", //渲染方式
                        render :"canvas",
                        text: this.comp("userData").val("userTj"), //url地址
                        height: 250,
                        width: 250,
                        src : imgurl //头像地址
                });

                var cavas = qrcodeElmt.children[0];
                var imgUrl = cavas.toDataURL("image/png");
                var a = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
                a.href = imgUrl;
                a.download = "tuijian";
                a.innerHTML = "下载二维码"
                var event = document.createEvent('MouseEvents');
                event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
                a.dispatchEvent(event);
                       
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|X3技术论坛|Justep Inc.    

GMT+8, 2024-5-3 05:04 , Processed in 0.095460 second(s), 32 queries .

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表