将html页面保存成图片,图片写入pdf的实现方法(推荐)


Posted in Javascript onSeptember 17, 2016

需求是一个导出pdf的功能,多方奔走终于实现了,走了不少弯路,而且怀疑现在这个方法仍是弯的。

有个jsPDF 插件可以在前端直接生成pdf,很简便,但不支持IE。

前端:

首先引入  html2canvas.js

html2canvas(document.body, { //截图对象
     //此处可配置详细参数
     onrendered: function(canvas) { //渲染完成回调canvas
       canvas.id = "mycanvas"; 
       // 生成base64图片数据
       var dataUrl = canvas.toDataURL('image/png');  //指定格式,也可不带参数
       var formData = new FormData(); //模拟表单对象
       formData.append("imgData", convertBase64UrlToBlob(dataUrl), "123.png"); //写入数据
       var xhr = new XMLHttpRequest(); //数据传输方法
       xhr.open("POST", "../bulletin/exportPdf"); //配置传输方式及地址
       xhr.send(formData);
       xhr.onreadystatechange = function(){ //回调函数
         if(xhr.readyState == 4){
            if (xhr.status == 200) {
               var back = JSON.parse(xhr.responseText);
               if(back.success == true){
                 alertBox({content: 'Pdf导出成功!',lock: true,drag: false,ok: true});
               }else{
                 alertBox({content: 'Pdf导出失败!',lock: true,drag: false,ok: true});
               }
            }
         }
       };
     }
}); 
  
//将以base64的图片url数据转换为Blob
function convertBase64UrlToBlob(urlData){
  //去掉url的头,并转换为byte
  var bytes=window.atob(urlData.split(',')[1]);    
  //处理异常,将ascii码小于0的转换为大于0
  var ab = new ArrayBuffer(bytes.length);
  var ia = new Uint8Array(ab);
  for (var i = 0; i < bytes.length; i++) {
    ia[i] = bytes.charCodeAt(i);
  }
  return new Blob( [ab] , {type : 'image/png'});
}

兼容性:Firefox 3.5+, Chrome, Opera, IE10+

不支持:iframe,浏览器插件,Flash

跨域图片需要在跨域服务器header加上允许跨域请求

access-control-allow-origin: *  access-control-allow-credentials: true

svg图片不能直接支持,已经有补丁包了,不过我没有试过。

IE9不支持FormData数据格式,也不支持Blob,这种情况下将canvas生成的64base字符串去掉url头之后直接传给后台,后台接收之后:

String base64 = Img.split(",")[1];
BASE64Decoder decode = new BASE64Decoder(); 
byte[] imgByte = decode.decodeBuffer(base64);

后端:

导入 itext jar包

 

