公司最近来了一个需求,需要将网页下载成pdf.在此期间,尝试了很多方法.

有尝试在前台使用html2canvas.js+jsPdf.js生成.不过尝试之后,这种方案就被pass掉了,原因是:

1.生成的pdf品质不高,不够清晰而且有样式丢失的情况.

2.html2canvas.js原理是将网页"截图"(遍历dom将每一个标签画在canvas中)后,再由jspdf.js将其转化成pdf,而生成pdf需要使用canvas.toDataUrl()方法.浏览器对此长度是有限制的.我的页面生成的canvas大概是220000+高度.明显已经超长了.就算使用toBlob()也达不到要求.

然后转换了思路,查阅了网上很多资料.尝试了用iText等方式进行转换.但是这种方式也不友好,对html页面要求比较严格.比如<br/>这样的标签是无法通过的.而且对中文支持也不太好,以及生成的pdf依旧会有样式丢失的情况存在.所以此方案也pass.

最后尝试使用wkhtmltopdf这个软件来进行转化.

1. 首先下载软件 官网:https://wkhtmltopdf.org/.

2. 选择合适的版本下载后直接进行安装.并配置环境变量.                                                                                                                                         

3.wkhtmltopdf使用非常简单,windows的cmd窗口输入命令行wkhtmltopdf  z:\firefox\123.html z:\firefox\12345.pdf

这样就可以将z盘下的firefox文件夹下的123.html转换成12345.pdf文件了.(此命令可以加参数,网站上很多有参数详解的,我就不在赘述了.)

4. 也可以直接将网页链接直接进行转换: wkhtmltopdf  www.baidu.com z:\firefox\12345.pdf (注:wkhtmltopdf html文件或链接 生成的pdf名.中间都有空格)

5.在java中实现调用wkhtmltopdf.

