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 相关文章推荐
jquery 文本上下无缝滚动,鼠标放上去就停止 小例子
Jun 05 Javascript
js中top的作用深入剖析
Mar 04 Javascript
JS根据变量保存方法名并执行方法示例
Apr 04 Javascript
使用javascript实现简单的选项卡切换
Jan 09 Javascript
javascript实现拖放效果
Dec 16 Javascript
jQuery Timelinr实现垂直水平时间轴插件(附源码下载)
Feb 16 Javascript
js简单时间比较的方法
Aug 02 Javascript
canvas实现简易的圆环进度条效果
Feb 28 Javascript
JS实现的将html转为pdf功能【基于浏览器端插件jsPDF】
Feb 06 Javascript
javascript数组去重方法总结(推荐)
Mar 20 Javascript
基于VUE实现判断设备是PC还是移动端
Jul 03 Javascript
js 数组当前行添加数据方法详解
Jul 28 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通过文件头检测文件类型通用代码类(zip,rar等)
2010/10/19 PHP
php中将网址转换为超链接的函数
2011/09/02 PHP
用ADODB.Stream转换
2007/01/22 Javascript
js 强制弹出窗口代码研究-又一款代码
2010/03/20 Javascript
js RuntimeObject() 获取ie里面自定义函数或者属性的集合
2010/11/23 Javascript
如何使用jquery动态加载js,css文件实现代码
2013/04/03 Javascript
onkeyup,onkeydown和onkeypress的区别介绍
2013/10/21 Javascript
JavaScript中的继承方式详解
2015/02/11 Javascript
javascript实现将文件保存到本地方法汇总
2015/07/26 Javascript
jquery实现鼠标滑过显示二级下拉菜单效果
2015/08/24 Javascript
Boostrap入门准备之border box
2016/05/09 Javascript
js阻止默认浏览器行为与冒泡行为的实现代码
2016/05/15 Javascript
基于JS实现checkbox全选功能实例代码
2016/10/31 Javascript
jQuery+Ajax请求本地数据加载商品列表页并跳转详情页的实现方法
2017/07/12 jQuery
vue.js学习笔记之v-bind和v-on解析
2018/05/03 Javascript
JavaScript实现异步图像上传功能
2018/07/12 Javascript
Vue递归实现树形菜单方法实例
2018/11/06 Javascript
构建Vue大型应用的10个最佳实践(小结)
2019/11/07 Javascript
JavaScript实现手机号码 3-4-4格式并控制新增和删除时光标的位置
2020/06/02 Javascript
vue 使用class创建和清除水印的示例代码
2020/12/25 Vue.js
python打开url并按指定块读取网页内容的方法
2015/04/29 Python
python中实现数组和列表读取一列的方法
2018/04/03 Python
python使用正则筛选信用卡
2019/01/27 Python
Django model select的多种用法详解
2019/07/16 Python
python通过TimedRotatingFileHandler按时间切割日志
2019/07/17 Python
Python程序慢的重要原因
2020/09/04 Python
基于python实现复制文件并重命名
2020/09/16 Python
Java的基础面试题附答案
2016/01/10 面试题
升旗仪式演讲稿
2014/05/08 职场文书
特教教师先进事迹
2014/05/21 职场文书
歌颂党的演讲稿
2014/09/10 职场文书
个人总结与自我评价
2014/09/18 职场文书
2015年毕业生实习评语
2015/03/25 职场文书
担保贷款承诺书
2015/04/30 职场文书
美容院员工规章制度
2015/08/05 职场文书
2019年健身俱乐部的创业计划书
2019/08/26 职场文书