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实现ASP分页函数 HTML分页函数
Sep 22 Javascript
用Jquery实现可编辑表格并用AJAX提交到服务器修改数据
Dec 27 Javascript
JS.findElementById()使用介绍
Sep 21 Javascript
js判断字符长度及中英文数字等
Mar 19 Javascript
使用jQuery管理选择结果
Jan 20 Javascript
深入理解node exports和module.exports区别
Jun 01 Javascript
JavaScript实现九九乘法表的简单实例
Jun 07 Javascript
BootStrap 超链接变按钮的实现方法
Sep 25 Javascript
在vue项目中,使用axios跨域处理
Mar 07 Javascript
vue2过滤器模糊查询方法
Sep 16 Javascript
angular4笔记系列之内置指令小结
Nov 09 Javascript
vue项目多环境配置(.env)的实现
Jul 21 Vue.js
详解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
eWebEditor v3.8 商业完整版 (PHP)
2006/12/06 PHP
PHP学习之字符串比较和查找
2011/04/17 PHP
30 个很棒的PHP开源CMS内容管理系统小结
2011/10/14 PHP
关于PHP结束标签的使用细节探讨及联想
2013/03/04 PHP
php中操作memcached缓存进行增删改查数据的实现代码
2014/08/15 PHP
一个简单安全的PHP验证码类 附调用方法
2016/06/24 PHP
PHP三种方式实现链式操作详解
2017/01/21 PHP
如何让动态插入的javascript脚本代码跑起来。
2007/01/09 Javascript
Javascript String对象扩展HTML编码和解码的方法
2009/06/02 Javascript
Firefox和IE兼容性问题及解决方法总结
2013/10/08 Javascript
js使用eval解析json(js中使用json)
2014/01/17 Javascript
5种处理js跨域问题方法汇总
2014/12/04 Javascript
javascript实现简单的贪吃蛇游戏
2015/03/31 Javascript
巧用jQuery选择器提高写表单效率的方法
2016/08/19 Javascript
Vue.js动态添加、删除选题的实例代码
2016/09/30 Javascript
bootstrap jquery dataTable 异步ajax刷新表格数据的实现方法
2017/02/10 Javascript
详解vue模拟加载更多功能(数据追加)
2017/06/23 Javascript
实例学习JavaScript读取和写入cookie
2018/01/29 Javascript
Vue2.0 实现歌手列表滚动及右侧快速入口功能
2018/08/08 Javascript
vue实现移动端图片上传功能
2019/12/23 Javascript
js实现select下拉框选择
2020/01/11 Javascript
vue 解决addRoutes多次添加路由重复的操作
2020/08/04 Javascript
Vue执行方法,方法获取data值,设置data值,方法传值操作
2020/08/05 Javascript
Python使用scrapy抓取网站sitemap信息的方法
2015/04/08 Python
Python读写Json涉及到中文的处理方法
2016/09/12 Python
Python实现的直接插入排序算法示例
2018/04/29 Python
pytorch训练imagenet分类的方法
2018/07/27 Python
Python sklearn KFold 生成交叉验证数据集的方法
2018/12/11 Python
python从入门到精通 windows安装python图文教程
2019/05/18 Python
荷兰时尚精品店:Labels Fashion
2020/03/22 全球购物
10的分与合教学反思
2014/04/30 职场文书
离婚协议书范本及离婚须知
2014/10/15 职场文书
先进党组织事迹材料
2014/12/26 职场文书
小升初自荐信范文
2015/03/05 职场文书
暑期社会实践个人总结
2015/03/06 职场文书
SpringBoot接入钉钉自定义机器人预警通知
2022/07/15 Java/Android