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 相关文章推荐
JavaScript经典效果集锦
Jul 06 Javascript
子窗体与父窗体传值示例js代码
Aug 01 Javascript
js使用循环清空某个div中的input标签值
Sep 29 Javascript
js实现类似于add(1)(2)(3)调用方式的方法
Mar 04 Javascript
AngularJS基础学习笔记之指令
May 10 Javascript
AngularJS中的Directive实现延迟加载
Jan 25 Javascript
基于JavaScript实现 网页切出 网站title变化代码
Apr 03 Javascript
JS实现兼容火狐及IE iframe onload属性的遮罩层隐藏及显示效果
Aug 23 Javascript
jQuery实现简单的tab标签页效果
Sep 12 Javascript
jQuery在header中设置请求信息的方法
Mar 06 Javascript
vue开发环境配置跨域的方法步骤
Jan 16 Javascript
vue-simple-uploader上传成功之后的response获取代码
Sep 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
星际争霸 Starcraft 游戏介绍
2020/03/14 星际争霸
php var_export与var_dump 输出的不同
2013/08/09 PHP
php使用pear_smtp发送邮件
2016/04/15 PHP
laravel 5.1下php artisan migrate的使用注意事项总结
2017/06/07 PHP
经验几则 推荐
2006/09/05 Javascript
一个不错的用JavaScript实现的UBB编码函数
2007/03/09 Javascript
真正的JQuery.ajax传递中文参数的解决方法
2011/05/28 Javascript
通过JS获取用户本地图片路径并显示的代码
2012/02/16 Javascript
jQuery中siblings()方法用法实例
2015/01/08 Javascript
EasyUI,点击开启编辑框,并且编辑框获得焦点的方法
2015/03/01 Javascript
JS对字符串编码的几种方式使用指南
2015/05/14 Javascript
jQuery实现的五子棋游戏实例
2015/06/13 Javascript
通用javascript代码判断版本号是否在版本范围之间
2015/11/29 Javascript
js中数组结合字符串实现查找(屏蔽广告判断url等)
2016/03/30 Javascript
js中编码函数:escape,encodeURI与encodeURIComponent详解
2017/03/21 Javascript
AjaxUpLoad.js实现文件上传
2018/03/05 Javascript
浅析Vue中method与computed的区别
2018/03/06 Javascript
Angularjs之如何在跨域请求中传输Cookie的方法
2018/06/01 Javascript
AngularJS 多指令Scope问题的解决
2018/10/25 Javascript
vue实现购物车选择功能
2020/01/10 Javascript
微信小程序动态添加和删除组件的现实
2020/02/28 Javascript
vue实现打地鼠小游戏
2020/08/21 Javascript
[15:39]教你分分钟做大人:龙骑士
2014/10/30 DOTA
python通过加号运算符操作列表的方法
2015/07/28 Python
python添加模块搜索路径方法
2017/09/11 Python
已安装tensorflow-gpu,但keras无法使用GPU加速的解决
2020/02/07 Python
Python OpenCV去除字母后面的杂线操作
2020/07/05 Python
编写html5时调试发现脚本php等网页js、css等失效
2013/12/31 HTML / CSS
开朗女孩的自我评价
2014/02/10 职场文书
初中军训感想300字
2014/03/05 职场文书
演讲稿的格式及范文
2014/08/22 职场文书
2016圣诞节贺卡寄语
2015/12/07 职场文书
党风廉洁教育心得体会
2016/01/20 职场文书
python实现高效的遗传算法
2021/04/07 Python
apache基于端口创建虚拟主机的示例
2021/04/22 Servers
PostgreSQL基于pgrouting的路径规划处理方法
2022/04/18 PostgreSQL