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处理VBArray的函数使用说明
May 11 Javascript
根据一段代码浅谈Javascript闭包
Dec 14 Javascript
如何使用json在前后台进行数据传输实例介绍
Apr 11 Javascript
JavaScript中匿名、命名函数的性能测试
Sep 04 Javascript
js原生Ajax的封装和原理详解
Mar 11 Javascript
基于js中style.width与offsetWidth的区别(详解)
Nov 12 Javascript
JavaScript简单实现关键字文本搜索高亮显示功能示例
Jul 25 Javascript
element UI upload组件上传附件格式限制方法
Sep 04 Javascript
微信小程序实现滑动切换自定义页码的方法分析
Dec 29 Javascript
jquery操作select常见方法大全【7种情况】
May 28 jQuery
Vue中常用rules校验规则(实例代码)
Nov 14 Javascript
JavaScript大数相加相乘的实现方法实例
Oct 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
需要注意的几个PHP漏洞小结
2012/02/05 PHP
详解Yii2 rules 的验证规则
2016/12/02 PHP
PHP实现表单提交数据的验证处理功能【防SQL注入和XSS攻击等】
2017/07/21 PHP
jQuery弹出(alert)select选择的值
2013/04/21 Javascript
intro.js 页面引导简单用法 分享
2013/08/06 Javascript
通过$(this)使用jQuery包装后的方法或属性
2014/05/18 Javascript
PHP配置文件php.ini中打开错误报告的设置方法
2015/01/09 PHP
jQuery超精致图片轮播幻灯片特效代码分享
2015/09/10 Javascript
Jquery全屏相册插件zoomvisualizer具有调节放大与缩小功能
2015/11/02 Javascript
Javascript操作dom对象之select全面解析
2017/04/24 Javascript
解决Vue页面固定滚动位置的处理办法
2017/07/13 Javascript
Vue框架中正确引入JS库的方法介绍
2017/07/30 Javascript
jQuery Layer弹出层传值到父页面的实现代码
2017/08/17 jQuery
Javasript设计模式之链式调用详解
2018/04/26 Javascript
vue中slot(插槽)的介绍与使用
2018/11/12 Javascript
JavaScript函数式编程(Functional Programming)声明式与命令式实例分析
2019/05/21 Javascript
JavaScript Html实现移动端红包雨功能页面
2021/01/10 Javascript
Python中的模块导入和读取键盘输入的方法
2015/10/16 Python
fastcgi文件读取漏洞之python扫描脚本
2017/04/23 Python
Python md5与sha1加密算法用法分析
2017/07/14 Python
Python排序搜索基本算法之归并排序实例分析
2017/12/08 Python
基于python OpenCV实现动态人脸检测
2018/05/25 Python
pycharm配置git(图文教程)
2019/08/16 Python
python sorted函数原理解析及练习
2020/02/10 Python
SQL Server数据库笔试题和答案
2016/02/04 面试题
你对IPv6了解程度
2016/02/09 面试题
27个经典Linux面试题及答案,你知道几个?
2013/01/10 面试题
幼儿园家长评语
2014/02/10 职场文书
学生违反校规检讨书
2014/10/28 职场文书
2015年上半年信访工作总结
2015/03/30 职场文书
家庭贫困证明
2015/06/16 职场文书
厉行节约工作总结
2015/08/12 职场文书
热爱劳动主题班会
2015/08/14 职场文书
改进工作作风心得体会
2016/01/23 职场文书
详解Mysql 函数调用优化
2021/04/07 MySQL
python引入其他文件夹下的py文件具体方法
2021/05/23 Python