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 相关文章推荐
使用prototype.js 的时候应该特别注意的几个问题.
Apr 12 Javascript
动态表格Table类的实现
Aug 26 Javascript
JS实现向表格中动态添加行的方法
Mar 30 Javascript
JavaScript中使用指数方法Math.exp()的简介
Jun 15 Javascript
详解JavaScript中双等号引起的隐性类型转换
May 30 Javascript
javascript闭包功能与用法实例分析
Apr 06 Javascript
Javascript实现跨域后台设置拦截的方法详解
Aug 04 Javascript
Javascript实现购物车功能的详细代码
May 08 Javascript
微信小程序实现批量倒计时功能
Nov 01 Javascript
JS数组方法join()用法实例分析
Jan 18 Javascript
ES6学习笔记之字符串、数组、对象、函数新增知识点实例分析
Jan 22 Javascript
JS正则表达式验证密码强度
Mar 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中数字0和空值的区别分析
2014/06/05 PHP
让jQuery与其他JavaScript库并存避免冲突的方法
2013/12/23 Javascript
jquery中的常用事件bind、hover、toggle等示例介绍
2014/07/21 Javascript
js实现匹配时换色的输入提示特效代码
2015/08/17 Javascript
JS获取IMG图片高宽的简单实例
2016/05/17 Javascript
jQuery validate插件功能与用法详解
2016/12/15 Javascript
layer子层给父层页面元素赋值,以达到向父层页面传值的效果实例
2017/09/22 Javascript
详解cordova打包成webapp的方法
2017/10/18 Javascript
利用Javascript获取选择文本所在的句子详解
2017/12/03 Javascript
vue自动化表单实例分析
2018/05/06 Javascript
微信小程序时间标签和时间范围的联动效果
2019/02/15 Javascript
react同构实践之实现自己的同构模板
2019/03/13 Javascript
在Vue项目中,防止页面被缩放和放大示例
2019/10/28 Javascript
详解vue3.0 的 Composition API 的一种使用方法
2020/10/26 Javascript
python 获取文件列表(或是目录例表)
2009/03/25 Python
深入理解Python中的元类(metaclass)
2015/02/14 Python
Python实现从log日志中提取ip的方法【正则提取】
2018/03/31 Python
详解利用django中间件django.middleware.csrf.CsrfViewMiddleware防止csrf攻击
2018/10/09 Python
Django学习之文件上传与下载
2019/10/06 Python
使用python+whoosh实现全文检索
2019/12/09 Python
用Python去除图像的黑色或白色背景实例
2019/12/12 Python
Python使用graphviz画流程图过程解析
2020/03/31 Python
Python3实现个位数字和十位数字对调, 其乘积不变
2020/05/03 Python
CSS3 border-image详解、应用及jQuery插件
2011/08/29 HTML / CSS
HTML5组件Canvas实现图像灰度化(步骤+实例效果)
2013/04/22 HTML / CSS
打印机墨盒:123Inkjets
2017/02/16 全球购物
Ramy Brook官网:美国现代女装品牌
2019/06/18 全球购物
受欢迎的大学生自我评价
2013/12/05 职场文书
法定代表人身份证明书(含说明)
2014/10/02 职场文书
升职感谢信
2015/01/22 职场文书
稽核岗位职责范本
2015/04/13 职场文书
被委托人身份证明
2015/08/07 职场文书
2016重阳节红领巾广播稿
2015/12/18 职场文书
2016年万圣节活动总结
2016/04/05 职场文书
SQL之各种join小结详细讲解
2021/08/04 MySQL
Spring Bean是如何初始化的详解
2022/03/22 Java/Android