使用officegen在Node.js中生成Word文件

3,032 阅读3分钟

概述

文章描述如何在 Node.js 里把之前通过H5页面展示的内容(文本,表格,图表),放到 Word 文件里,并提供用户下载。大概的思路框架如下图,分三个部分:

  1. 业务程序,负责处理组装数据
  2. officegen,生成Word文件
  3. 文件处理,提供下载接口 未命名文件.png

officegen原理说明

1.拆解.docx文件

docx、pptx、xlsx这些格式遵循着ECMA-376标准规范,也就是Office Open XML格式标准。

ECMA-376标准对于打包方式描述的中指出,Office Open XML是由一堆相关文件包,这个包是一个ZIP」,也就可以理解成.docx、.pptx或者.xlsx 其实就是把.zip换了个写法。

把一个.docx文档后缀名改为.zip并进行解压,查看包结构。如下,有一些描述文件,核心内容存在document.xml中

2.office Open xml

docx官方API地址:officeopenxml.com/WPtableProp… 打开的我们导出的文件,左图红框内的红色文字,在document.xml中的表示方式为右图所示

3. officegen 介绍

officegen为 Microsoft Office 2007 及更高版本创建 Office Open XML 文件(Word、Excel 和 Powerpoint)。本文只介绍Word文件的生成。

document 元素是Word主要内容部分的根元素,而段落是文档中内容的主要块级容器,我们的数据内容,均以段落为基本元素,从上到下来生成。如下代码开始生成文档:

var pageStyle = {
    type:'docx',
    font_face:"仿宋",
    font_size: 12,
    author:"name",
    creator:"name",
    pageMargins:{   // 页边距 A4 PageSize width: 11906,height:16838
      top: 1000,   
      right: 1000,
      bottom: 1000,
      left: 1000
     }
   }
var officegen = require('officegen');
var docx = officegen(pageStyle)

使用示例

段落

在元素插入需要有个段落作为父容器,可整体设置布局样式

var paragraphStyle = { // 段落设置
  align :'right',      // 对齐
  inentLeft:640,       // 整段缩进
  indentFirstLine:640  // 首行缩进
  spacing:{            // 段落间距
     after: 640,       // 段后
     before: 640       // 段前
     line: 640         // 行间距
  },
}
var pObj = docx.createP(paragraphStyle)

officegen官方不支持段落边框的设置,做了下扩展,参考源码:github

pObj = docx.createP({
border:{
  bottom:{
    color: '000088',
    val: 'dashed',
    space: "8",
    sz : '4'
  },
  left:{},
  right:{},
  top:{}
}})

文本

可设置字体样式,多次addText时,可设置不同字体样式。

```
var textStyle = {    
   font_face:"黑体",
   font_size: 16,
   bold: true,
   italic:true,
   border: 'dotted',  // 边框
   borderSize: 12,
   borderColor: '88CCFF'
}
var text = '添加的本文'
pObj.addText(text, textStyle)
```

图片

pObj = docx.createP()
var imageStryle = {cx:500,cy:250} // 宽度,高度
pObj.addImage(path.resolve(__dirname,'../images_for_examples/image2.jpg'))

图表:

图表H5端渲染用的是 Highcharts,服务端生成图片采用Highcharts服务端导出的工具 highcharts-export-server,并和前端渲染共用一套数据。highcharts-export-server把相关图表数据导出生成图片文件后,再通过addImage插入Word文件

表格

表格整体风格布局类似段落,列的配置信息需要个性化的在columns中,数据是结构和行列保持一致的二维数组,每个单元格样式可单独设置。

跨列:在数据单元格中配置opts: { gridSpan: 2 }

跨行:在数据单元格中配置opts: { vMerge: 'restart' }, opts: { vMerge: 'continue' }

var tableData = [ // 以行为单位的数组
[                 //第一行
    { val: "I have two spans.", opts: { gridSpan: 2 } },  // 第一列,跨列 gridSpan
    { val: "3",opts:{ vMerge: "restart" } },              // 第二列,跨行 本行开始
],
[                //第二行
   4, 
   "watch out for the baobabs!",
   { opts: { vMerge: "continue" } } ]  // 第三列,被跨行 跳过
];
var tableStyle =   {
   borders: true, 
   borderSize: 1columns:[         // 单列样式配置
     {width: 1000},
     {width: 1000},
     {width: 1000},
   ]
}
pObj = docx.createTable(tableData, tableStyle)

以上配置渲染效果: 78381009-502a0080-7607-11ea-94ac-38c4513daa51.png 在首行有多个单元格跨列时,列计算会有问题:解决方式是在tableStyle中声明列个数,如上columns属性

遇到的问题

  1. WPS 或者 Word一方打不开,一般解决方式是打开对应document.xml看看数据差别

  2. addHorizontalLine 产生的线条在 Word 打开时是个矩形框,后来改为扩展paragraph的boder属性