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 事件冒泡简介及应用
Jan 11 Javascript
jQuery实现公告文字左右滚动的实例代码
Oct 29 Javascript
初识angular框架后的所思所想
Feb 19 Javascript
js实现当鼠标移到表格上时显示这一格全部内容的代码
Jun 12 Javascript
JavaScript简单验证表单空值及邮箱格式的方法
Jan 20 Javascript
Vue.js中用webpack合并打包多个组件并实现按需加载
Feb 17 Javascript
详解AngularJS2 Http服务
Jun 26 Javascript
js 概率计算(简单版)
Sep 12 Javascript
vue自定义一个v-model的实现代码
Jun 21 Javascript
vue中子组件调用兄弟组件方法
Jul 06 Javascript
json 带斜杠时如何解析的实现
Aug 12 Javascript
vue登录以及权限验证相关的实现
Oct 25 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 $_SERVER详解
2009/01/16 PHP
使用PHP实现密保卡功能实现代码&amp;lt;打包下载直接运行&amp;gt;
2011/10/09 PHP
PHP三元运算符的结合性介绍
2012/01/10 PHP
php 获取今日、昨日、上周、本月的起始时间戳和结束时间戳的方法
2013/09/28 PHP
在win系统安装配置 Memcached for PHP 5.3 图文教程
2015/03/03 PHP
PHP读取配置文件类实例(可读取ini,yaml,xml等)
2015/07/28 PHP
使用xampp搭建运行php虚拟主机的详细步骤
2015/10/21 PHP
自写的利用PDO对mysql数据库增删改查操作类
2018/02/19 PHP
解决 FireFox 下[使用event很麻烦] 的问题.
2006/08/22 Javascript
javascript入门·图片对象(无刷新变换图片)\滚动图像
2007/10/01 Javascript
基于jquery的15款幻灯片插件
2011/04/10 Javascript
javascript笔记 String类replace函数的一些事
2011/09/22 Javascript
为JavaScript类型增加方法的实现代码(增加功能)
2011/12/29 Javascript
jQuery获取及设置表单input各种类型值的方法小结
2016/05/24 Javascript
JavaScript随机打乱数组顺序之随机洗牌算法
2016/08/02 Javascript
各式各样的导航条效果css3结合jquery代码实现
2016/09/17 Javascript
Json对象和字符串互相转换json数据拼接和JSON使用方式详细介绍(小结)
2016/10/25 Javascript
Angular2学习笔记——详解路由器模型(Router)
2016/12/02 Javascript
初探nodeJS
2017/01/24 NodeJs
node通过express搭建自己的服务器
2017/09/30 Javascript
微信小程序 如何引入外部字体库iconfont的图标
2018/01/31 Javascript
koa上传excel文件并解析的实现方法
2018/08/09 Javascript
Angularjs 根据一个select的值去设置另一个select的值方法
2018/08/13 Javascript
nodejs基础之多进程实例详解
2018/12/27 NodeJs
js获取本日、本周、本月的时间代码
2020/02/01 Javascript
vue实现图片上传到后台
2020/06/29 Javascript
[36:17]DOTA2上海特级锦标赛 - VGL音乐会全集
2016/03/06 DOTA
解析Python中的异常处理
2015/04/28 Python
python实现猜拳小游戏
2020/04/05 Python
python写一个随机点名软件的实例
2019/11/28 Python
Nike西班牙官方网站:Nike.com (ES)
2017/10/30 全球购物
加拿大时尚床上用品零售商:QE Home | Quilts Etc
2018/01/22 全球购物
教师四风问题整改措施
2014/09/25 职场文书
农村党员学习党的群众路线教育实践活动心得体会
2014/11/04 职场文书
白鹤梁导游词
2015/02/06 职场文书
高中班主任心得体会
2016/01/07 职场文书