//wkhtmltopdf在系统中的路径private static String toPdfTool = "Z:\\wkhtmltopdf\\bin\\wkhtmltopdf.exe";
/*** html转pdf* @param srcPath html路径,可以是硬盘上的路径,也可以是网络路径* @param destPath pdf保存路径* @return 转换成功返回true*/public static boolean htmlToPdf(String srcPath, String destPath){File file = new File(destPath);File parent = file.getParentFile();//如果pdf保存路径不存在,则创建路径if(!parent.exists()){parent.mkdirs();}StringBuilder cmd = new StringBuilder();if(System.getProperty("os.name").indexOf("Windows") == -1){//linux 系统}cmd.append(toPdfTool);cmd.append(" ");//cmd.append(" --disable-javascript ");//页眉下面的线//cmd.append(" --header-center 这里是页眉这里是页眉这里是页眉这里是页眉 ");//页眉中间内容//cmd.append(" --margin-top 3cm ");//设置页面上边距 (default 10mm)//cmd.append(" --page-width 30cm ");//设置页面上边距 (default 10mm) //cmd.append(" --header-html file:///"+WebUtil.getServletContext().getRealPath("")+FileUtil.convertSystemFilePath("\\style\\pdf\\head.html"));// (添加一个HTML页眉,后面是网址)//cmd.append(" --header-spacing 5 ");// (设置页眉和内容的距离,默认0)//cmd.append(" --footer-center (设置在中心位置的页脚内容)");//设置在中心位置的页脚内容//cmd.append(" --footer-html file:///"+WebUtil.getServletContext().getRealPath("")+FileUtil.convertSystemFilePath("\\style\\pdf\\foter.html"));// (添加一个HTML页脚,后面是网址)//cmd.append(" --footer-line");//* 显示一条线在页脚内容上)//cmd.append(" --footer-spacing 5 ");// (设置页脚和内容的距离)cmd.append(srcPath);cmd.append(" ");cmd.append(destPath);boolean result = true;try{Process proc = Runtime.getRuntime().exec(cmd.toString());HtmlToPdfInterceptor error = new HtmlToPdfInterceptor(proc.getErrorStream());HtmlToPdfInterceptor output = new HtmlToPdfInterceptor(proc.getInputStream());error.start();output.start();proc.waitFor();}catch(Exception e){result = false;e.printStackTrace();}return true;}

我们的项目中使用security安全框架,所以直接放链接会有问题.所以采用将网页保存后再进行转换.这样的话,调用是没有问题了.

6.还有问题就是我需要将网页保存下来.先想使用js模拟按键ctrl+s保存,转念一想是行不通的.因为这种保存只能保存在客户端上.本地跑项目没问题,但是之后到服务器上就有大问题了.所以 多思考一下还是有点用的,至少可以少做点事.哈哈.

把网页保存下来也废了我不少功夫.从url流访问保存,到htmlunit爬取网页,方法都试了,可是因为项目的jsp使用异步ajax进行页面渲染.所以总是只能拿到初始的界面,htmlunit的等待js执行等方式都试过了,还是没有用.所以就采取了简单粗暴的办法.直接用js获取整个网页的代码.发送到后台.然后直接将string字符串生成一个html文件好了.(不知道会不会挨打)

7. 上述方式只有html代码,所以还需要将原网页的css文件拉下来先存到html读取的位置上去.后期能想到更好的办法再来替换吧,先出此下策了.

这样的话,就可以调用上面的方法进行html转换为pdf啦.

8.pdf生成之后,还需要给前台提供下载.这里又出现一个小问题.ajax方式里没有文件这种类型,所以不能使用ajax方式进行前后台交互.又是麻烦事.于是破罐子破摔.在html上加上一个input输入框.在页面渲染的方法的最后将整个网页的源码赋值给输入框.

var html=document.getElementsByTagName('html')[0].innerHTML;
$("#input").val(html);
<form method="POST" style="float:right;" target='ifr' action="xxx.do"><input id="input" name="html" type="text" style=" display:none;"/><button class="download-button" iconCls="icon-print" id="renderPdf" onclick="downloadPDF();">下载</button>
</form>
<iframe name='ifr' id="ifr" style='display: none;'></iframe>

下面的iframe是为了实现form表单提交时,页面不刷新.网上也有相关方法解释.

9.这样,终于快要大功告成,要实现html转pdf并下载了.

    /*** 下载成pdf* @param request* @return*/@RequestMapping(value="/xxx")@ResponseBodypublic Map<String, Object> downloadPdf(HttpServletRequest request,HttpServletResponse response){String html = request.getParameter("html");Map<String, Object> returnMap = new HashMap<String, Object>();String newDate = new Date().getTime()+"";String pdffileName = newDate + ".pdf";String htmlfileName = newDate + ".html";String pdfPath = PATH + pdffileName;String javaScriptStr = "<base href="+"\"http://localhost:8081/crs2/\""+">";html = html.replace(javaScriptStr, "");FileInputStream input = null;try {File file = new File(PATH + htmlfileName);if(!file.exists()){ file.createNewFile(); } byte bytes[]=new byte[1024];bytes=html.getBytes(); FileOutputStream fos=new FileOutputStream(file); fos.write(bytes);fos.close();HtmlToPdf.convert(PATH + htmlfileName,pdfPath);//根据文件名获取 MIME 类型String contentType = request.getServletContext().getMimeType(pdfPath);FileDownloadUtil.download(request, response, contentType, pdffileName, pdfPath);} catch (Exception e) {e.printStackTrace();} finally{if(input != null){try {input.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}returnMap.put("success", true);return returnMap;}

运行到HtmlToPdf.convert(PATH + htmlfileName,pdfPath)时,pdf文件已经生成.FileDownLoadUtil类是自己编写的下载类.就不贴出来了.代码亲测可用.不过应该网页超长加上自己电脑配置不高的情况下,从点击下载按钮,到弹出文件下载框的时间是有点久的.

学而不思则罔,想把自己学的东西记录下来.加油吧码农! 有大佬觉得哪里不合理的话,欢迎指点!!!

使用wkhtmltopdf将网页转换成pdf文件+前台下载相关推荐

  1. Python编程:使用wkhtmltopdf将html网页转成pdf文件

    官网:https://wkhtmltopdf.org/ github: https://github.com/wkhtmltopdf/wkhtmltopdf Mac环境: brew install C ...

  2. 网页html转为pdf,html页面转换成PDF文件

    html页面转换成PDF文件 发布时间:2020-06-14 05:24:50 来源:51CTO 阅读:523 作者:robinmars package pdftest; import java.io ...

  3. 在 Linux 中把一个网页转换成 PDF的技巧介绍

    你如何在 Linux 中把一个网页转换成 PDF?你可以选择使用每个 Linux 发行版上的网页浏览器(GUI),或者使用终端将网页变成 PDF 文件. 在这里,我将提到这两种方法来帮助你完成工作. ...

  4. java使用wkhtmltopdf将html转换成pdf

    使用wkhtmltopdf将html转换成pdf 安装wkhtmltopdf windows下载 window安装 linux安装 使用java调用wkhtmltopdf 注意 安装wkhtmltop ...

  5. wkhtmltopdf:wkhtmltopdf(将html转换成pdf的利器)简介、安装、使用方法详细攻略

    wkhtmltopdf:wkhtmltopdf(将html转换成pdf的利器)简介.安装.使用方法详细攻略 目录 wkhtmltopdf简介 wkhtmltopdf安装 wkhtmltopdf使用方法 ...

  6. 1604_linux环境下使用命令行把网页转换成pdf

    全部学习汇总: GreyZhang/toolbox: 常用的工具使用查询,非教程,仅作为自我参考! (github.com) 使用的工具很容易在彼此之间产生隔离性障碍,比如我最近使用的墨水屏阅读的最合 ...

  7. 如何将CAJ文件转换成PDF文件?教你一招搞定

    CAJ文件是中国知网的专用格式,主要用于存储学术文献等信息.由于这种格式并非常见格式,很多用户不知道如何打开或转换.如果您需要将CAJ文件转换成PDF文件,不必担心,您可以使用记灵在线工具来解决这个问 ...

  8. 在线caj转换成pdf文件的操作方法

    在线caj转换成pdf文件的操作方法 现在我看到caj就头痛的厉害,因为我是在网上下载论文的时候遇到的,而且网上的论文基本都是caj格式,我头痛是因为我不会转换caj文件,所以小编我自己找了在线的方法 ...

  9. python怎么变成文档_python3如何将docx转换成pdf文件

    本文实例为大家分享了python3将docx转换成pdf文件的具体代码,供大家参考,具体内容如下 直接上代码 # -*- encoding:utf-8 -*- """ a ...

  10. tif文件转pdf_PPT怎么转换成PDF文件?可以帮到你的PPT转PDF方法

    PPT怎么转换成PDF文件?大家在平时的工作与学习中肯定接触且使用过PPT.PDF这两种格式的文件,随之就会有将PPT转换成PDF文件的需求.这是由于PPT文件兼容性比较差,不同设备打开文件的效果不同 ...

最新文章

  1. 面试使用计算机,面试相关之计算机基础
  2. 注册app短信验证平台_短信验证码平台能免费测试吗?怎么测试?
  3. JQuery Mobile 手机显示页面偏小
  4. 第一个程序---汇编学习笔记
  5. JNI实现源码分析【四 函数调用】
  6. 动态规划--目标和问题
  7. 利用Gitee搭建个人图床(下)
  8. printf()的冷门用法+格子中输出--蓝桥杯
  9. [科普]关于文件头的那些事
  10. C语言图形库函数easyx下载
  11. matlab 平滑曲线连接_用MATLAB做数据拟合究竟有多直观
  12. java 解析umd文件_Javascript模块化编程之CommonJS,AMD,CMD,UMD模块加载规范详解
  13. 杭州师范大学计算机科学与技术怎么样,杭州师范大学怎么样 王牌专业有哪些...
  14. 数据分析师面试常见的77个问题
  15. 如何更改iPhone备份和iTunes MobileSync备份文件夹的位置
  16. Python海龟画图 画一个爱心 赶快给女朋友来一个
  17. 区块链能否助力版权“突围”?
  18. 准备春招 CSDN博客不定期脱更 见谅
  19. 树莓派入门(三)之步进电机控制
  20. 编程语言的自举之路——从机器码到高级语言

热门文章

  1. ArcGIS 矢量数据的合并
  2. MapGIS矢量数据的误差校正
  3. NES模拟器[H_NES]
  4. 当代中国社会划分为十大阶层
  5. linux正则表达式大全,正则表达式,正则表达式语法大全
  6. 漫画×雕塑 | 之于表达
  7. java环境手机版_Java环境搭建
  8. 使用Java打印三角形
  9. 优秀关卡设计的十个原则
  10. 生信常用分析图形绘制02 -- 解锁火山图真谛!