简介
需求: app中填写表单(大量图片)传给后端,生成pdf返回保存于手机中
使用的依赖
代码结构
utils/index.js主要方法
const path = require('path')
const pdf = require('html-pdf'); // html-pdf
const optionDefault = {
"format": 'A4',
"header": {
"height": "10mm",
"contents": ''
},
// "phantomPath": "/usr/local/phantomjs-2.1.1-linux-x86_64/bin/phantomjs" // 线上部署phantomjs路径
};
module.exports = {
/**
* 导出pdf
* @param {String} template 模板
* @param {String} name pdf名称
* @param {Object} data 数据
* @param {Function} fn 处理函数
* @param {Object} options html-pdf参数
*/
exportPdf(template, name, data, fn = null, options = optionDefault) {
return new Promise((resolve, reject) => {
let dataReplace = { ...data };
if (fn) { dataReplace = fn(data) }
const html = template.replace(/__([A-Za-z]+)__/g, function(a1, a2) {
return dataReplace[a2] || ' '
});
const exportPath = path.resolve(__dirname, '../../temporary')
pdf.create(html, options).toFile(`${exportPath}/${name}.pdf`, (err, res) => {
if (err) {
reject(err)
} else {
// resolve(res)
resolve(`${name}.pdf`)
}
});
})
},
}
enum.js 针对不同模板,编写不同处理函数
const fs = require('fs');
const path = require('path')
const TABLE_TYPE = {
proofing: {
name: '打样单',
fn(data) {
data.images = data.imgs.map((item) => {
return `<img src="${item.src}" />`
}).join('')
return data
}
},
primary: {
name: '首件检验记录表',
fn(data) {
data.pngs = data.imgs.map((item) => {
return `<img src="${item.src}" />`
}).join('')
return data
}
},
}
module.exports = function(type) {
const templatePath = path.resolve(__dirname, `./template/${type}.html`)
const template = fs.readFileSync(templatePath, 'utf8'); // 引入html模板
const { name, fn } = TABLE_TYPE[type]
return { name, fn , template }
}
index.js 项目启动文件
const Koa = require('koa')
const Route = require('koa-router')
const koaBody = require('koa-body')
const koaStatic = require('koa-static');
const cors = require('@koa/cors');
const path = require('path')
const app = new Koa();
const router = new Route()
const { exportPdf } = require('./utils/exportPdf')
const EnumHtml = require('./enum')
// 采用中间件
app.use(koaBody());
app.use(cors());
app.use(koaStatic(path.resolve(__dirname, '../temporary')));
// 导出pdf接口
router.post('/', async (ctx) => {
const data = ctx.request.body
const { template, name, fn = null } = EnumHtml(data.type)
const exportPath = await exportPdf(template, name + data.createTime, data, fn)
ctx.body = exportPath
ctx.status = 200
})
app.use(router.routes())
app.listen(3001)
console.log('服务运行: http://localhost:3001')
template/proofing.html 模板文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body {
margin: 0;
padding: 20px;
}
/* 自定义pdf样式 */
</style>
</head>
<body>
<table>
<tr>
<td class="key">申请人</td>
<td>__applicant__</td>
<td class="key">申请日期</td>
<td>__date__</td>
<td class="key">申请部门</td>
<td>__department__</td>
</tr>
<tr>
<td>负责部门</td>
<td>面板</td>
<td>主机</td>
<td>打包</td>
<td>品质</td>
<td>生产车间主任</td>
</tr>
<tr class="sign-block">
<td class="key">负责人签字</td>
<td><img class="sign" src="__panel__" /></td>
<td><img class="sign" src="__host__" /></td>
<td><img class="sign" src="__packaging__" /></td>
<td><img class="sign" src="__quality__" /></td>
<td><img class="sign" src="__generationWorkshopDirector__" /></td>
</tr>
</table>
<div class="image-block">
<!-- 拍照信息 -->
__images__
</div>
</body>
</html>
问题解决
安装phantomjs
AssertionError [ERR_ASSERTION]: html-pdf: Failed to load PhantomJS module. You have to set the path to the PhantomJS binary using 'options.phantomPath'
...
小伙伴在使用中可能会出现以上问题
PhantomJs时一个服务器端的JavaScript API的WebKit,支持各种Web标准:DOM处理,CSS选择器,JSON,Canvas,SVG. 使用html-pdf时需根据服务器操作系统,安装 phantomjs 下载
- 下载,根据上面链接
- 安装,PhantomJs不需要安装,解压后,配置环境变量后,便可直接使用
- 配置, vim /etc/profile => export PATH=$PATH:/usr/local/phantomjs-2.1.1-linux-x86_64/bin 执行命令,使其生效:source /etc/profile
- 在 utils/index.js 中更改phantomjs路径
安装字体库 & 中文字体
小伙伴可能会遇到导出的pdf无法显示中文,在本地开发很难发现,因为mac、windows开发环境都拥有字体库并支持中文。 但部署在服务器时,可能没有安装字体库。根据操作系统来安装中文字体库,网上可以直接搜索:
就不展开了
最后
希望能够帮助到你,以上代码很完整了,有什么问题可以一起交流哦
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!