123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- const { PATH_FILES } = require('../config')
- const logger = require('../log/index')
- const puppeteer = require('puppeteer');
- const fs = require('fs')
- const path = require('path')
- // 生成
- async function initBrowser () {
- logger.log.debug('启动', new Date().toLocaleString())
- return await puppeteer.launch({
- headless: true,
- args: ['--no-sandbox', '--disable-setuid-sandbox']
- });
- }
- let browser = null
- function checkCache (fPath) {
- try {
- const fStat = fs.statSync(fPath)
- if (fStat) {
- const isFile = fStat.isFile()
- if (isFile) {
- return fPath
- }
- }
- return false
- } catch (err) {
- return false
- }
- }
- function wait(ms) {
- return new Promise((resolve, reject) => {
- setTimeout(() => {
- console.log("Done waiting");
- resolve(ms)
- }, ms)
- })
- }
- function asyncCheck(delay, step, delayFn) {
- return new Promise((resolve, reject) => {
- let attempts = 0;
- const maxAttempts = Math.ceil(delay / step); // 计算最大尝试次数
- const check = () => {
- delayFn().then(result => {
- if (result) {
- resolve({ result: true, type: 'check' });
- } else {
- attempts++;
- if (attempts > maxAttempts) {
- resolve({ result: false, type: 'max' });
- } else {
- // 如果还没有达到最大尝试次数,继续查询
- setTimeout(check, step);
- }
- }
- }).catch(error => {
- // 如果delayFn抛出错误,拒绝Promise
- logger.log.debug('检查页面状态失败', error)
- setTimeout(() => {
- resolve({ result: false, type: 'max-error' });
- }, delay)
- });
- };
- // 启动定时查询
- check();
- });
- }
- async function createPDFOfURL (url, config = {}) {
- if (!browser) {
- browser = await initBrowser()
- }
- config = Object.assign( {
- filename: '',
- dir: '',
- nocache: false,
- width: '950px',
- height: '1360px',
- margin: {
- top: 0,
- bottom: 0
- },
- step: 200,
- check: true
- }, config)
- // 文件路径
- const outPath = path.join(PATH_FILES, config.dir)
- if (!fs.existsSync(outPath)) {
- fs.mkdirSync(outPath);
- }
- const outConfig = Object.assign({path: `${config.filename}.pdf`, width: config.width, height: config.height,printBackground: true }, config)
- outConfig.path = path.join(outPath, outConfig.path)
- // 检查缓存
- if (!config.nocache) {
- const result = checkCache(outConfig.path)
- if (result) {
- logger.log.debug('命中缓存文件')
- return result
- }
- }
- const page = await browser.newPage();
- try {
- await page.setDefaultNavigationTimeout(0)
- await page.goto(url, {waitUntil: 'networkidle2'});
- logger.log.debug('等待生成', new Date().toLocaleString())
- if (config.check) {
- await asyncCheck(config.delay, config.step, async () => {
- const result = await page.evaluate(() => {
- return window.__PDF_LOADED__ || false
- })
- logger.log.debug('页面 __PDF_LOADED__ 状态检查', result)
- return result
- })
- } else {
- await wait(config.delay || 1000)
- }
- await page.pdf(outConfig);
- await page.close();
- logger.log.debug('当前时间', new Date().toLocaleString())
- return outConfig.path
- } catch (e) {
- logger.log.debug(e)
- await page.close();
- }
- }
- module.exports = createPDFOfURL
|