node实现markdown导出PDF

358 阅读2分钟

node实现markdown导出PDF

前言

开发环境

"engines": { "node": ">=18.x" }

实例

将markdown内容转换成html

需要安装markdown-it来转换,我安装版本的是

"markdown-it": "^14.1.0",

安装

yarn add markdown-it

引用

import MarkdownIt from 'markdown-it';
const md = MarkdownIt();

导入文件并转换

以下demo默认文档内容是在本地环境,通过fs来导入

如果文档是线上资源,可以直接跳过这一步,直接将线上资源通过md.render()导出成html

import fs from 'fs';
const markdownContent = fs.readFileSync(markdownFilePath, 'utf-8');//markdownFilePath 为文件地址
const htmlContent = md.render(markdownContent);

给html添加样式

导出html是MarkdownIt的默认样式,如果想自定义样式,可以自己追加style。

例如我想加一个写表格相关的样式, 先定义样式如下:

const styles = `
  table {
    border-collapse: collapse;
    width: 100%;
  }
  th, td {
    border: 1px solid black;
    padding: 8px;
    text-align: left;
  }
  table thead {
    background: #EEF0F4;
  }
  /* 添加更多样式规则 */
`;
const styleTag = `<style>${styles}</style>`;

再把Style和刚刚的htmlContent合并起来

const pdfContent = styleTag + htmlContent;

现在已经完成准备工作了,接下来就是将准备好的html再导出pdf

将html转换成pdf

注意现在是node环境,需要启动一个虚拟的chorme浏览器,来模拟浏览器环境,导出pdf

这里需要安装一个包puppeteer,我用的版本是"puppeteer": "^22.12.0"

安装

yarn add puppeteer

导出pdf

// 启动Puppeteer
const browser = await puppeteer.launch(launchOptions);
const page = await browser.newPage();

// 加载HTML内容
await page.setContent(pdfContent);

// 生成PDF
await page.pdf({ path: pdfOutputPath, 
format: 'A4', 
margin: {left: 30, top:30, right:30, bottom:30}});
// 关闭浏览器
await browser.close();
console.log('\nPDF文件已生成:', pdfOutputPath);

完整代码

async function convertMarkdownToPdfAndUpload(markdownFilePath, pdfOutputPath, name) {
    try {
      console.log('\n正在处理', name);
      const markdownContent = fs.readFileSync(markdownFilePath, 'utf-8');
      
      // 将Markdown转换为HTML
      const htmlContent = md.render(markdownContent);
      const pdfContent = styleTag + htmlContent;
      // 启动Puppeteer
      const browser = await puppeteer.launch(launchOptions);
      const page = await browser.newPage();
      
      // 加载HTML内容
      await page.setContent(pdfContent);
      
      // 生成PDF
      await page.pdf({ path: pdfOutputPath, 
        format: 'A4', 
        margin: {left: 30, top:30, right:30, bottom:30}});
      // 关闭浏览器
      await browser.close();
      console.log('\nPDF文件已生成:', pdfOutputPath);
      return Promise.resolve(name);
    } catch (error) {
      console.error(markdownFilePath, '转换Markdown到PDF时出错:', error);
      return Promise.reject(error);
    }
  }

遗留问题

无法处理markdown里的图片