nodeJs读取JOSN文件导出多个word文件

发布时间 2023-09-14 15:16:59作者: webHYT

前言

最近遇到一个需求,读取JOSN文件,以JSON文件的标题为word的文件名导出多个文档,利用nodeJs和 officegen 实现了该功能
exportWords.js 代码如下

/**
 * 读取指定文件夹下的JSON文件,导出多个word文件
 * 一个json文件导出多个word文件,通常以json文件中的title作为导出的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;

let DIR = path.join(__dirname, 'Json/xxx'); // 需要导出的文件夹

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,index) => {
    await generateWordFile(p,index); // 生成word文件
  })

})

// 读取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']; // 文档内容

  // 生成docx对象
  const docx = officegen({
    type: "docx",
    styleXML,
  });
  //定义文档的标题
  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'
  })
  return docx;
}
let fileNameArr = []; // 文件名数组,用于文件重名判断
async function generateWordFile (params, index) {
  const docx = await addDocPara(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/xxx` // 导出的文件目录
  console.log('outDir',outDir)
  // mkdirs(outDir, () => { }) // 生成文件目录

  let fileName = params['title'].replace(/\//g, '') //文件名有/不行,会被判断为文件夹
  if (fileNameArr.includes(fileName)) { 
    fileName = fileName + '-' + index;
  }
  fileNameArr.push(fileName);
  let out = await fs.createWriteStream(path.join(__dirname, `${outDir}/${fileName}.docx`));
  out.on('error', (err) => {
    console.log(err)
  })
  docx.generate(out)
}

//检测目录是否存在,不存在就创建
function mkdirs(dirname, callback) {
  fs.exists(dirname, function (exists) {  
      if (exists) {  
          callback();  
      } else {  
          mkdirs(path.dirname(dirname), function () {  
              fs.mkdir(dirname, callback);  
          });  
      }  
  });  
}