注册/登录

教你两招,轻松搞定Html页面导出为Pdf文件

网络 通信技术
本文主要介绍了如何将html页面导出为pdf文件,希望给遇到类似需求的小伙伴一点思路,以后说不定用得到。

[[398656]]

本文转载自微信公众号「爱写Bug的麦洛」,作者麦洛。转载本文请联系爱写Bug的麦洛公众号。

Hi,大家好,我是麦洛,最近项目中遇到了将html页面导出为pdf文件,现在将相关内容分享出来,希望帮到有需要的伙伴

在招投标软件中,每个标段结束评标之后,都会生成评标报告

评标报告主要包含项目信息,标段信息,投标人信息,投标人报价,评标专家打分等情况,相对来说信息量还是比较大,假如我们要导出评标报告该如何做?

  • html页面直接导出为pdf
  • 后端组装页面,导出pdf
  • 对比两种方式,很明显第一种方式优越性更好。即方便实现,又避免了由于页面的变动而需要改动导出功能代码的尴尬

    查阅了一些资料,目前市面上流行的解决方案主要有以下几种

  • wkhtmltopdf
  • iText
  • html2canvas+jsPDF
  • 其中前面两种为后端实现方式,第三种为纯前端实现方式;

    首先让我们来看一下wkhtmltopdf

    从github上可以看出,wkhtmltopdf的Star数量总共有11.1K,由此可见他的火爆程度。经过测验以后,我发现他的效果也是最好的。但是由于我们的项目采用了vue,貌似它不支持vue语法。所以我这边最后只能退而求其次,使用了其他技术来实现。

    接着我们来看一下html2canvas+jsPDF的方式

    这种方式是采用以上两个开源项目来实现。网上把它称作是一种曲线救国的方式。首先我们利用html2canvas将HTML网页保存成canvas图片,然后我们在利用jsPDF将canvas图片生成PDF文件。所以最终我们拿到的PDF文件并不是真正意义上的PDF文件,而是一张图片。这也导致我们无法编辑PDF文件。而且质量也一般。

    最后我们来看一看iText

    itext7好像是最新版本,这种方式适合于维护PDF模板然后动态添加内容,有需要的小伙伴可以了解一下。

    由于我们的项目前端是采用vue,经过测试以后,我发现wkhtmltopdf好像并不支持Vue语法。也可能是我的使用方式不当。欢迎小伙伴指正。而且itext7更多用于需要去维护PDF模板的场景,并不适合我本次的需求。所以我最终使用html2canvas+jsPDF的方式来实现。

    html2canvas+jsPDF

    现在,我们来看看html2canvas+jsPDF的实现方式

    首先需要引入html2canvas和jsPDF的依赖文件。大家可以从官网下载。我也会在文末的资源包中放一份,方便大家使用。

    1. //导出pdf文件[html2canvas&&jspdf结合方式] 
    2.        getPdf: function () { 
    3.            var that = this; 
    4.            //影藏不需要的按钮 
    5.            that.buttonShow = !that.buttonShow; 
    6.            //不写会报错 
    7.            window.jsPDF = window.jspdf.jsPDF; 
    8.            //将body的内容保存为一个图片 
    9.            var html2canvas1 = html2canvas(document.body, { 
    10.                //图片跨域加载 
    11.                useCORS: true
    12.                onrendered: function (canvas) { 
    13.                    var contentWidth = canvas.width 
    14.                    var contentHeight = canvas.height 
    15.                    //一页pdf显示html页面生成的canvas高度 
    16.                    var pageHeight = contentWidth / 592.28 * 841.89 
    17.                    //未生成pdf的html页面高度 
    18.                    var leftHeight = contentHeight 
    19.                    //页面偏移 
    20.                    var position = 0 
    21.                    //a4纸的尺寸[595.28,841.89] html页面生成的canvas在pdf的宽高 
    22.                    var imgWidth = 595.28 
    23.                    var imgHeight = 592.28 / contentWidth * contentHeight 
    24.                    //获取图片的base64数据 
    25.                    var pageData = canvas.toDataURL('image/jpeg', 1.0) 
    26.                    //document.body.appendChild(canvas); 
    27.                    var PDF = new jsPDF('''pt''a4'); 
    28.                    if (leftHeight < pageHeight) { 
    29.                        PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight) 
    30.                    } else { 
    31.                        //分页 
    32.                        while (leftHeight > 0) { 
    33.                            PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight) 
    34.                            leftHeight -= pageHeight 
    35.                            position -= 841.89 
    36.                            if (leftHeight > 0) { 
    37.                                PDF.addPage() 
    38.                            } 
    39.                        } 
    40.                    } 
    41.                    //下载pdf 
    42.                    var save = PDF.save(that.sectionInfo.sectionName+"评标报告" + '.pdf'); 
    43.                    //将pdf文件转为blob对象 
    44.                    var blob = save.output("blob"); 
    45.                    //保存pdf文件到服务器 
    46.                    that.savePdf(blob) 
    47.                }, 
    48.            }); 
    49.        }, 

    由于这种方式是纯前端实现。如果我们想要把PDF保存一份到服务器,需要自己手动实现将文件上传到服务器。

    wkhtmltopdf

    接下来我们来看看wkhtmltopdf这种方式如何实现?

    如果我们要使用wkhtmltopdf,需要安装官方提供的软件,大家可以在他的官网进行下载。

    https://wkhtmltopdf.org/downloads.html

    安装完成以后我们需要将安装路径配置的我们的工具类中。

    1. public class WKHtmlToPdfUtil { 
    2.     private static final String WINDOWS_URL = "D:/wkhtmltopdf/bin/wkhtmltopdf.exe"
    3.     private static final String LINUX_URL = "/opt/wkhtmltox/bin/wkhtmltopdf"

    下面我们看一看如何使用,我们需要将我们导出的页面的路径拼接后作为参数传递进来。

    1. String serverUrl = request.getScheme() + "://" + request.getServerName()+":"+request.getServerPort(); 
    2.        //组装需要导出页面的地址 
    3.        serverUrl += request.getContextPath()+"/"
    4.            serverUrl += "evaluate/report/evaluateSectionReport?projectId="+projectId+"&sectionId="+sectionId; 
    5.            logger.info(serverUrl); 
    6.         // 工具类调用 
    7.        exportPdf(serverUrl,response); 
    1. /** 
    2.     * @Title: 导出pdf到服务器 
    3.     * @param 
    4.     * @return 
    5.     */ 
    6.    public static void exportPdf(String serverUrl, HttpServletResponse response){ 
    7.        try { 
    8.            ArrayList<String> urlList = new ArrayList<>(); 
    9.            urlList.add(serverUrl); 
    10.            String folder = Global.getProfile() + "resultReports/"
    11.            // 判断此路径所有目录是否存在,不存在则创建 
    12.            File file = new File(folder); 
    13.            if(!file.exists() && !file.isDirectory()){ 
    14.                // mkdir()创建此抽象路径名指定的目录。如果父目录不存在则创建不成功 
    15.                // mkdirs()创建此抽象路径名指定的目录,包括所有必需但不存在的父目录 
    16.                file.mkdirs(); 
    17.            } 
    18.            // 生成随机的附件路径(时间戳+4位随机数) 
    19.            Random random = new Random(); 
    20.            String fileName = "milolee"+random.nextInt(10); 
    21.            //资源包中,自己下载 
    22.            WKHtmlToPdfUtil.htmlToPdf(urlList, folder+fileName+".pdf"); 
    23.            //资源包中,自己下载 
    24.            // 生成成交通知书pdf文件到服务器之后下载到客户端 
    25.            FileUtils.downLoadFile(folder,fileName+".pdf",response); 
    26.             
    27.        } catch (Exception e){ 
    28.            e.printStackTrace(); 
    29.        } 
    30.    } 

    工具类WKHtmlToPdfUtil和FileUtils我放到资源包中,大家自行下载,太多了就不一一粘贴了

    接下来我们看一看导出我的CSDN首页的效果,还是很棒的

    本文主要介绍了如何将html页面导出为pdf文件,希望给遇到类似需求的小伙伴一点思路,没遇到的也可以收藏一下,以后说不定用得到。

    由于本文设计到的代码比较多,我会打包上传到csdn,大家可以自行下载

    责任编辑:武晓燕 爱写Bug的麦洛
    点赞
    收藏