需求场景:

web界面已经生成了对应的报告信息模板和相关文件,现需要将网页文档转为pdf下载答应,同时网页中指标内容会应用户的修改而发生变化,现用户需要下载该网页版的报告。

方案一:html2pdf

前端使用html2pdf.js和pdf相关的组件JS,直接将网页转为pdf然后下载。

优点:1、网络上相关参考案例较多,纯前端,不用后台开发费力。

2、转化时间段,效率高,几乎可以实现实时转化,服务器压力小;

缺点:1、对浏览器的兼容要求比较高,有些页面语法无法实现,浏览器分辨率对生成的文件清晰度影响较大,虽然可以通过设置像素处理,但是比较繁琐;按照官网案例很难实现清晰度较高的文档,且坑较多,笔者为后台开发选手,处理很难,放弃。

遇到的问题:

1、html2pdf使用canvas对页面进行截屏,然后转化为pdf,对网页中原有的echarts绘制的图像转canvas元素时出现空白,对跨域的网页图片转化也会出现问题;

相关案例可以在gitee或网页中搜索,有很多案例。

通过使用和测试,感觉改该插比较适用网页简单,对内容要求较低,实时性强的场景。

方案二:poi-tl

可参考:https://blog.csdn.net/weixin_41419401/article/details/113933121

且没有可用的word文档模板(文档模板可以自己定义修改,但工作量大),所以放弃了使用java poi 在服务端转化的方案。

官网文档较详细,生成word后转pdf很容易。

个人人为适用于文档内容格式固定,内容丰富但变化较小的场景。

方案三:frammark

该方案在网上查过,但是要后台熟悉使用,有点类似poi,考虑开发周期,放弃。

方案四:nodejs文档转化服务

选用该方案是考虑到项目中有很多网页转化场景,使用单一服务比较好扩展。

安装nodejs过程如下:

1、下载安装nodejs对应版本,配置bin目录至环境变量 ,linux同样  参考地址 : https://www.runoob.com/nodejs/nodejs-install-setup.html2、cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org3、 安装结果验证:版本验证,命令为:node -v和npm -v查看位置:where node查看淘宝镜像设置,命令为:npm get registry查看npm全局路径设置情况,命令为:npm install webpack -g4、执行命令:npm init 初始化生成package.json (执行命令回车即可)5、 项目中安装mysql,执行命令为:npm install express mysql --save
6、 项目中安装puppeteer,执行命令为:cnpm install puppeteer --savecnpm install bufferutil --savecnpm install  utf-8-validate --save7、启动服务 node app.js

linux 中以上命令也可执行。特别的,linux环境下生成的pdf可能会有部分中文乱码,出现方框,所以需要修改linux 字体配置等。

案例代码如下:

// 引入相关库文件
//var express = require('express');
const puppeteer = require('puppeteer');
const config = require('./config.js');
const mysqlUtils = require('./MysqlUtils.js');//var app = express();
let intervalObj = null;/*** 定义node服务对象
**/
var nodeServerObj = {/*** 开启服务*/startServer: function () {try {mysqlUtils.start();console.log("node server start---------------------");// 定时获取任务this.getUnstartDatas();intervalObj = setInterval(nodeServerObj.getUnstartDatas, config.INTERVAL_TIME);} catch (e) {console.error(e);}},/*** 停止服务*/stopServer: function () {if (intervalObj) {clearInterval(intervalObj);intervalObj = null;}},/*** 获取未开始的数据内容*/getUnstartDatas: function () {if (config.ISSHOW_DEBUGINFO) {console.log("getUnstartDatas---------------------");}let sql = "select id, semester, class_id, child_id, report_file_name, report_file_save_name, status from rk_lb_dg_report_prisefile where status='0' order by id";mysqlUtils.executeSql(sql, function (err, result) {if (err) {console.error(err);} else {for (let i in result) {nodeServerObj.startWork(result[i]);}}});},/*** 开始下载文件(先修改状态再进行转换)* @param {*} reportItem */startWork: function (reportItem) {if (config.ISSHOW_DEBUGINFO) {console.log("startWork---------------------");console.log("操作文件:" + JSON.stringify(reportItem));}let sql = "update rk_lb_dg_report_prisefile set status='2', modify_time=now() where id=" + reportItem['id'];mysqlUtils.executeSql(sql, function (err, result) {if (err) {console.error(err);} else {nodeServerObj.createReportFile(reportItem);}});},/*** 生成报告文件(通过puppeteer进行转换)* @param {*} reportItem */createReportFile: function (reportItem) { let url = config.REPORT_SERVER_PREVIEW_URL + "?childId=" + reportItem['child_id'] + "&semester=" + reportItem['semester'] + "&classId=" + reportItem['class_id'];if (config.ISSHOW_DEBUGINFO) {console.log("createReportFile---------------------url="+url);}var saveFile = config.DOWNLOAD_DIRECTORY + reportItem['report_file_save_name'];(async () => {try {const browser = await puppeteer.launch({headless: true,args: ['--no-sandbox', '--disable-setuid-sandbox']})let loadUiFlag = true;// 加载页面是否正常,默认为trueconst page = await browser.newPage();page.setUserAgent("Mozilla/5.0 (Linux; Android 8.1.0; MI 8 Build/OPM1.171019.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/62.0.3202.84 Mobile Safari/537.36");// page.on('response',(res)=>{//    let url = res.url();//     if(res.status() == 404){//        console.error("页面访问异常,url="+url);//      loadUiFlag = false;//      // 转换失败//       nodeServerObj.stopWork(reportItem['id'], 1, saveFile);//  }/*else{//      console.log("监听事件中正常访问的地址信息,url="+url+", status: "+res.status());//  }*/// });await page.goto(url, { waitUntil: 'networkidle0' });             await page.pdf({path: saveFile,format: 'A4'});await browser.close();// 转换成功if(loadUiFlag){nodeServerObj.stopWork(reportItem['id'], 3, saveFile);    }} catch (e) {console.error(e);// 转换失败nodeServerObj.stopWork(reportItem['id'], 1, saveFile);}})();},/*** 结束转换文件工作* @param {*} id * @param {*} status 转换结果,1:转换失败,3:转换完成*/stopWork: function (id, status, saveFile) {if (config.ISSHOW_DEBUGINFO) {console.log("stopWork---------------------");           }let sql = "update rk_lb_dg_report_prisefile set status='" + status + "', modify_time=now() where id=" + id;mysqlUtils.executeSql(sql, function (err, result) {if (err) {console.error(err);}else{console.log("id: " + id + ", status: " + status + ", saveFile: " + saveFile);}});}};// 初始化服务
nodeServerObj.startServer();

链接:

nodejs实现api接口:

https://www.jianshu.com/p/5f5050257f2e

https://www.cnblogs.com/tuspring/p/14340457.html

网页如何转pdf并实现下载相关推荐

  1. charm浏览器下载网页预览PDF文件

    进入网页开发者页面,寻找可直接下载的PDF源文件 (简单有效.无限制) 1.浏览器打开网页(建议用谷歌浏览器打开): 2.点击鼠标右键,选择[检查] ,或者按Crtl+shift+I快捷键: 3.进入 ...

  2. python下载网页中的pdf文件_【Python】Python的urllib模块、urllib2模块批量进行网页下载文件...

    由于需要从某个网页上下载一些PDF文件,但是需要下载的PDF文件有几百个,所以不可能用人工点击来下载.正好Python有相关的模块,所以写了个程序来进行PDF文件的下载,顺便熟悉了Python的url ...

  3. JavaScript前端:与PDF.js结合,实现网页PDF内容批量下载

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 JavaScript前端:与PDF.js结合,实现网页PDF内容批量下载 前言 一.PDF.js是什么? 二.PDF.js单个PDF文 ...

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

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

  5. python编程入门第3版pdf-Python编程入门第3版PDF电子书免费下载

    本文档的主要内容详细介绍的是Python编程入门第3版PDF电子书免费下载. Python是一种解释型.面向对象.动态数据类型的高级程序设计语言,自20世纪90年代初诞生至今,逐渐被广泛应用于处理系统 ...

  6. 免费开源好用还佛系的国产PDF软件:pdf补丁丁下载 | 含pdf补丁丁使用手册

    PDF补丁丁(PDFPatcher)是一款绿色免费开源且完全免费的多功能国产PDF软件,基于.NET Framework开发,主要采用 iText和MuPDF这两个开放源代码的组件库来处理PDF文件, ...

  7. 网页上打印PDF文件

    在网页上打印pdf文件,有两种方式:可以是在java后端通过调用iText PDF的jar包的方法实现PDF打印;也可以在前端调用lodop插件打印pdf文件. PDF文件的内容可以是表格,图片等等, ...

  8. 在html中加入pdf文件吗,如何在网页中显示PDF文件

    我们是不是对百度文库能直接在网页上显示PDF文件感到好奇,你是否也想实现这样的功能?很多朋友认为可以直接在网页中插入代码就可以实现这个功能,其实要在网页中完整地显示PDF文件,需要把PDF文件转换成S ...

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

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

  10. 如何将网页打印成PDF文档?没看错,这个真可以!

    当我们在浏览器上看到某篇文章时,需要保存下来,大家都会用哪种方式呢? 一般的小伙伴都是复制内容,然后粘贴到Word里,为了美观,然后再重新排版.其实这种方法并不是不可,但是如果遇到有限制的文章.那么就 ...

最新文章

  1. 我所理解的MVCMVPMVVM
  2. vim 改变当前工作路径和创建文件夹
  3. VTK:图片之ImageDilateErode3D
  4. Delphi写的等待进程运行结束函数
  5. ecshop 广告设置
  6. 【渝粤题库】陕西师范大学292071社会统计学作业(高起专)
  7. 鼠标控制视角wasd移动_绝地求生:为什么控制方向键是WASD?网友:就不能是其他键位吗?...
  8. 福建省计算机类考生,福建一档多投对考生是有利的,“滑档”的锅甩给计算机吗?...
  9. C#: using JsonReader avoid Deserialize Json to dynamic
  10. 2021牛客寒假算法基础集训营5,签到题BF
  11. struts2中action手动获取參数
  12. 计算机科学导论第12版答案,计算机科学导论第12章参考答案.pdf
  13. 2022年全国各省四级行政区划Shp矢量数据
  14. Oracle分析函数-first_value()和last_value()
  15. php 判断时间是星期几,通过PHP的date()函数判断今天是星期几
  16. 华为什么出鸿蒙系统,华为已官宣鸿蒙,中兴和魅族的态度却截然不同, 到底啥原因?...
  17. 米斯齐超声波传感器显示测量距离(oled)内附Arduino代码
  18. 关关于android 微信sdk 分享 图片 到 朋友圈 的问题
  19. PHP打包下载zip文件
  20. Redis server went away

热门文章

  1. 【无标题】对Unity的Windows项目进行dll反编译修改
  2. svn 分支上新增文件合并发生冲突_windows 下svn 创建分支 合并分支 冲突
  3. 32 道常见的 Kafka 面试题
  4. PLC可编程控制器的应用
  5. 使用ffmpeg解析mp4文件得到音频和视频数据
  6. 怎样更改计算机ip,怎么快速修改电脑ip地址
  7. 在虚拟机的ubuntu 中配置 tftp 服务器(2021-4-14)
  8. 【开源】有手就能做的街机游戏
  9. C语言面试基本点整理
  10. Vue图片放大镜插件