# 目前将 html 页面转成 pdf 文件的主流方式
- 完整 demo,见 当前目录下的 example 目录,demo 细节详见 './example/readme.md'
![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c1abbf0aa9f046c3bf84e18bcd82e6dc~tplv-k3u1fbpfcp-watermark.image?)
# 1.不论是哪种方式,只要是将 h5/vue/react/原生 js 页面生成 pdf,都会遇到的问题
1. 各个浏览器、手机兼容性问题;
2. 内容截断问题; 包括不限于 echart 图表截断、动态 table 行截断问题
3. 业务关系紧密的内容和描述需要尽可能放在一起打印
4. 生成动态内容 pdf 等问题
5. 批量下载 pdf 稳定性问题
6. 如果是大文件 前端等待时间较长,如果关闭页面生成失败
# 2.针对以上问题的解决方案
<img src="https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/994310822e8c4959b80847e4ccc72cfe~tplv-k3u1fbpfcp-watermark.image?" alt="image.png" width="70%" />
## 方案 1.前端生成 页面转 pdf 工具 + nb-fe-pdf 算法
页面转 pdf 工具,比如:htmlToCavas/window.print/jspdf
- 这个方案可以解决内容截断和生成动态内容,但是有以下问题
- 各个浏览器、手机兼容性问题;
- 批量下载 pdf 稳定性问题
- 如果是大文件 前端等待时间较长,如果关闭页面生成失败
## 方案 2.node 端 node + Puppeteer + nb-fe-pdf 算法(推荐)
- 这个方案可以解决以 1 到 6 所有问题,并且经过多个项目的验证,不管是用 vue/react 还是别的框架,pc 端还是 H5 端,ui 框架用的 elementui/vant/antd 等,只要最终渲染结果是 DOM 结构都可以理想的实现分页下载;
- 同步方案:
- 适用于并发比较小(10 左右),要下载的内容比较少(1M 左右)时以内的场景
- 异步方案(墙裂推荐)
- 适用于各种场景,高并发、大文件的情况也适用;
- 需要处理队列中的任务状态,成功要做什么、失败了要做什么等等
# 3.nb-fe-pdf 算法
## 3.1 nb-fe-pdf 算法思想
### 分页效果图
![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f5f1566030794c35a462c7bf46adf3d0~tplv-k3u1fbpfcp-watermark.image?)
### nb-fe-pdf 算法思想图
![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2a76cb164e004e428304543cb639e171~tplv-k3u1fbpfcp-watermark.image?)
- nb-fe-pdf 算法是在页面 dom 结构生成完成之后,根据标记,将页面分成一个个模块,计算这些模块的高度,将一个个模块合理的放到 A4 纸中;
- 类似于拼图游戏,这个拼图游戏是要将一个个模块合理的放到 A4 纸中;
- 上图例子中,模块 1 可能处于 pdf 页面的尾部,标题 1 和文本 1 可能在上一页,说明 1 可能被分到下一页了, 说明 1 是描述文本 1,我们希望他们放在一起,给模块 1 所在的外层 div 加一个 flag 标记;
- 最终分页问题转化为将一个个 flag,合理的放到 A4 纸中
### view 层约定-普通模块(高度是固定的)
- 给业务关系比较紧密的模块的外层元素,加上 class="page-splite-flag"
```
<div>
<div class="page-splite-flag">
模块1
<title>标题1</title>
<div>
<p>文本1</p>
<p>文本2</p>
<p>文本3</p>
</div>
<p>说明1</p>
</div>
<div class="page-splite-flag">
模块2
动态table2
<xx-tabel>
我有多少行,取决于数据库有多少条数据
</xx-table>
</div>
<div class="page-splite-flag">
模块3
<title>标题2</title>
<div id="echarts1">饼状图、柱状图</div>
</div>
</div>
```
### view 层约定 - 带有 table 的模块(高度未知,根据数据多少来展示)
- - 默认 ui 组件是基于 elementui
- 如果 table 内容的长度是动态的 引入 cardTable 组件,用 slot 的方式在对应的信息放进去;
- 如果 table 长度不是动态的就可以不用
- 其实在算法层,最终用到的是"card-table"、“card-table-top-wraper”、“card-table-wraper”、“card-table-bom-wraper” 这些 class 类名,意味着不论什么 ui 框架的 table 组件,或者是原生 table,只要按照这种结构,给对应的位置加上这些 class 名,就可以正确的完成动态 table 分页;
```
// cardTable.vue
<template>
<div class="card-table page-splite-flag">
<div class="card-table-top-wraper">
<slot name="card-table-header" />
</div>
<div class="card-table-wraper">
<slot name="card-table" />
</div>
<div class="card-table-bom-wraper">
<slot name="card-table-footer" />
</div>
</div>
</template>
```
```
// usage.vue
<card-table >
<template #card-table-header>
<div>
<h3>投资产品选择</h3>
</div>
<h4 style="padding-left: 20px">定投产品总览</h4>
</template>
<template #card-table>
<ts-table
:table-data="regularList"
:table-head="regularHead"
:table-title-obj="{ hide: true }"
:paginationHide="true"
/>
</template>
<template #card-table-footer>
<p>表格说明信息1</p>
<p>表格说明信息2</p>
<p>...</p>
</template>
</card-table>
```
## 3.2 nb-fe-pdf 使用方式
### 安装
```js
nbnpm i nb-fe-pdf -S // nbnpm 下载(内部下载)
or
npm install nb-fe-pdf -S // 无法使用nbnpm,可以用npm或yarn
源码地址:
https://gitlab.newbanker.cn/nbnpm/nb-fe-pdf (内部访问)
or
https://www.npmjs.com/package/nb-fe-pdf
```
### 参数说明
```
export interface PrintParmas {
moduleMap: ModuleMap | ModuleInfo; // moduleMap是由多个ModuleInfo 组成的
selectModule?: string[]; // 要下载的模块名["analy", "pension"]
injectClass?: BaseClass; // injectClass不传默认是elementui的el-table
callback?: Function; // 分页执行完毕的回调函数
}
const moduleInfo: ModuleInfo = {
moduleId: "#print-analy-wraper", // 模块id,给每个要下载的组合所有页面的根元素加上id
pageInfo: {
title?: string; // 模块标题
needTpl?: boolean; // 是否需要头尾模板,默认为false
defaultType?: PrintType; // 模板类型,需要needTpl为true,
waterMark?: boolean // 是否需要水印, 默认为false
waterMarkConfig: { // 需要waterMark为true
waterMarkId: string; // 要做水印的根元素id
waterMarkContent: string; // 水印内容
};
};
}
// 模板类型
export enum PrintType {
NORMAL_TYPE = "NORMAL_TYPE", // 无头无尾
HEADER_TYPE = "HEADER_TYPE", // 有头无尾
FOOTER_TYPE = "FOOTER_TYPE", // 无头有尾
HEADER_FOOTER_TYPE = "HEADER_FOOTER_TYPE", // 有头有尾
}
```
### 适配不同的 UI 框架
- 在 pageInfo 传入对应 ui 框架的 table 的 injectClass 类名即可
```
// defaut use elementui table component classnames
static cardTableTBHeaderWraper = "el-table__header-wrapper"; // table header wraper classname
static cardElRowClass = "el-table__row"; // table body row classname
static elTableBodyWraper = "el-table__body-wrapper"; // table body wraper classname
const injectClass = {
cardTableTBHeaderWraper: 've-table-header'
cardElRowClass: 've-table-body-tr',
elTableBodyWraper: 've-table-body'
}
```
### 快速开始-下载单个模块语法
```
// javascript 引用方式
import { Print } from 'nb-fe-pdf/lib/src'
// typescript 引用方式
import { Print } from 'nb-fe-pdf'
语法 new Print(moduleInfo) // 下载单个模块
也就是
new Print({moduleId: "#print-operate-report-wrapper",
pageInfo: {
defaultType: 'HEADER_TYPE',
needTpl: true,
},
})
```
### 下载单个模块 - demo
```
<section>
<!-- 页眉页脚模板 -->
<pdf-tpl><pdf-tpl/>
<!--
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
这里为你收集整理了关于毕业设计、课程设计可参考借鉴的资料一份,质量非常高,如果你投入时间去研究几天相信肯定对你有很大的帮助。到时候你会回来感谢我的。 本资源是经过本地编译测试、可打开、可运行的项目、文件或源码,可以用于毕业设计、课程设计的应用、参考和学习需求,请放心下载。 祝愿你在这个毕业设计项目中取得巨大进步,顺利毕业! 但还需强调一下,这些项目源码仅供学习和研究之用。在使用这些资源时,请务必遵守学术诚信原则和相关法律法规,不得将其用于任何商业目的或侵犯他人权益的行为。对于任何因使用本资源而导致的问题,包括但不限于数据丢失、系统崩溃或安全漏洞,风险自担哦! 如有侵权,请联系博主删除。
资源推荐
资源详情
资源评论
收起资源包目录
毕业设计-将htmlvuereact等ui界面生成pdf的源码处理了分页截断问题和异步并发问题经过多个项目验证e (1).zip (111个子文件)
. prettierrc 106B
.browserslistrc 30B
reset.css 1KB
print.css 1KB
base.css 128B
.eslintignore 20B
.gitignore 231B
.gitignore 38B
.gitignore 12B
index.html 611B
favicon.ico 4KB
nb-fe-pdf.global.js 42KB
SplitePage.js 10KB
PdfPage.js 10KB
DfsChild.js 8KB
SplitePage1.js 6KB
downloadMixins.js 6KB
index.js 5KB
waterMark.js 5KB
Compose.js 4KB
index.js 3KB
const.js 3KB
pupMiddle.js 3KB
app.js 3KB
utils.js 2KB
queue.js 2KB
index.js 2KB
utils.js 2KB
default.js 1KB
worker.js 1KB
resize-mixins.js 1KB
index.js 1KB
baseController.js 1KB
asyncController.js 1KB
base.js 993B
asyncManyController.js 956B
base-qianhai.js 865B
main.js 808B
logger.js 808B
index.js 795B
handleJob.js 740B
redis.js 698B
syncDownloadController.js 670B
.eslintrc.js 620B
local.same.js 516B
index.js 480B
production.js 445B
vue.config.js 368B
testController.js 280B
babel.config copy.js 255B
babel.config.js 66B
index.js 51B
test.js 20B
package-lock.json 367KB
package-lock.json 124KB
package.json 2KB
package.json 1KB
package.json 909B
tsconfig.json 878B
tsconfig.json 792B
package-lock.json 648B
pm2.json 639B
yarn.lock 103KB
nb-fe-pdf.global.js.map 70KB
readme.md 17KB
readme.md 3KB
LICENSE.md 1KB
test_report.pdf 1.71MB
异步单个下载报告-db60f46d-1a79-4813-ad68-64ac7a48aa8c.pdf 310KB
process-ui.png 244KB
asyncPrintUi.png 244KB
17ea0a60-1647-46e2-abf5-582f92cf3f27.png 78KB
async-download-dir.png 75KB
logo.png 7KB
logo.png 7KB
PdfPage.ts 8KB
SplitePage.ts 8KB
DfsChild.ts 6KB
waterMark.ts 5KB
downloadMixins.ts 3KB
index.ts 3KB
Compose.ts 3KB
index.ts 3KB
const.ts 3KB
utils.ts 2KB
utils.ts 1KB
index.ts 764B
resize-mixins.ts 598B
main.ts 354B
shims-tsx.d.ts 222B
index.ts 186B
shims-vue.d.ts 72B
print.vue 4KB
HelloWorld.vue 3KB
asyncDownload.vue 3KB
clickPage.vue 3KB
syncPage.vue 3KB
lineChart.vue 2KB
index.vue 2KB
index.vue 1KB
共 111 条
- 1
- 2
资源评论
高校毕业设计
- 粉丝: 210
- 资源: 384
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功