将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 相关文章推荐
js png图片(有含有透明)在IE6中为什么不透明了
Feb 07 Javascript
初窥JQuery(二) 事件机制(1)
Nov 25 Javascript
jquery封装的对话框简单实现
Jul 21 Javascript
javascript移动设备Web开发中对touch事件的封装实例
Jun 05 Javascript
jQuery实现下拉框功能实例代码
May 06 Javascript
微信小程序(应用号)简单实例应用及实例详解
Sep 26 Javascript
jquery easyui dataGrid动态改变排序字段名的方法
Mar 02 Javascript
基于Vue实现拖拽功能
Jul 29 Javascript
node.js部署之启动后台运行forever的方法
May 23 Javascript
Vue.js 中 axios 跨域访问错误问题及解决方法
Nov 21 Javascript
Vue.js中该如何自己维护路由跳转记录
May 19 Javascript
JS数据类型判断的几种常用方法
Jul 07 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三元运算符知识汇总
2015/07/02 PHP
PHP strip_tags() 去字符串中的 HTML、XML 以及 PHP 标签的函数
2016/05/22 PHP
微信公众号开发之通过接口删除菜单
2017/02/20 PHP
php实现的错误处理封装类实例
2017/06/20 PHP
php 判断IP为有效IP地址的方法
2018/01/28 PHP
QQ邮箱的一个文本编辑器代码
2007/03/14 Javascript
jquery ready()的几种实现方法小结
2010/06/18 Javascript
js克隆对象、数组的常用方法介绍
2013/09/26 Javascript
js报$ is not a function 的问题的解决方法
2014/01/20 Javascript
jQuery 鼠标经过(hover)事件的延时处理示例
2014/04/14 Javascript
详解 javascript中offsetleft属性的用法
2015/11/11 Javascript
Backbone.js框架中Model与Collection的使用实例
2016/05/07 Javascript
基于touch.js手势库+zepto.js插件开发图片查看器(滑动、缩放、双击缩放)
2016/11/17 Javascript
JS中用childNodes获取子元素换行会产生一个子元素
2016/12/08 Javascript
JavaScript数据结构中栈的应用之表达式求值问题详解
2017/04/11 Javascript
jquery实现图片放大点击切换
2017/06/06 jQuery
vue中appear的用法
2017/08/17 Javascript
javaScript中的空值和假值
2017/12/18 Javascript
详解Nodejs内存治理
2018/05/13 NodeJs
vue.js 2.0实现简单分页效果
2019/07/29 Javascript
react国际化化插件react-i18n-auto使用详解
2020/03/31 Javascript
[58:54]EG vs RNG 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/18 DOTA
使用Protocol Buffers的C语言拓展提速Python程序的示例
2015/04/16 Python
Python通过matplotlib绘制动画简单实例
2017/12/13 Python
详解Tensorflow数据读取有三种方式(next_batch)
2018/02/01 Python
python 文件转成16进制数组的实例
2018/07/09 Python
python使用requests模块实现爬取电影天堂最新电影信息
2019/04/03 Python
PyQt5图形界面播放音乐的实例
2019/06/17 Python
HTML5事件方法全部汇总
2016/05/12 HTML / CSS
AJAX的优缺点都有什么
2015/08/18 面试题
个人查摆剖析材料
2014/02/04 职场文书
心理健康活动总结
2014/04/30 职场文书
师范大学生求职信
2014/06/13 职场文书
公安局班子个人对照检查材料思想汇报
2014/10/09 职场文书
2015年度酒店客房部工作总结
2015/05/25 职场文书
导游词书写之黄山
2019/08/06 职场文书