需求
- 变量,如何传递到 i18n 中?
- 标签和样式,怎么传递到 i18n 中?
- pdf 如何生成
实现
- 首先,新建一个 egg 测试环境
- 然后,配置 i18n
- 加入变量
- 加入标签
- 奥利给!
搭建环境
创建文件及文件夹
mkdir egg
cd egg
npm init
mkdir pdf
mkdir app
mkdir config
cd app
mkdir controller
mkdir public
mkdir view
touch router.js
cd view
touch template.html
cd ../controller
touch user.js
cd ../../config
mkdir locale
touch config.default.js
touch plugin.js
cd locale
touch zh.js
touch en.js
目录结构
├── pdf // 生成的pdf的存储位置
├── app
│ ├── router.js // 定义接口
│ ├── public
│ ├── view
│ │ ├── template.html // 模版
│ ├── controller
│ │ ├── user.js // 导出pdf的逻辑
├── config
│ ├── config.default.js // 默认的配置
│ ├── plugin.js // 启用的插件
│ ├── locale
│ │ ├── zh.js
│ │ ├── en.js
├── package.json
安装依赖
npm install egg -S
npm install egg-bin -D
npm install egg-view-nunjucks -S
npm install puppeteer -S
npm install node-pdftk
编辑启动命令
在 package.json 中加入 egg 启动命令
"scripts": {
"dev": "egg-bin dev",
},
编辑代码
router.js
module.exports = app => {
const { router, controller } = app;
router.get('/test_transfer', controller.user.test_transfer);
};
config.default.js
exports.keys = '1234567890';
exports.i18n = {
defaultLocale: 'zh',
};
exports.nunjucks = {
autoescape: false //设置不自动转译标签
};
exports.view = {
defaultViewEngine: 'nunjucks',
mapping: {
'.html': 'nunjucks',
}
}
plugin.js
exports.nunjucks = {
enable: true,
package: 'egg-view-nunjucks',
};
template.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
</head>
<body>
<header>
{{header}}
</header>
<section>
{{section}}
</section>
</body>
</html>
user.js
const puppeteer = require('puppeteer');
const { promises: { readFile, writeFile } } = require('fs');
const pdftk = require('node-pdftk');
const Controller = require('egg').Controller;
class User extends Controller {
async test_transfer() {
const {ctx} = this
const pdfString = await ctx.renderView(`../view/template.html`, {
title:ctx.__('title'),
header: ctx.__('header',{h:'我是变量'}),
section: ctx.__('section'),
})
const template_path = `${process.cwd()}/app/public/test.html`
await writeFile(template_path, pdfString, 'utf8')
const browser = await puppeteer.launch({
args: ['--disable-dev-shm-usage', '--no-sandbox']
});
const page = await browser.newPage();
await page.goto('file://' + template_path);
const footerTemplate = `<div
style="width:80%;margin:0 auto;font-size:8px;border-top:1px solid #ddd;padding:10px 0;display: flex; justify-content: space-between; ">
<span style="">页脚</span>
<div><span class="pageNumber">
</span> / <span class="totalPages"></span></div>
</div>`;
const headerTemplate = `<div
style="width:80%;margin:0 auto;font-size:8px;border-bottom:1px solid #ddd;padding:10px 0;display: flex; justify-content: space-between;">
<span>页眉1</span>
<span>页眉2</span>
</div>`
const options = {
format: 'A4',
printBackground: true,
'-webkit-print-color-adjust': 'exact',
}
// 封面
const page1 = await page.pdf({
...options,
pageRanges: '1'
})
// 规避封面因为margin:0 导致的后面 margin 失效
await page.addStyleTag({
content: ".cover {display:none}"
})
// 后面所有的内容页
const page2 = await page.pdf({
...options,
displayHeaderFooter: true,
headerTemplate,
footerTemplate,
margin: {
top: 80,
bottom: 80
},
})
const pdfs = [page1, page2];
const buf = await pdftk.input(pdfs).output()
await writeFile(`${process.cwd()}/pdf/canvas.pdf`, buf)
await browser.close();
ctx.body = ctx.__('code')
}
}
module.exports = User;
en.js
module.exports = {
code: 'success',
title: 'title',
header: 'these are some test code,<strong style="font-size:50px">{h}</strong>',
section: 'section'
};
zh.js
module.exports = {
code: '成功',
title: '标题',
header: '这是一段测试完文字,<strong style="font-size:50px">{h}</strong>',
section: '章节'
};
启动程序
npm run dev
访问接口
在浏览器中输入http://127.0.0.1:7001/test_transfer,如果看到success
或者成功
就证明可以了,然后打开 pdf 下的 canvas.pdf 查看生成的 pdf 即可。
PS
如果对生成pdf的内容有疑问,请访问我的另一篇博客,有详细的讲述