nodejs-编辑、生成word(docxtemplater、officegen、adm-zip)

一、docxtemplater

用途:使用 Javascript 从应用程序内部生成 docx、pptx 或 xlsx

注意:安装3.5版本即可。不用安装最新版本(官方声明:open-docxtemplater-image-module版本在docxtemplater3.5.2之前是兼容的),可能存在docx无法替换图片 Cannot read properties of undefined (reading ‘part’)的问题。

1.引入相关的库

搭配pizzip(或jszip)、open-docxtemplater-image-module使用

  • pizzip:一个同步压缩文件的库,是JsZip的一个分支

  • open-docxtemplater-image-module:开源 docxtemplater 图片模块

// 引入相关的库
const PizZip = require('pizzip')
const Docxtemplater = require('docxtemplater')
const ImageModule = require('open-docxtemplater-image-module') // 读取模板文件

2.替换数据格式

//文本替换模板
{name1}--------------obj.name1
{name2}--------------obj.name2

//图片替换模板
{%image}--------------obj.image

3.根据模板填充word文档

/**
 * 填充word文档
 * @param {string} inputPath 模板文件
 * @param {{}} data 替换数据
 * @param {string} outPutPath 输出文件
 */
fileHelper.replaceWord = async function (inputPath, data, outPutPath) {
  try {
    console.log(inputPath, outPutPath)
    // 读取文件,以二进制文件形式保存
    const content = fs.readFileSync(inputPath, 'binary', function () {})
    // 压缩数据
    const zip = new PizZip(content)
    // 生成模板文档
    const doc = new Docxtemplater()
    const opts = {
      centered: false,
      getImage: function (tagValue, tagName) {
        return fs.readFileSync(
          path.join(__dirname, '../template/图片/' + tagValue)
        )
      },
      getSize: function (img, tagValue, tagName) {
        return [250, 200]
      }
    }

    doc
      .attachModule(new ImageModule(opts))
      .loadZip(zip)
      .setData(data)
    // 渲染数据生成文档
    doc.render()
    // 将文档转换文nodejs能使用的buf
    const buf = doc.getZip().generate({ type: 'nodebuffer' })
    // 输出文件
    await fs.writeFile(outPutPath, buf, function () {})
  } catch (error) {
    console.log(error)
  }
}

二、officegen

用途:为 Microsoft Office 2007 及更高版本创建 Office Open XML 文件(Word、Excel 和 Powerpoint),无需外部工具,只需纯 Javascript。 officegen应该适用于任何支持 Node.js 的环境,包括 Linux、OSX 和 Windows。 officegen还支持带有嵌入数据的PowerPoint原生图表对象。

1.引入相关的库

const officegen = require('officegen')

2.生成word

async function generateWord (date, inputPath, outputPath) {   
const docx = officegen('docx')
  // 1.添加文本
  const title1 = docx.createP({ align: 'center' })
  title1.addText('文本一', { blod: true, font_face: '宋体', font_size: 12 })
  title1.addLineBreak() // 换行
  title1.addText('文本二')

  // 2.添加表格
  let pObjTable = docx.createP()
  const table = [
    ['col1', 'col2', 'col3'],
    [1, 'All grown-ups were once children', '']
  ]
  const tableStyle = {
      tableColWidth: 3261,
      tableSize: 24,
      tableAlign: 'center',
      tableVAlign: 'center',
      borders: true, // default is false. if true, default border size is 4
      borderSize: 2, // To use this option, the 'borders' must set as true, default is 4
      columns: [{ width: 1261 }, { width: 1000 }, { width: 1000 }] // Table logical columns
    }   
  pObjTable = docx.createTable(table, tableStyle)

  // 3.添加图片
  const pObjPic = docx.createP()
  pObjPic.addImage('image.png')

  // 获取文件名
  const fileName = 'result.docx'
  // 导出word
  const out = fs.createWriteStream(path.resolve(outputPath, fileName))
  // 文件写入
  out.on('error', function (err) {
    // console.log(err)
    return err
  })

  const result = docx.generate(out) // 服务端生成word
  docx.on('finalize', function (written) {
    // console.log(
    //   'Finish to create Word file.\nTotal bytes created: ' + written + '\n'
    // )
    return result
  })
  return result
}

3.自定义样式

3.1 重写水平线

  else if (objs_list[i].data[j].horizontal_line) {
              console.log(objs_list[i].data[j])
              var height =
                typeof objs_list[i].data[j].options.height == 'string'
                  ? objs_list[i].data[j].options.height
                  : '.75'
              var fillcolor =
                typeof objs_list[i].data[j].options.fillcolor == 'string'
                  ? objs_list[i].data[j].options.fillcolor
                  : 'e0e0e0'
              //outString += `<w:r><w:pict><v:rect o:spt="1" style="width:0;height:${height}pt" o:hralign="center" o:hrstd="t" o:hr="t" fillcolor="#${fillcolor}" stroked="f"></v:rect></w:pict></w:r>`;
              outString += `<w:r><w:pict><v:rect o:spt="1" style="height:${height}pt;width:0pt;" fillcolor="#${fillcolor}" filled="t" stroked="f" coordsize="21600,21600" o:hr="t" o:hrstd="t" o:hrnoshade="t" o:hralign="center"></v:rect></w:pict></w:r>`
              // Bookmark start support:
            }

