将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判断数组中是否有重复值得三种实用方法
Aug 16 Javascript
浅析return false的正确使用
Nov 04 Javascript
JavaScript获取flash对象与网上的有所不同
Apr 21 Javascript
JavaScript中的ArrayBuffer详细介绍
Dec 08 Javascript
通过js获取上传的图片信息(临时保存路径,名称,大小)然后通过ajax传递给后端的方法
Oct 01 Javascript
jQuery动态添加及删除表单上传元素的方法(附demo源码下载)
Jan 15 Javascript
JavaScript自定义浏览器滚动条兼容IE、 火狐和chrome
Jan 05 Javascript
JS库之wow.js使用方法
Sep 14 Javascript
js中的 || 与 &amp;&amp; 运算符详解
May 24 Javascript
JS字符串与二进制的相互转化实例代码详解
Jun 28 Javascript
利用Vue的v-for和v-bind实现列表颜色切换
Jul 17 Javascript
解决Vue中的生命周期beforeDestory不触发的问题
Jul 21 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连接MySQL的2种方法小结以及防止乱码
2014/03/11 PHP
PHP简单实现合并2个数字键数组值的方法
2017/05/30 PHP
对于Laravel 5.5核心架构的深入理解
2018/02/22 PHP
初学Javascript的一些总结
2008/11/03 Javascript
33个优秀的jQuery 教程分享(幻灯片、动画菜单)
2011/07/08 Javascript
Javascript 鼠标移动上去 滑块跟随效果代码分享
2013/11/23 Javascript
兼容所有浏览器的js复制插件Zero使用介绍
2014/03/19 Javascript
JavaScript导出Excel实例详解
2014/11/25 Javascript
在Node.js应用中使用Redis的方法简介
2015/06/24 Javascript
jQuery用FormData实现文件上传的方法
2016/11/21 Javascript
详解基于javascript实现的苹果系统底部菜单
2016/12/02 Javascript
微信小程序实现动态设置页面标题的方法【附源码下载】
2017/11/29 Javascript
react 实现页面代码分割、按需加载的方法
2018/04/03 Javascript
vue数组对象排序的实现代码
2018/06/20 Javascript
webpack打包多页面的方法
2018/11/30 Javascript
Nodejs中怎么实现函数的串行执行
2019/03/02 NodeJs
解决vue打包后vendor.js文件过大问题
2019/07/03 Javascript
nuxt.js服务端渲染中axios和proxy代理的配置操作
2020/11/06 Javascript
[02:51]2018年度DOTA2最佳中单位选手-完美盛典
2018/12/17 DOTA
python比较两个列表大小的方法
2015/07/11 Python
python入门教程 python入门神图一张
2018/03/05 Python
Python 访问限制 private public的详细介绍
2018/10/16 Python
利用python实现短信和电话提醒功能的例子
2019/08/08 Python
python根据多个文件名批量查找文件
2019/08/13 Python
Python3操作Excel文件(读写)的简单实例
2019/09/02 Python
基于Python+Appium实现京东双十一自动领金币功能
2019/10/31 Python
Windows+Anaconda3+PyTorch+PyCharm的安装教程图文详解
2020/04/03 Python
python 多线程爬取壁纸网站的示例
2021/02/20 Python
ProBikeKit新西兰:自行车套件,跑步和铁人三项装备
2017/04/05 全球购物
Casadei卡萨蒂官网:意大利奢侈鞋履品牌
2017/10/28 全球购物
Martinelli官方商店:西班牙皮鞋和高跟鞋品牌
2019/07/30 全球购物
线程的基本概念、线程的基本状态以及状态之间的关系
2012/10/26 面试题
JVM是一个编译程序还是解释程序
2012/09/11 面试题
日语专业毕业生求职信
2013/12/04 职场文书
绿色学校实施方案
2014/03/31 职场文书
保安辞职信范文
2015/02/28 职场文书