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 相关文章推荐
Js 获取当前日期时间及其它操作实现代码
Mar 04 Javascript
AppBaseJs 类库 网上常用的javascript函数及其他js类库写的
Mar 04 Javascript
封装了一个js图片轮换效果的函数
Sep 28 Javascript
JavaScritp添加url参数并将参数加入到url中及更改url参数的方法
Oct 26 Javascript
JavaScript调用传递变量参数的相关问题及解决办法
Nov 01 Javascript
jQuery常用的一些技巧汇总
Mar 26 Javascript
JavaScript如何实现跨域请求
Aug 05 Javascript
Node.js + Redis Sorted Set实现任务队列
Sep 19 Javascript
如何使用headjs来管理和异步加载js
Nov 29 Javascript
js时间戳格式化成日期格式的多种方法介绍
Feb 16 Javascript
4 种滚动吸顶实现方式的比较
Apr 09 Javascript
django简单的前后端分离的数据传输实例 axios
May 18 Javascript
详解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
用Zend Studio+PHPnow+Zend Debugger搭建PHP服务器调试环境步骤
2014/01/19 PHP
ThinkPHP模板判断输出Defined标签用法详解
2014/06/30 PHP
PHP里的单例类写法实例
2015/06/25 PHP
JSON两种结构之对象和数组的理解
2016/07/19 PHP
PHP设计模式(四)原型模式Prototype实例详解【创建型】
2020/05/02 PHP
js 自定义的联动下拉框
2010/02/07 Javascript
JavaScript DOM 学习第三章 内容表格
2010/02/19 Javascript
一个简单的JS时间控件示例代码(JS时分秒时间控件)
2013/11/22 Javascript
使用js判断TextBox控件值改变然后出发事件
2014/03/07 Javascript
Node.js中使用Buffer编码、解码二进制数据详解
2014/08/16 Javascript
全面解析JavaScript中的valueOf与toString方法(推荐)
2016/06/14 Javascript
js当前页面登录注册框,固定div,底层阴影的实例代码
2016/10/04 Javascript
详解jQuery简单的表单应用
2016/12/16 Javascript
深入理解ES7的async/await的用法
2017/09/09 Javascript
简单实现vue验证码60秒倒计时功能
2017/10/11 Javascript
Vue 使用 Mint UI 实现左滑删除效果CellSwipe
2018/04/27 Javascript
Nodejs实现多文件夹文件同步
2018/10/17 NodeJs
NodeJs crypto加密制作token的实现代码
2019/11/15 NodeJs
jquery制作的移动端购物车效果完整示例
2020/02/24 jQuery
js实现从右往左匀速显示图片(无缝轮播)
2020/06/29 Javascript
详解vue3中组件的非兼容变更
2021/03/03 Vue.js
[49:31]DOTA2-DPC中国联赛 正赛 Elephant vs LBZS BO3 第二场 1月29日
2021/03/11 DOTA
Django中实现一个高性能计数器(Counter)实例
2014/07/09 Python
微信跳一跳python自动代码解读1.0
2018/01/12 Python
详解Pandas之容易让人混淆的行选择和列选择
2019/07/10 Python
Python爬取爱奇艺电影信息代码实例
2019/11/26 Python
Canvas globalCompositeOperation
2018/12/18 HTML / CSS
澳大利亚运动鞋商店:Platypus Shoes
2019/09/27 全球购物
Oral-B荷兰:牙医最推荐的品牌
2020/02/25 全球购物
逻辑链路控制协议
2016/10/01 面试题
物理课外活动总结
2014/08/27 职场文书
2015年秋季新学期寄语
2015/03/25 职场文书
小区保洁员岗位职责
2015/04/10 职场文书
生活委员竞选稿
2015/11/21 职场文书
基于Golang 高并发问题的解决方案
2021/05/08 Golang
CSS 实现多彩、智能的阴影效果
2021/05/12 HTML / CSS