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 学习第七课 扩展jQuery的功能 插件开发
May 17 Javascript
jquery的map与get方法详解
Nov 04 Javascript
javascript实现uploadify上传格式以及个数限制
Nov 23 Javascript
SpringMVC返回json数据的三种方式
Dec 10 Javascript
jQuery实现从身份证号中获取出生日期和性别的方法分析
Feb 25 Javascript
逻辑表达式中与或非的用法详解
Jun 06 Javascript
微信小程序中使元素占满整个屏幕高度实现方法
Dec 14 Javascript
jQuery实现6位数字密码输入框
Dec 29 Javascript
Bootstrap导航条学习使用(二)
Feb 08 Javascript
小程序日历控件使用方法详解
Dec 29 Javascript
Vue render函数实战之实现tabs选项卡组件
Apr 22 Javascript
vue 公共列表选择组件,引用Vant-UI的样式方式
Nov 02 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
提问的智慧
2006/10/09 PHP
PHP 替换模板变量实现步骤
2009/08/24 PHP
php ios推送(代码)
2013/07/01 PHP
php全角字符转换为半角函数
2014/02/07 PHP
php cli换行示例
2014/04/22 PHP
PHP使用json_encode函数时不转义中文的解决方法
2014/11/12 PHP
PHP 接入支付宝即时到账功能
2016/09/18 PHP
动态为事件添加js代码示例
2009/02/15 Javascript
cument.execCommand()用法深入理解
2012/12/04 Javascript
用javascript模仿ie的自动完成类似自动完成功的表单
2012/12/12 Javascript
在javascript中执行任意html代码的方法示例解读
2013/12/25 Javascript
用jquery写的菜单从左往右滑动出现
2014/04/11 Javascript
js图片模糊切换显示特效的方法
2015/02/17 Javascript
jQuery实现定时读取分析xml文件的方法
2015/07/16 Javascript
JS实现超简单的鼠标拖动效果
2015/11/02 Javascript
js阻止移动端页面滚动的两种方法
2017/01/25 Javascript
JavaScript实现瀑布流以及加载效果
2017/02/11 Javascript
React如何利用相对于根目录进行引用组件详解
2017/10/09 Javascript
利用SpringMVC过滤器解决vue跨域请求的问题
2018/02/10 Javascript
Node.js使用cookie保持登录的方法
2018/05/11 Javascript
微信小程序实现日期格式化和倒计时
2020/11/01 Javascript
Flexible.js可伸缩布局实现方法详解
2020/11/13 Javascript
Python 加密的实例详解
2017/10/09 Python
TensorFlow实现简单卷积神经网络
2018/05/24 Python
解决Django的request.POST获取不到内容的问题
2018/05/28 Python
详解Django的CSRF认证实现
2018/10/09 Python
django restframework serializer 增加自定义字段操作
2020/07/15 Python
浅谈python锁与死锁问题
2020/08/14 Python
Ticketmaster意大利:音乐会、节日、艺术和剧院的官方门票
2019/12/23 全球购物
介绍一下SQL注入攻击的种类和防范手段
2012/02/18 面试题
体育专业个人的求职信范文
2013/09/21 职场文书
五五普法心得体会
2014/09/04 职场文书
2015年度服装销售工作总结
2015/03/31 职场文书
团日活动总结格式
2015/05/11 职场文书
机关干部正风肃纪心得体会
2016/01/15 职场文书
Mysql中mvcc各场景理解应用
2022/08/05 MySQL