JFinal

登录 注册

有没有jfinal批量生成二维码,并打包下载的例子。

最近要做个二维码管理平台,主要是为某一个企业生成二维码,数量在每次十万个左右。大佬们!帮帮忙啊。

评论

  • 03-12 18:49
    之前做了一版,但是生成,大致思路是在项目目录下生成了一个专门存放二维码的文件夹。然后生成二维码放在该文件夹里。再打包成zip文件下载,关闭输出流的时候删除之前生成的所有文件。但是方法执行的太慢了。感觉时间花在了生成文件和删除文件上了。有什么方法优化么?
  • 03-12 20:12
    每次生成的数量很多,可以用多线程并发去生成

    生成二维码的代码,拿到 jfinal 的 com.jfinal.render.QrRender.java 源码,将里头的输出 OutputStream 定向到你自己的 FileOutputStream 即可

    先搞定生成,然后用 java 自带的 visual vm 工具检查哪里是瓶颈,有针对性的优化性能即可
  • 03-13 12:05
    @JFinal 这个地方能不能不在服务器生成文件,然后执行下载呢,因为生成完成之后这些文件就没用了,后续的访问都是给页面code,页面自己根据code生成的二维码。
  • 03-13 14:13
    @CrazyZH 这个随便玩,B/S 架构在服务端生成为好。 C/S 架构可以考虑在客户端生成
  • 03-14 09:51
    @JFinal
    昨天又修改了下,生成二维码的方法:

    public class MyQrcodeRender extends Render{

    private String content;
    private int width;
    private int height;
    private ErrorCorrectionLevel errorCorrectionLevel;
    private String savePath; // 保存到那个地址
    private String urlStr; // 拼接在content前面的地址如http://....
    /**
    * 构造方法,经测试不指定纠错参数时,默认使用的是 'L' 最低级别纠错参数
    * @param content 二维码携带内容
    * @param width 二维码宽度
    * @param height 二维码高度
    */
    public MyQrcodeRender(String content, int width, int height, String savePath,String urlStr) {
    init(content, width, height, null, savePath, urlStr);
    }

    private void init(String content, int width, int height, ErrorCorrectionLevel errorCorrectionLevel, String savePath, String urlStr) {
    if (StrKit.isBlank(content)) {
    throw new IllegalArgumentException("content 不能为空");
    }
    if (width < 0 || height < 0) {
    throw new IllegalArgumentException("width 与 height 不能小于 0");
    }
    if(StrKit.isBlank(savePath)) {
    throw new IllegalArgumentException("savePath 保存地址不能为空");
    }
    this.content = content;
    this.width = width;
    this.height = height;
    this.errorCorrectionLevel = errorCorrectionLevel;
    this.savePath = savePath;
    this.urlStr = urlStr;
    }

    public void render() {
    /*response.setHeader("Pragma","no-cache");
    response.setHeader("Cache-Control","no-cache");
    response.setDateHeader("Expires", 0);
    response.setContentType("image/png");*/

    Map hints = new HashMap();
    hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
    hints.put(EncodeHintType.MARGIN, 0); //去掉白色边框,极度重要,否则二维码周围的白边会很宽
    if (errorCorrectionLevel != null) {
    hints.put(EncodeHintType.ERROR_CORRECTION, errorCorrectionLevel);
    }

    try {
    // MultiFormatWriter 可支持多种格式的条形码,在此直接使用 QRCodeWriter,通过查看源码可知少创建一个对象
    // BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);

    QRCodeWriter writer = new QRCodeWriter();
    BitMatrix bitMatrix = writer.encode(urlStr+content, BarcodeFormat.QR_CODE, width, height, hints);

    // 经测试 200 X 200 大小的二维码使用 "png" 格式只有 412B,而 "jpg" 却达到 15KB
    //MatrixToImageWriter.writeToStream(bitMatrix, "png", response.getOutputStream()); // format: "jpg"、"png"
    // String realPath = request.getServletContext().getRealPath("") + File.separator;
    String realPath = PathKit.getWebRootPath() + File.separator;
    File jiaFile = new File(realPath + savePath);// 判断文件夹是否存在,不存在则创建这个文件夹
    if (!jiaFile.exists()) {
    jiaFile.mkdirs();
    }
    String filePath = savePath + "/" + content + ".png";
    File outputFile = new File(realPath + filePath);
    //MatrixToImageWriter.writeToFile(bitMatrix, "png", outputFile);
    MatrixToImageWriter.writeToPath(bitMatrix, "png", outputFile.toPath());
    }catch (Exception e) {
    throw new RenderException(e);
    }
    }


    这么一改的话,一万个二维码文件是压缩后是9M多点,比之前的260多M小了好多好多。用时一分多钟,感觉上面的判断文件夹是否存在那个可以放在外面去会更好点。谢谢指点!
  • 03-14 09:52
    生成文件用多线程处理,一万个图片需要四十秒左右生成。
  • 03-14 13:32
    @CrazyZH jfinal 的 QrCodeRender 是严格试验过,尽可能保证二维码文件的体积最小,这样无论用于在 html 显示还是生成为文件,体积都非常小

    默认大小的二维码生成的图片大小为 412 个字节,已经是极小的体积
  • 发送