一、起因

  • 没错,在经历了前端生成word文档之后,甲方不出意外的提出了要生成它们所汇报的PPT文件需求,内容包含图片、chart图表、table列表等等。

  • 而且没错,这次后端多加了一个人,但却依旧忙的不可开交,于是身为前端菜坤的我,再次重拳出击🤜 冲冲冲!!!

  • 此篇文章包含了我两个月的心血,我将会详细的讲解这两个月我使用PptxGenJS踩过的坑,以及其基本用法,相信读完这篇文章你将会对PptxGenJS这门技术熟练的掌握!

二、PptxGenJS简介

  • PptxGenJS是一个用于在网页上生成PowerPoint演示文稿(PPTX)的JavaScript库。它可以让开发人员通过编写JavaScript代码来创建和定制PPTX文件,从而实现动态生成演示文稿的功能。

  • PptxGenJS可以生成chart图表、table列表、text文字、image图片、media视频、shapes形状这6种类型。

  • PptxGenJS通常是通过先通过let pptx = new pptxgen(); 生成PptxGenJs的实例,再通过let page1 = pptx.addSlide()的方式,生成一张空白的ppt页,再通过page1.addText('文字')等方法添加文字、图片等类型数据。

三、PptxGenJS的安装以及使用

1. 依赖安装

npm install  pptxgenjs   // 我的版本是:3.12.0

2. 基本使用

1. 引入pptxgenjs,创建其实例

  • 新增一张空白的PPT幻灯片

import pptxgen from "pptxgenjs"; //引入

let pptx = new pptxgen()  // 生成实例

let page1 = pptx.addSlide()  // 生成一张空白的PPT幻灯片

2. 设置PPT幻灯片的页面大小

  1. pptxgenjs默认的幻灯片大小是10 x 5.625 英寸,有四种布局大小供用户选择

    不过推荐大家使用13.3 x 7.5英寸的,如果客户有打印的需求的话,而且占比也宽,可以容纳更多的元素。

  2. pptxgenjs也支持自定义幻灯片大小,通过pptx.defineLayout 来创建属于自己的幻灯片大小,width、height:代表幻灯片的宽度高度,两者单位都是英寸。

    // 定制属于自己的幻灯片大小A3,  宽13.3英寸 高7.5英寸
    pptx.defineLayout({ name:'A3', width:13.3, height:7.5 });
    
    // 并应用自己的布局A3
    pptx.layout = 'A3'

3. 添加文字类型(addText)

addText(text, options):方法包含两个参数,

  1. text:可以是数组对象形式,也可以是字符串形式。数组对象形式可以给每一个text对象设置单独的文字样式 同时也可以通过options设置统一的文本样式,而字符串形式之只能通过options制定统一的文字样式。

  2. options对象形式,可以规定text里所有文字的样式,常用的如:

    • isTextBox:给文字添加文本框

    • fill:给文本框填充颜色

    • shape: 给文本添加形状(shape: ppt.ShapeType.rect 矩形形状)

    • align:文字水平对齐方式

    • valign:文字垂直方向对齐方式 top,middle,bottom

    • breakLine:文字是否换行显示

    • bullet:该段文字是否需要分点(默认true false 以原点的形式显示)

      • bullet对象形式可以设置分点类型: bullet:{ type:number }

      • bullet也可通过设置code方式,找寻你需要的分点标识:bullet:{ code:2605}

      • indentLevel :设置文字分点的层级,数字越大

3.1 字符串形式

  1. text字符串形式如:生成一个蓝色底色的文本框,宽度占据幻灯片的100%,文本框距离顶部35%的距离,文字内容:"Hello World!",文字居中加粗等。(x、y、w、h可以是inch英寸也可以是百分比%单位)

    page1.addText("Hello World!", {
      y: "35%", //相对于页面的位置
      h: "20%", //相对于页面的高度
      w: "100%", //元素宽度
      isTextBox: true,  //是否为文本框
      fill: { color: "275591" },  //文本框填充颜色
      color: "ffff00",    //文本颜色
      align: "center",    //文本对齐方式
      fontSize: 48,     //字体大小
      fontFace: "微软雅黑", //字体
      bold: true,   //是否加粗
    })
    pptx.writeFile({ fileName: "text_ppt" }) //导出PPT