@RequestMapping("/exportPdf")
public @ResponseBody void exportPdf(MultipartHttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {
  ResultData result = new ResultData();  //自定义结果格式
  String filePath = "c:\\exportPdf2.pdf";
  String imagePath = "c:\\exportImg2.bmp";
  Document document = new Document(); 
  try{
    Map getMap = request.getFileMap();
    MultipartFile mfile = (MultipartFile) getMap.get("imgData"); //获取数据
    InputStream file = mfile.getInputStream();
    byte[] fileByte = FileCopyUtils.copyToByteArray(file);
      
    FileImageOutputStream imageOutput = new FileImageOutputStream(new File(imagePath));//打开输入流
    imageOutput.write(fileByte, 0, fileByte.length);//生成本地图片文件
    imageOutput.close();
      
    PdfWriter.getInstance(document, new FileOutputStream(filePath)); //itextpdf文件
//    document.setPageSize(PageSize.A2);
    document.open();
    document.add(new Paragraph("JUST TEST ..."));
    Image image = Image.getInstance(imagePath); //itext-pdf-image
    float heigth = image.getHeight(); 
        float width = image.getWidth(); 
        int percent = getPercent2(heigth, width);  //按比例缩小图片
        image.setAlignment(Image.MIDDLE); 
        image.scalePercent(percent+3);
    document.add(image);
    document.close();
  
    result.setSuccess(true);
    operatelogService.addOperateLogInfo(request, "导出成功:成功导出简报Pdf");
  }catch (DocumentException de) {
    System.err.println(de.getMessage());
  }
  catch (Exception e) {
    e.printStackTrace();
    result.setSuccess(false);
    result.setErrorMessage(e.toString());
    try {
      operatelogService.addOperateLogError(request, "导出失败:服务器异常");
    } catch (Exception e1) {
      e1.printStackTrace();
    }
  }
  response.getWriter().print(JSONObject.fromObject(result).toString());
}

private static int getPercent2(float h, float w) {
  int p = 0;
  float p2 = 0.0f;
  p2 = 530 / w * 100;
  p = Math.round(p2);
  return p;
}

 iText是著名的开放源码的站点sourceforge一个项目,是用于生成PDF文档的一个java类库。

处理速度快,支持很多PDF"高级"特性。

但是itext出错的时候不会报错,直接跳过去,回头看pdf文档损坏,找不到出错原因,真是急死人。

最后感谢网络上有关的博文和贴子以及百度搜索。

以上这篇将html页面保存成图片,图片写入pdf的实现方法(推荐)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript 实现??打印?理
Apr 28 Javascript
JQuyer $.post 与 $.ajax 访问WCF ajax service 时的问题需要注意的地方
Sep 20 Javascript
jquery 插件学习(三)
Aug 06 Javascript
基于jQuery实现下拉收缩(展开与折叠)特效
Dec 25 Javascript
使用jQuery清空file文件域的解决方案
Apr 12 Javascript
jquery DIV撑大让滚动条滚到最底部代码
Jun 06 Javascript
javascript中apply和call方法的作用及区别说明
Feb 14 Javascript
HTML页面登录时的JS验证方法
May 28 Javascript
vue2.0组件之间传值、通信的多种方式(干货)
Feb 10 Javascript
jquery 动态遍历select 赋值的实例
Sep 12 jQuery
JS array数组检测方式解析
May 19 Javascript
JS setTimeout与setInterval的区别
Apr 20 Javascript
jquery遍历标签中自定义的属性方法
Sep 17 #Javascript
jquery属性,遍历,HTML操作方法详解
Sep 17 #Javascript
详解Angular2中的编程对象Observable
Sep 17 #Javascript
详细总结Javascript中的焦点管理
Sep 17 #Javascript
js变量提升深入理解
Sep 16 #Javascript
再谈javascript常见错误及解决方法
Sep 16 #Javascript
使用JQuery中的trim()方法去掉前后空格
Sep 16 #Javascript
You might like
php基础知识:类与对象(4) 范围解析操作符(::)
2006/12/13 PHP
第三章 php操作符与控制结构代码
2011/12/30 PHP
php程序总是提示验证码输入有误解决方案
2015/01/07 PHP
Laravel实现autoload方法详解
2017/05/07 PHP
JAVASCRIPT 对象的创建与使用
2021/03/09 Javascript
js数组Array sort方法使用深入分析
2013/02/21 Javascript
JavaScript实现继承的4种方法总结
2014/10/16 Javascript
JavaScript分页功能的实现方法
2015/04/25 Javascript
JavaScript的设计模式经典之代理模式
2016/02/24 Javascript
基于jquery实现的鼠标悬停提示案例
2016/12/11 Javascript
详解vue的数据binding绑定原理
2017/04/12 Javascript
JavaScript 高性能数组去重的方法
2018/09/20 Javascript
[05:15]2018年度CS GO社区贡献奖-完美盛典
2018/12/16 DOTA
python二分法实现实例
2013/11/21 Python
Python按行读取文件的简单实现方法
2016/06/22 Python
解决python3 urllib 链接中有中文的问题
2018/07/16 Python
详解Python中的内建函数,可迭代对象,迭代器
2019/04/29 Python
使用Python轻松完成垃圾分类(基于图像识别)
2019/07/09 Python
python抓取多种类型的页面方法实例
2019/11/20 Python
Python: 传递列表副本方式
2019/12/19 Python
美国大型的健身社区和补充商店:Bodybuilding.com
2016/09/06 全球购物
我们是伦敦女孩:WalG
2018/01/08 全球购物
以工厂直接定价的传奇性能:Ben Hogan Golf
2019/01/04 全球购物
如何保障Web服务器安全
2014/05/05 面试题
旷课检讨书1000字
2014/02/14 职场文书
党的群众路线教育实践活动实施方案
2014/10/31 职场文书
交通事故一次性赔偿协议书范本
2014/11/02 职场文书
2015年宣传部部长竞选演讲稿
2014/11/28 职场文书
2015年专项整治工作总结
2015/04/03 职场文书
2015年出纳工作总结与计划
2015/05/18 职场文书
投诉书格式范本
2015/07/02 职场文书
2016庆祝国庆67周年宣传语
2015/11/25 职场文书
会计工作自我鉴定范文
2019/06/21 职场文书
如何撰写出一份完美的商业计划书?
2019/07/12 职场文书
教你用eclipse连接mysql数据库
2021/04/22 MySQL
python中取整数的几种方法
2021/11/07 Python