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中的prototype与面向对象的实例讲解
May 22 Javascript
jquery实现metro效果示例代码
Sep 06 Javascript
jQuery实现带有上下控制按钮的简单多行滚屏效果代码
Sep 04 Javascript
JavaScript事件学习小结(三)js事件对象
Jun 09 Javascript
jQuery获取多种input值的简单实现方法
Jun 20 Javascript
JavaScript实现的微信二维码图片生成器的示例
Oct 26 Javascript
详解Jquery EasyUI tree 的异步加载(遍历指定文件夹,根据文件夹内的文件生成tree)
Feb 11 Javascript
vue.js国际化 vue-i18n插件的使用详解
Jul 07 Javascript
vue的style绑定background-image的方式和其他变量数据的区别详解
Sep 03 Javascript
Django模板继承 extend标签实例代码详解
May 16 Javascript
javascript函数式编程基础
Sep 15 Javascript
JavaScript实现简单的音乐播放器
Aug 14 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设计模式(五)适配器模式Adapter实例详解【结构型】
2020/05/02 PHP
基于JQuery的密码强度验证代码
2010/03/01 Javascript
十个优秀的Ajax/Javascript实例网站收集
2010/03/31 Javascript
关于hashchangebroker和statehashable的补充文档
2011/08/08 Javascript
一些老手都不一定知道的JavaScript技巧
2014/05/06 Javascript
jQuery ajax调用WCF服务实例
2014/07/16 Javascript
JS限制文本框只能输入数字和字母方法
2015/02/28 Javascript
JavaScript实现自动消除按钮功能的方法
2015/08/05 Javascript
JS操作XML实例总结(加载与解析XML文件、字符串)
2015/12/08 Javascript
JS 日期与时间戮相互转化的简单实例
2016/06/22 Javascript
基于JS设计12306登录页面
2016/12/28 Javascript
JavaScript实现时钟滴答声效果
2017/01/29 Javascript
如何用JS/HTML将时间戳转换为“xx天前”的形式
2017/02/06 Javascript
JS 验证密码 不能为空,必须含有数字、字母、特殊字符,长度在8-12位
2017/06/21 Javascript
react 创建单例组件的方法
2018/04/26 Javascript
javascript原型链学习记录之继承实现方式分析
2019/05/01 Javascript
[05:17]DOTA2誓师:今天我们在这里 明天TI4等我!
2014/03/26 DOTA
python传递参数方式小结
2015/04/17 Python
Python的pycurl包用法简介
2015/11/13 Python
Python在图片中插入大量文字并且自动换行
2019/01/02 Python
PyQt5显示GIF图片的方法
2019/06/17 Python
详解将Pandas中的DataFrame类型转换成Numpy中array类型的三种方法
2019/07/06 Python
Django中celery执行任务结果的保存方法
2019/07/12 Python
django 读取图片到页面实例
2020/03/27 Python
Python 实现 T00ls 自动签到脚本代码(邮件+钉钉通知)
2020/07/06 Python
SEPHORA丝芙兰捷克官网:购买香水、化妆品和护肤品
2018/11/26 全球购物
Booking.com缤客中国:全球酒店在线预订网站
2020/05/03 全球购物
C语言编程题
2015/03/09 面试题
医药代表个人求职信范本
2013/12/19 职场文书
开门红主持词
2014/04/02 职场文书
幼儿园中班教师寄语
2014/04/03 职场文书
个人安全承诺书
2014/05/22 职场文书
公积金贷款承诺书
2015/04/30 职场文书
泰坦尼克号观后感
2015/06/04 职场文书
烛光里的微笑观后感
2015/06/17 职场文书
Win11右下角图标点了没反应怎么办?Win11点击右下角图标无反应解决方法汇总
2022/07/07 数码科技