nodeJS读取JSON文件导出word文档

发布时间 2023-09-14 15:10:53作者: webHYT

前言
最近遇到一个需求,将JSON文件的内容,导出到word文档,利用nodeJs 和 Officegen 实现了文件导出的功能
exportAWord.js 代码如下

/**
 * 读取指定文件夹下的JSON文件,导出为word
 * 一个json文件为一个word,以json文件的名称为word文件的名称
 */
let fs = require("fs");
let path = require("path");
const officegen = require('officegen')
let styleXML = fs.readFileSync("./utils/styles.xml", "utf-8"); // 文档的标题
require('events').EventEmitter.defaultMaxListeners = 0; // 去除MaxListenersExceededWarning限制

let DIR = path.join(__dirname, 'Json');  // 需要导出的文件夹
let docx = officegen({
  type: "docx",
  styleXML,
});


const fileList = readDirSync(DIR);
console.log('fileList', fileList);

fileList.forEach(async (e) => {
  let content = await cusReadFile(path.join(DIR, e));
  content = JSON.parse(content);
  content.forEach(async (p) => { 
    await addDocPara(p)
  })
  await generateWordFile(e);
})

// 读取path下的文件名称列表
function readDirSync(path) {
  let files = [];
  let pa = fs.readdirSync(path);
  pa.forEach(function (ele, index) {
    let info = fs.statSync(path + "/" + ele);
    if (info.isDirectory()) {
      //  console.log("dir: " + ele);
      readDirSync(path + "/" + ele);
    } else {
      //  console.log("file: " + ele);
      files.push(ele);
    }
  });
  return files;
}


// 读取文件
async function cusReadFile(src) {
  return new Promise((resolve) => {
    let a = "";
    const r = fs.createReadStream(src);
    // r.setEncoding('utf-8');
    r.on("data", (chunk) => {
      a += chunk;
    });
    r.on("end", () => {
      resolve(a);
    });
    r.on("error", () => {});
  });
  //
}

function addDocPara (params) {
  const title = params['title']; //文档标题
  const content = params['content']; // 文档内容
   
  //定义文档的标题
  let tObj = docx.createP(); 
  tObj.options.force_style = "myHeading1";
  tObj.addText(title, {
    font_face: 'Arial',
    font_size: 20,
    align: 'left'
  });
  tObj.addLineBreak() //换行
  //定义内容
  let pObj = docx.createP()
  pObj.addText(content, {
    font_size: 14,
    font_face: 'Arial'
  })
}

async function generateWordFile (params) {
  docx.on('finalize', function (written) {
    console.log(
      'Finish to create a Microsoft Word document.'
    )
  })
  docx.on('error', function (err) {
    console.log(err)
  })

  const outDir = `Word/` // 导出的文件目录
  const fileName = params.split('.')[0] // 导出的文件名称
  let out = await fs.createWriteStream(path.join(__dirname, `${outDir}/${fileName}.docx` ));
  out.on('error', (err) => {
    console.log(err)
  })
  docx.generate(out)
}

styles.xml 代码如下

<w:styles xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
    xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
    xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"
    xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml"
    xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" mc:Ignorable="w14 w15 w16se">
    <w:style w:type="paragraph" w:styleId="myHeading1">
        <w:name w:val="heading 1"/>
    </w:style>
    <w:style w:type="paragraph" w:styleId="myHeading2">
        <w:name w:val="heading 2"/>
    </w:style>
    <w:style w:type="paragraph" w:styleId="myHeading3">
        <w:name w:val="heading 3"/>
    </w:style>
    <w:style w:type="paragraph" w:styleId="myHeading4">
        <w:name w:val="heading 4"/>
    </w:style>
    <w:style w:type="paragraph" w:styleId="myHeading5">
        <w:name w:val="heading 5"/>
    </w:style>
</w:styles>