在这里插入图片描述

/**
 * Insert a horizontal line inside this paragraph.
 */
MakeDocxP.prototype.addHorizontalLine = function (opt) {
  var newP = this
  // newP.data[newP.data.length] = { horizontal_line: true }
  newP.data[newP.data.length] = { horizontal_line: true, options: opt || {} }
}

在这里插入图片描述
使用:

 // 4.添加水平线
  const pObj = docx.createP()
  pObj.addHorizontalLine({
    height: '2',
    fillcolor: 'FF0000'
  })  

三、adm-zip

用途:

  • 将 zip 文件直接解压缩到磁盘或内存缓冲区中
  • 压缩文件并将它们以 .zip 格式或压缩缓冲区存储到磁盘
  • 从现有 .zip 更新/添加新/删除文件的内容

说明:可以将word当作zip文件进行解压缩,编辑其中内容

注意:无法解析doc文件,只能解析docx文件。

(docx格式与doc格式都是word文本格式,但是二者的差距实际上是很大的,docx和doc的区别显著的一点就是体积大小的不同。docx格式就是一个zip文件,我们可以拿winrar打开docx文件,得到一堆的文件,很类似android程序或者win7桌面窗体的源码,你在里面可以找到各种配置文件,文本文件和媒体文件。)

1.引入相关的库

const AdmZip = require('adm-zip')

2.解压缩(解析word为原始数据)

 const zip = new AdmZip('../test.docx') 
 // 将该docx解压到指定文件夹temp下,word/document.xml为word文件数据
 zip.extractAllTo('../temp', /* overwrite */ true)
 

在这里插入图片描述

3.根据模板填充文件数据(word/document.xml)

在这里插入图片描述

 const result = await fs.promises.readFile(fileName)
    let str = result.toString() 
    //正则表达式替换数据
    const data=[{sourceRegx:/\$\{CE_day\}/g,targetStr:'test'}]
    data.forEach(item => {
      str = str.replace(item.sourceRegx, item.targetStr)
    })
 await fs.promises.writeFile(fileName, str.toString())

4.压缩(导出word)

try {
    const zip = new AdmZip() 
    zip.addLocalFolder(inputPath)//inputPath:word文件夹路径
    await zip.writeZip(outputPath)//result.docx
  } catch (error) {
    console.log('生成word,err:', error)
  }
  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: nodejs-server-wechat-landlordgame-master.zip 是一个基于 Node.js 的服务器代码压缩包,该服务器是用于开发微信地主游戏的。Node.js 是一种基于事件驱动的 JavaScript 运行环境,可以使 JavaScript 在服务器端执行。压缩包中,包含了服务器的相关代码,如游戏逻辑、玩家数据管理、游戏战斗等。利用该服务器,用户可以进行多人在线的地主游戏,游戏结果会通过服务器进行计算。此外,该服务器还提供了一些其他功能,如实时聊天、好友添加等。如果用户想要进行类似微信地主的多人在线游戏开发,可以参考该服务器代码,以便快速地搭建出自己的服务器。同时,需要注意的是,该服务器代码并非完全开源,使用时需要遵循其许可证规定。 ### 回答2: Node.js是一种服务器端JavaScript运行环境,它充分利用了JavaScript的异步和事件驱动性质,使得在高并发的情况下保持高效率和可扩展性变得更加容易。wechat-landlordgame-master.zip是一个基于Node.js的群聊斗地主游戏的代码库。使用该代码库可以快速地构建一个在线的斗地主游戏,具有聊天室和游戏大厅等功能。游戏通过WebSocket实现实时通信,并且支持不同用户之间的文件上传、下载、转发和共享。该代码库提供了完整的代码和文档,易于理解和使用。同时,全面的单元测试和持续集成使得该代码库的质量得到了保证。该项目不仅展示了Node.js在构建在线游戏方面的优越性,也展现了软件开发质量保证的最佳实践。该代码库可作为学习Node.js技术和实践敏捷开发的一个好例子。 ### 回答3: nodejs-server-wechat-landlordgame-master.zip 这个文件是一个JavaScript项目的压缩包,在这个项目中,使用Node.js作为服务器,在微信公众号中实现了斗地主游戏。 作为一个JavaScript项目,使用Node.js作为服务器,可以实现高效的通信和数据处理,同时具有强大的扩展性和灵活性,方便后续的项目更新和维护。 在这个项目中,使用微信公众号作为前端界面,用户可以在公众号内体验斗地主游戏。在微信公众号平台,用户可以快速分享和传播,提高了游戏的曝光率和用户量。 同时,这个项目的作者还给出了详细的使用说明,方便其他开发者进行学习和参考。这种开放式的项目精神,促进了开源社区的发展和技术共享。 总之,nodejs-server-wechat-landlordgame-master.zip 是一个使用Node.js作为服务器,在微信公众号中实现斗地主游戏的JavaScript项目,具有高效的通信和数据处理能力,同时适用于开源社区中的技术共享和学习。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值