3.2 数组对象形式

  1. text数组对象形式如:一段文字中,有不同颜色不同样式的文字。可以在对象中单独设置文字以及其样式,也可以制定改数组对象中所有文字的统一样式(text1Options

     let text1 = [
        {
          text: "大家好,我是",
        },
        {
          text: "TKEY",
          options: {
            bold: true,
            color: "ff0000",
          },
        },
        {
          text: ",今年",
        },
        {
          text: "18",
          options: {
            bold: true,
            color: "ff0000",
          },
        },
        {
          text: "岁~",
        },
      ]
      let text1Options = {
        x: 1.5,
        y: 0.5,
        w: 10,
        h: 1,
        color: "072b54",
        isTextBox: true,
        fontSize: 20,
        align: "center",
        fontFace: "微软雅黑",
      }
      page1.addText(text1, text1Options)

  2. 给文字分点,并且设置分点的层级

      let page2 = pptx.addSlide()  //创建新的空白页PPT
      // addText的数组对象形式
      let text2 = [
        {
          text: "Indent-Level 0    ",
          options: {
            fontSize: 32,
            bullet: true, // 是否分点
            color: "275591",
            indentLevel: 0, //分点层级0
          },
        },
        {
          text: "Indent-Level 1",
          options: {
            fontSize: 32,
            bullet: true, // 是否分点
            color: "275591",
            indentLevel: 1, //分点层级1
          },
        },
        {
          text: "Indent-Level 2",
          options: {
            fontSize: 32,
            bullet: true, // 是否分点
            color: "275591",
            indentLevel: 2, //分点层级2
          },
        },
        {
          text: "Indent-Level 3",
          options: {
            fontSize: 32,
            bullet: { type: "number" }, // 是否分点 分点的类型 数字
            color: "ff0000",
            indentLevel: 3, //分点层级3
          },
        },
      ]
    //  调用addText 给PPT添加文字类型数据
      page2.addText(text2, {
        x: 1,
        y: 1,
        w: 10,
        h: 5,
        fontSize: 32,
        fontFace: "微软雅黑",
      })

    image-iuax.png

4. 添加图片类型(addImage)

addImage(options):方法包含一个参数

  1. options对象形式,options里设置图片有两种形式:path(图片的路径地址),data(图片的base64格式),两种选其一即可。在options中还可以设置诸如:rotate(图片旋转角度)、sizing(图片是否需要根据高宽保留尺寸、裁剪等)、transparency(透明度)、shadow(阴影)等。

    1. 如:生成一张图片,位于ppt的中间位置

        page1.addImage({
          path: "/avatar.png",  // 将图片放在public或者static文件目录下,直接引用
          x: "40%",
          y: "35%",
          w: "20%",
          h: "35%",
        })
       // 图片格式为base64  可以使用data
        page1.addImage({
          data: "image/png;base64,iVtDafDrBF[...]=",  
          x: "40%",
          y: "35%",
          w: "20%",
          h: "35%",
        })

    2. addImage() 同样也可以生成gif图,不过动画 gif:仅在 Microsoft 365/Office365 和最新桌面版本中显示动画,旧版本仅在演示模式中显示动画。

      ppt_gif.gif

5. 添加形状类型(addShape)

addShape(shapeType, options):方法包含两个参数

  1. shapeType:需要添加的形状类型,PptxGenJS提供差不多200种形状供以选择,具体形状名称:shapeType ,点击之后搜索export enum ShapeType即可。

  2. options对象形式,规定形状的相关样式,这里讲下项目中比较常用的样式

    • fill:填充颜色或透明度。fill: { color: "275591" }

    • reactRadius:圆角

    • rotate:旋转

  3. 例子:将所有shapeType形状类型生成一张张PPT

    for(const key in ppt.ShapeType){
        const page = ppt.addSlide(key)
        page.addShape(ppt.ShapeType[key],{ x:1,y:1,w:1,y:1,fill:'ff0000' })
    }

    可以看到一共输出了179页PPT,每一页都有一个不同的形状

6. 添加表格类型(addTable)

addTable(tableData, options):方法包含两个参数

  1. tableData:接受一个二维数组,并不像我们使用el-table组件时传的数组对象,而是一个二维数组的形式。第二维的每一个数组,都代表着列表的一行,同样第二维的可以为数组形式,也可以为数组对象的形式,方便制定单元格背景、颜色、合并单元格等

    1. 如:数组形式,以名字、年龄、职业为表头生成一个表格,其tableData的值就为

      const tableData = [
          ['姓名', '年龄', '职业'],
          ['小明', 18, '程序员'],
          ['小红', 16, '消防员']
        ]
    2. 第二维为数组对象形式,对象中包含:text:单元格显示数据options:单元格样式

      const tableData = [
          [
           { text: '姓名',options:{ fill: "0070c0",color: "ffffff", bold: true}},
           { text: '年龄',options:{ fill: "0070c0",color: "ffffff", bold: true}},
           { text: '职业',options:{ fill: "0070c0",color: "ffffff", bold: true}}
          ],
          ['小明', 18, '程序员'],
          ['小红', 16, '消防员']
        ]
  1. options对象形式,可以制定表格中单元格的行高、列宽、行合并、列合并、边距对齐等等。

    • colW:表格的列宽。有两种形式,如colW:0.5 代表表格中的每一列的列宽都为0.5英寸,colW:[ 0.2,0.5,0.8 ] 代表列表中的第一二三列的列宽。需要注意使用数组形式时,需要给表格中的每一列都制定对应的宽度,否则无法生效。

    • rowH:表格的行高,属性用法与colW相同。

    • fill:单元格的背景颜色。

    • italic:单元格文字斜体

    • border:单元格边框

    • align:文字水平对齐方式

    • valign:文字垂直方向对齐方式 top,middle,bottom

    • rowspan:行合并。(有点坑,下章会讲)

    • border:单元格边框,对象形式type,pt,color 三个属性,分别代表边框的类型、边框厚度、边框颜色。type包含solid,none,dash,分别是实线、无边框、虚线边框。

    • autoPage:Boolean属性,当表格超过了当前PPT页面时,会自动将后面超过的单元格换页到下一张PPT中去。(不过不是很好用,会在下一章提到,一般都自己写好方法去判断)

    • autoPageRepeatHeader:Boolean属性,搭配autoPage使用。换页的表格是否需要将表头携带过来。

    • autoPageHeaderRows:数值类型(取值:-1~1)搭配autoPage使用。调整计算出的字符宽度。如果每行留有太多空白,则增加字符权重值。相反,如果表格行溢出,则降低字符权重值。

    • autoPageLineWeight:数值类型(取值:-1~1)搭配autoPage使用。调整计算出的行高。如果每个表格下留有过多空白,则增加行权重值。反之,如果表格占满了幻灯片的底部,则降低行权重值。在使用某些不具备常用黄金比例的字体时也很有用。

  2. 例子:以名字、年龄、职业为表头生成一个表格

    let page1 = pptx.addSlide()
    
    const tableData1 = [
      [
        {
          text: "姓名",
          options: { fill: "0070c0", color: "ffffff", bold: true },
        },
        {
          text: "年龄",
          options: { fill: "0070c0", color: "ffffff", bold: true },
        },
        {
          text: "职业",
          options: { fill: "0070c0", color: "ffffff", bold: true },
        },
      ],
      ["小明", 18, "程序员"],
      ["小红", 16, "消防员"],
    ]
    
    page1.addTable(tableData1, {
      x: 0.5,
      y: 0.5,
      w: 12,
      fontSize: 16,
      fontFace: "微软雅黑",
      align: "center",
      valign: "middle",
      rowH: 0.5,  //行高
      border: { pt: 1, color: "000000" },
    })

    table-ppt.png

7. 添加图表类型(addChart)

生成图表类型的PPT有点特殊,有两种方法.

第一种是单一chart图表方法,addChart(chartType, chartData, chartOptions)

第二种是组合式图表addChart(chartTypes, chartOptions),图表中可以包含折线、柱状图等等(这个方法有点坑,当数据有小数点并且显示数据标签时,会默认四舍五入显示整数)。

  1. addChart(chartType, chartData, chartOptions):方法包含三个参数,分别是chartType图表类型,chartData图表的数据,chartOptions图表的样式。

    1. chartType:图表的类型,PptxGenJs所支持的图表类型一共有10种,包含折线、柱状图、散点图、饼图、雷达图等等,可以在后台打印console.log(pptx.ChartType)查看。

    2. chartData:图表的数据。数组对象形式,对象种由:name:数据名字,labels:X轴数据,values:图表数据组成。

      let chartData = [
          {
            name: "小明成绩",
            labels: ["1月", "2月", "3月", "4月", "5月", "6月"],
            values: [80.5, 75.4, 40, 50, 60, 70],
          },
      ]
  2. addChart(chartTypes, chartOptions):方法包含两个参数,chartTypes图表类型以及图表数据,chartOptions图表统一配置项

    1. chartTypes:数组对象形式,包含图表类型type、图表数据data、以及每个chart类型单独配置项options

      const chartTypes = [
        {
          type: pptx.charts.BAR,  //柱状图
          data: [
            {
              name: "月份",
              labels: ["May", "June", "July", "August"],
              values: [26, 53, 100, 75],
            },
          ],
          options: { chartColors: COLORS_SPECTRUM, barGrouping: "stacked" },
        },
        {
          type: pptx.charts.LINE, //折线图
          data: [
            {
              name: "月份",
              labels: ["May", "June", "July", "August"],
              values: [26, 53, 100, 75],
            },
          ],
          options: {
            chartColors: ["F38940"],
            secondaryValAxis: true,
            secondaryCatAxis: true,
          },
        },
      ]
    2. chartOptions:图表的配置项,对象形式,包含了位置/尺寸属性、通用/数据表格/图例/图表标题属性、x轴/y轴属性、柱状图/数据标签/折线图属性等等,有非常多的配置项,这里介绍我项目中经常用到的。

      1. showTitle:是否显示图表标题

      2. showValue:是否显示数据(标签)

      3. showLegend:是否显示图例

      4. showLabel:是否显示标签

      5. chartColors:图表色盘,这是一个字符串数组,里面存放着各种颜色,图表会依次从中取色(多系列图表)

      6. legendFontFace 图例字体

      7. legendFontSize 图例字体大小

      8. legendColor 图例颜色

      9. legendPos 图例位置(b,t,l,r 分别代表下,上,左,右)

      10. 关于x/y轴的配置,如果是x轴则以 cat 开头,如果是y轴则以 val 开头,比如说x轴显隐的属性是:catAxisHidden

        1. 显示隐藏:AxisHidden(布尔值)

        2. 轴标题显示隐藏:showCatAxisTitle(布尔值)

        3. 显示系列名称:showSerName(字符串)

        4. 轴数据标签自定义文字:LabelFormatCode (这个比较坑 下章会提到)

        5. 轴数据标签颜色:AxisLabelColor(字符串)

        6. 轴数据标签是否粗体:AxisLabelFontBold(布尔值)

        7. 轴标签字族:AxisLabelFontFace(字符串)

        8. 轴标签字体大小:AxisLabelFontSize(数值)

        9. 轴标签频率:AxisLabelFrequency(数值,[1-n])

        10. 轴标签位置:AxisLabelPos(字符串,[low,high,nextTo])

        11. 轴线颜色:AxisLineColor(字符串)

        12. 轴线显隐:AxisLineShow(布尔值)

        13. 轴线类型:AxisLineStyle(字符串,[solid,dash,dot])

        14. 轴最大值:AxisMaxVal(数值)

        15. 轴最小值:AxisMinVal(数值)

        16. 轴标题:AxisTitle(字符串)

        17. 轴标题颜色:AxisTitleColor(字符串)

        18. 轴分隔线样式:GridLine(对象,有size,color,style三个属性)

  3. 两个例子,关于这两种方法的实际运用。

    1. 第一种方法,小明与小美的成绩对比

        let page1 = pptx.addSlide()
        // Add a chart to the slide
        let chartData = [
          {
            name: "小明成绩",
            labels: ["1月", "2月", "3月", "4月", "5月", "6月"],
            values: [80.5, 75.4, 40, 50, 60, 70],
          },
          {
            name: "小美成绩",
            labels: ["1月", "2月", "3月", "4月", "5月", "6月"],
            values: [100, 80, 70, 84, 85, 90],
          },
        ]
      
        let chartOptions = {
          x: 0.5,
          y: 1.2,
          w: 12,
          h: 6,
          showTitle: true, //显示标题
          title: "小明和小美成绩对比",  // 标题名字
      
          showLegend: true,  //显示图例
          legendPos: "t",  //图例位置
          showValue: true,  //展示数据标签
        }
        page1.addChart(pptx.ChartType.bar, chartData, chartOptions)

      ppt_柱状图1.png

    2. 第二种方法:小明小美的成绩以及班里的平均分对比

         let page2 = pptx.addSlide()
      
        let chartData2 = [
          {
            type: "line",
            data: [
              {
                name: "班级平均分",
                labels: ["1月", "2月", "3月", "4月", "5月", "6月"],
                values: [80, 75, 70, 84, 85, 90],
              },
            ],
            options: {
              chartColors: ["FF8C00"],
              dataLabelFormatCode: "", //自定义数据标签 为空则显示数据本身 而不是四舍五入后的值
            },
          },
          {
            type: "bar",
            data: [
              {
                name: "小明成绩",
                labels: ["1月", "2月", "3月", "4月", "5月", "6月"],
                values: [80.5, 75.4, 40, 50, 60, 70],
              },
              {
                name: "小美成绩",
                labels: ["1月", "2月", "3月", "4月", "5月", "6月"],
                values: [100, 80, 70, 84, 85, 90],
              },
            ],
            options: {
              dataLabelFormatCode: "",
            },
          },
        ]
        let chartOptions2 = {
          x: 0.5,
          y: 1.2,
          w: 12,
          h: 6,
      
          showTitle: true,
          title: "小明和小美成绩与班级平均分对比",
          showLegend: true,
          legendPos: "t",
          showValue: true,
        }
        page2.addChart(chartData2, chartOptions2)

      ppt_柱状图22.png

四、结尾

本篇文章讲解了关于PptxGenJs的基本使用方法,看完了该篇应该会对PptxGenJs的使用方法有一个完整的认知,解决一些小小的需求还是阔以的。。。吧😂。

后面会再开一章讲解专门讲解我在使用PptxGenJs技术所遇到的坑,以及会分享一些我在做这个需求时所遇到的要展现的特殊效果及要求,并且会做成一个一个例子上传到我的GitHub上面。

感谢大家看完这篇文章,喜欢的话就点个赞吧。ヾ(≧▽≦*)o

五、资料引用

https://juejin.cn/column/7169610205225811982