JavaScript+Java实现HTML页面转为PDF文件保存的方法


Posted in Javascript onMay 30, 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)); //写入数据
       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包(官方下载地址:https://sourceforge.net/projects/itext/)

@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"高级"特性。

Javascript 相关文章推荐
另类调用flash无须激活的方法
Dec 27 Javascript
js对数字的格式化使用说明
Jan 12 Javascript
一个关于jqGrid使用的小例子(行按钮)
Nov 04 Javascript
cookie 最近浏览记录(中文escape转码)具体实现
Jun 08 Javascript
jQuery中animate()方法用法实例
Dec 24 Javascript
jquery文档操作wrap()方法实例简述
Jan 10 Javascript
jQuery animate easing使用方法图文详解
Jun 17 Javascript
JavaScript简单拖拽效果(1)
May 17 Javascript
jquery Ajax实现Select动态添加数据
Jun 08 jQuery
react native带索引的城市列表组件的实例代码
Aug 08 Javascript
快速搭建Node.js(Express)用户注册、登录以及授权的方法
May 09 Javascript
vue实现简单数据双向绑定
Apr 28 Vue.js
详解JavaScript中双等号引起的隐性类型转换
May 30 #Javascript
JavaScript中的操作符类型转换示例总结
May 30 #Javascript
jQuery中的通配符选择器使用总结
May 30 #Javascript
移动端jQuery修正Web页面滑动时div问题的两则实例
May 30 #Javascript
jQuery增加和删除表格项目及实现表格项目排序的方法
May 30 #Javascript
使用jQuery判断浏览器滚动条位置的方法
May 30 #Javascript
JS检测移动端横竖屏的代码
May 30 #Javascript
You might like
收音机的保养
2021/03/01 无线电
PHP中去除换行解决办法小结(PHP_EOL)
2011/11/27 PHP
php解析xml提示Invalid byte 1 of 1-byte UTF-8 sequence错误的处理方法
2013/11/14 PHP
PHP会话控制:Session与Cookie详解
2014/09/27 PHP
php正确输出json数据的实例讲解
2018/08/21 PHP
把textarea中字符串里含有的回车换行替换成&amp;lt;br&amp;gt;的javascript代码
2007/04/20 Javascript
CSS和JS标签style属性对照表(方便js开发的朋友)
2010/11/11 Javascript
可自己添加html的伪弹出框实现代码
2013/09/08 Javascript
js获取时间并实现字符串和时间戳之间的转换
2015/01/05 Javascript
JS实现灵巧的下拉导航效果代码
2015/08/25 Javascript
Javascript中作用域的详细介绍
2016/10/06 Javascript
Vue.js学习示例分享
2017/02/05 Javascript
微信小程序 扎金花简单实例
2017/02/21 Javascript
基于jquery实现二级联动效果
2017/03/30 jQuery
微信小程序wx.getImageInfo()如何获取图片信息
2018/01/26 Javascript
Vue.js组件通信之自定义事件详解
2019/10/19 Javascript
vue+ts下对axios的封装实现
2020/02/18 Javascript
js删除对象中的某一个字段的方法实现
2021/01/11 Javascript
Python编码类型转换方法详解
2016/07/01 Python
Pycharm取消py脚本中SQL识别的方法
2018/11/29 Python
Python基于numpy模块实现回归预测
2020/05/14 Python
python中requests模拟登录的三种方式(携带cookie/session进行请求网站)
2020/11/17 Python
selenium3.0+python之环境搭建的方法步骤
2021/02/01 Python
First Aid Beauty官网:FAB急救面霜
2018/05/24 全球购物
哄娃神器4moms商店:美国婴童用品品牌
2019/03/07 全球购物
Canal官网:巴西女性时尚品牌
2019/10/16 全球购物
师范教师大学生职业生涯规划范文
2014/01/05 职场文书
厂区绿化方案
2014/05/08 职场文书
应急处置方案
2014/06/16 职场文书
人事行政经理岗位职责
2014/06/18 职场文书
法院授权委托书格式
2014/09/28 职场文书
公司股份转让协议书范本
2015/01/28 职场文书
公务员政审个人总结
2015/02/12 职场文书
2015廉洁自律个人总结
2015/02/14 职场文书
看上去很美观后感
2015/06/10 职场文书
原型和原型链 prototype和proto的区别详情
2021/11/02 Javascript