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 相关文章推荐
jquery选择器之属性过滤选择器详解
Jan 27 Javascript
JS在IE下缺少标识符的错误
Jul 23 Javascript
JavaScript中的对象序列化介绍
Dec 30 Javascript
自己动手写的javascript前端等待控件
Oct 30 Javascript
Bootstrap中CSS的使用方法
Feb 17 Javascript
利用Node.JS实现邮件发送功能
Oct 21 Javascript
实现一个完整的Node.js RESTful API的示例
Sep 29 Javascript
vue源码入口文件分析(推荐)
Jan 30 Javascript
如何为你的JavaScript代码日志着色详解
Apr 08 Javascript
jQuery操作attr、prop、val()/text()/html()、class属性
May 23 jQuery
微信小程序 textarea 层级过高问题简单解决方案
Oct 14 Javascript
解决Vue-Router升级导致的Uncaught (in promise)问题
Aug 07 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
PHP 彩色文字实现代码
2009/06/29 PHP
CI框架整合widget(页面格局)的方法
2016/05/17 PHP
ucenter中词语过滤原理分析
2016/07/13 PHP
Laravel服务容器绑定的几种方法总结
2020/06/14 PHP
IE7提供XMLHttpRequest对象为兼容
2007/03/08 Javascript
比较全面的event对像在IE与FF中的区别 推荐
2009/09/21 Javascript
javascript:void(0)是什么意思及href=#与href=javascriptvoid(0)的区别
2015/11/13 Javascript
Bootstrap3使用typeahead插件实现自动补全功能
2016/07/07 Javascript
微信小程序 开发经验整理
2017/02/15 Javascript
详解nodejs的express如何自动生成项目框架
2017/07/12 NodeJs
详解vue mint-ui源码解析之loadmore组件
2017/10/11 Javascript
JavaScript变量声明var,let.const及区别浅析
2018/04/23 Javascript
layui 富文本编辑器和textarea值的相互传递方法
2019/09/18 Javascript
原生JS与JQ获取元素的区别详解
2020/02/13 Javascript
vant 中van-list的用法说明
2020/11/11 Javascript
Python实现获取网站PR及百度权重
2015/01/21 Python
Python常用的日期时间处理方法示例
2015/02/08 Python
Python多进程并发与多线程并发编程实例总结
2018/02/08 Python
Request的中断和ErrorHandler实例解析
2018/02/12 Python
python2和python3的输入和输出区别介绍
2018/11/20 Python
在PyCharm下打包*.py程序成.exe的方法
2018/11/29 Python
python使用socket实现的传输demo示例【基于TCP协议】
2019/09/24 Python
python使用协程实现并发操作的方法详解
2019/12/27 Python
tensorflow入门:tfrecord 和tf.data.TFRecordDataset的使用
2020/01/20 Python
Python模块 _winreg操作注册表
2020/02/05 Python
Python 生成短8位唯一id实战教程
2021/01/13 Python
python中numpy数组与list相互转换实例方法
2021/01/29 Python
岗位职责风险点
2014/03/12 职场文书
领导班子群众路线与四风问题对照检查材料思想汇报
2014/10/11 职场文书
单位实习鉴定评语
2015/01/04 职场文书
务工证明怎么写
2015/06/18 职场文书
关于感恩的作文
2019/08/26 职场文书
Python实现的扫码工具居然这么好用!
2021/06/07 Python
详解Java ES多节点任务的高效分发与收集实现
2021/06/30 Java/Android
MySql数据库触发器使用教程
2022/06/01 MySQL
微信小程序实现轮播图指示器
2022/06/25 Javascript